This document provides essential context for working with the Maestro MCP Server codebase.
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.
src/
├── index.ts # Main server (4400+ lines) - tool definitions, MCP handlers, API execution
└── streamable-http.ts # HTTP transport layer using Hono framework
- Tool Definition Map (
toolDefinitionMap) - Static map of 119 API endpoints translated to MCP tools - Zod Schema Cache (
zodSchemaCache) - Pre-compiled validation schemas for all tools - Session Management (
MCPStreamableHttpServer.sessions) - Per-session state including auth tokens - HTTP Client (
apiClient) - Axios instance with connection pooling
The server is auto-generated from OpenAPI specification:
npx openapi-mcp-generator --input openapi-merged.json --output ./ \
--force --transport streamable-http --port 3000Look for /* MAESTRO OVERRIDE */ comments to find custom modifications that should be preserved when regenerating.
The following optimizations were implemented to improve reliability and performance:
- 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
- Before: Single
bearerAuthstring shared across all sessions (bug) - After: Each session stores its own
bearerAuthinSessionData - Impact: Fixes correctness issue with multiple concurrent clients
- Before: New TCP/TLS connection for every API call
- After:
apiClientwithkeepAlive: true, 50 max sockets - Impact: Reduced latency for subsequent requests
- Before: Created 119 new objects on every
tools/listcall - After:
cachedToolsForClientbuilt once at startup - Impact: Zero allocation on tools listing
- Before: Synchronous
fs.statSync()andfs.readFileSync() - After: Async
fs.promises.stat()andfs.promises.readFile() - Impact: Non-blocking static file serving
- Before: Dynamic
import('fs')on every static file request - After: Imports at module level with pre-computed paths
- Impact: Eliminates module resolution overhead
- Before: Sessions stored indefinitely until explicit close
- After: Automatic cleanup of sessions inactive for 30 minutes (configurable)
- Impact: Prevents memory leaks from abandoned sessions
- Before: Verbose
console.error()on every request - After: Debug logging controlled by
LOG_LEVELenv var - Impact: Reduced I/O overhead in production
| 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) |
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.
# 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"}}}'-
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
-
src/streamable-http.ts - HTTP transport
- Lines 65-72:
SessionDatainterface - Lines 74-120: Session cleanup logic
- Lines 132-239: Request handling with per-session auth
- Lines 271-281:
getBearerAuth()- Per-session token retrieval
- Lines 65-72:
Tools are auto-generated from openapi-merged.json. To add manually:
- Add entry to
toolDefinitionMapinindex.ts - Schema will be auto-compiled at startup
Edit executeApiTool() function in index.ts (around line 4088).
Edit MCPStreamableHttpServer class in streamable-http.ts.
Set LOG_LEVEL=debug for verbose output:
LOG_LEVEL=debug bun run start:http-
Two tools have malformed JSON schemas that fail Zod compilation:
mkt-btc-prices-by-timestampsmkt-rune-prices-by-timestamps
These fall back to passthrough validation and still work.
-
The
API_BASE_URLenvironment variable support was added but the value is also hardcoded as a fallback.