Skip to content

Latest commit

 

History

History
161 lines (117 loc) · 5.76 KB

File metadata and controls

161 lines (117 loc) · 5.76 KB

Maestro MCP Server - Developer Guide

This document provides essential context for working with the Maestro MCP Server codebase.

Overview

This is a Model Context Protocol (MCP) server that provides LLM-accessible tools for interacting with Bitcoin blockchain via the Maestro API platform. It exposes 119 tools covering addresses, assets (BRC20/Runes/Inscriptions), blocks, transactions, mempool data, and Node RPC operations.

Architecture

src/
├── index.ts           # Main server (4400+ lines) - tool definitions, MCP handlers, API execution
└── streamable-http.ts # HTTP transport layer using Hono framework

Key Components

  1. Tool Definition Map (toolDefinitionMap) - Static map of 119 API endpoints translated to MCP tools
  2. Zod Schema Cache (zodSchemaCache) - Pre-compiled validation schemas for all tools
  3. Session Management (MCPStreamableHttpServer.sessions) - Per-session state including auth tokens
  4. HTTP Client (apiClient) - Axios instance with connection pooling

Code Generation

The server is auto-generated from OpenAPI specification:

npx openapi-mcp-generator --input openapi-merged.json --output ./ \
  --force --transport streamable-http --port 3000

Look for /* MAESTRO OVERRIDE */ comments to find custom modifications that should be preserved when regenerating.

Performance Optimizations (2026-02)

The following optimizations were implemented to improve reliability and performance:

1. Zod Schema Caching

  • Before: eval() called on every API request to convert JSON Schema → Zod
  • After: All schemas pre-compiled at startup, cached in zodSchemaCache
  • Impact: Eliminates ~5-10ms per request

2. Per-Session Authentication

  • Before: Single bearerAuth string shared across all sessions (bug)
  • After: Each session stores its own bearerAuth in SessionData
  • Impact: Fixes correctness issue with multiple concurrent clients

3. HTTP Connection Pooling

  • Before: New TCP/TLS connection for every API call
  • After: apiClient with keepAlive: true, 50 max sockets
  • Impact: Reduced latency for subsequent requests

4. ListTools Response Caching

  • Before: Created 119 new objects on every tools/list call
  • After: cachedToolsForClient built once at startup
  • Impact: Zero allocation on tools listing

5. Async File Operations

  • Before: Synchronous fs.statSync() and fs.readFileSync()
  • After: Async fs.promises.stat() and fs.promises.readFile()
  • Impact: Non-blocking static file serving

6. Module-Level Imports

  • Before: Dynamic import('fs') on every static file request
  • After: Imports at module level with pre-computed paths
  • Impact: Eliminates module resolution overhead

7. Session Timeout/Cleanup

  • Before: Sessions stored indefinitely until explicit close
  • After: Automatic cleanup of sessions inactive for 30 minutes (configurable)
  • Impact: Prevents memory leaks from abandoned sessions

8. Configurable Logging

  • Before: Verbose console.error() on every request
  • After: Debug logging controlled by LOG_LEVEL env var
  • Impact: Reduced I/O overhead in production

Environment Variables

Variable Default Description
PORT 3000 Server port
LOG_LEVEL info Logging level (info or debug)
API_BASE_URL https://xbt-mainnet.gomaestro-api.org/v0 Maestro API endpoint
SESSION_TIMEOUT_MS 1800000 Session timeout (30 min)

API Authentication

The server supports Bearer token authentication passed via the Authorization header:

Authorization: Bearer <maestro-api-key>

Tokens are stored per-session and passed to the Maestro API as the api-key header.

Testing

# Build
bun run build

# Start server
PORT=3001 bun run start:http

# Test health endpoint
curl http://localhost:3001/health

# Test MCP initialize
curl -X POST http://localhost:3001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

Key Files to Understand

  1. src/index.ts - Main entry point

    • Lines 22-66: Imports and configuration (logging, HTTP agents, caches)
    • Lines 67-110: Server and cache initialization
    • Lines 3890-3930: Cache initialization function
    • Lines 3932-3965: MCP request handlers
    • Lines 4088-4180: executeApiTool() - API call execution
    • Lines 4463-4486: getZodSchemaFromJsonSchema() - Schema lookup
  2. src/streamable-http.ts - HTTP transport

    • Lines 65-72: SessionData interface
    • Lines 74-120: Session cleanup logic
    • Lines 132-239: Request handling with per-session auth
    • Lines 271-281: getBearerAuth() - Per-session token retrieval

Common Tasks

Adding a New Tool

Tools are auto-generated from openapi-merged.json. To add manually:

  1. Add entry to toolDefinitionMap in index.ts
  2. Schema will be auto-compiled at startup

Modifying API Call Behavior

Edit executeApiTool() function in index.ts (around line 4088).

Changing Session Behavior

Edit MCPStreamableHttpServer class in streamable-http.ts.

Debugging

Set LOG_LEVEL=debug for verbose output:

LOG_LEVEL=debug bun run start:http

Known Issues

  1. Two tools have malformed JSON schemas that fail Zod compilation:

    • mkt-btc-prices-by-timestamps
    • mkt-rune-prices-by-timestamps

    These fall back to passthrough validation and still work.

  2. The API_BASE_URL environment variable support was added but the value is also hardcoded as a fallback.