Architettura e flussi
Componenti principali
server.js: bootstrap viacreateMicroserviceServer; registra il router di debug (routes.mcpDebug.js) e opzionalmente il router HTTP (routes.mcpHttp.js);modules/main.js: service runtime (McpGateway extends BaseService); inizializzaMcpSubsysteme avvia il trasporto configurato in_onInit();modules/mcp/index.js:McpSubsystem— crea il registry e gestisce il ciclo di vita del trasporto stdio;modules/mcp/registry.js:McpRegistry— mappa nome → tool, applica allowlist, esponelistTools()ecallTool();modules/mcp/transports/stdio.js:StdioTransport— readline su stdin, JSON per riga, dispatch a registry;modules/mcp/tools/ping.js·modules/mcp/tools/strategies_list.js: tool registrati di default;routes.mcpDebug.js: router debug —GET /mcp/healtheGET /mcp/tools(sempre attivi,protected: true);routes.mcpHttp.js: router HTTP transport —GET /toolsePOST /call(solo seMCP_TRANSPORT=http, protetti daX-Internal-Token).
Flusso stdio (Claude Desktop / Claude Code)
- Il client MCP avvia
node server.jscome processo figlio. _onInit()chiamamcp.startStdio()→ creaStdioTransport.StdioTransport.start()apre unreadline.Interfacesuprocess.stdin.- Il client invia una riga JSON:
{"id":"1","tool":"ping","input":{"message":"ok"}}. - Il transport chiama
registry.callTool(tool, input, ctx). - Il registry recupera il tool, esegue
validate()(se presente) ehandler(ctx, input). - Il risultato viene scritto su
process.stdoutcome riga JSON:{"id":"1","ok":true,"data":{...}}.
Flusso HTTP transport (client MCP remoti)
- Il servizio avvia con
MCP_TRANSPORT=http. serverFactorymontaroutes.mcpHttp.jsal pathMCP_HTTP_PATH.- Il client chiama
GET <path>/tools(lista) oPOST <path>/call(invocazione). - Il middleware
requireTokenvalidaX-Internal-TokenseINTERNAL_TOKENè impostato. POST /call: body{"tool":"...", "input":{...}}→registry.callTool()→ risposta JSON.
Flusso invocazione tool
client → transport (stdio | HTTP)
→ registry.callTool(name, input, ctx)
→ tool.validate(input) [opzionale]
→ tool.handler(ctx, input) [async]
→ upstream call (es. tickerscanner REST) o logica locale
← { ok, data } | { ok: false, error: { code, message } }
← risposta al client
Contesto tool (ctx)
Ogni handler riceve un oggetto ctx con:
{
service, // istanza McpGateway (BaseService) — accesso a URL, logger, Redis
logger, // logger del servizio
}
Gli strumenti accedono agli URL degli altri microservizi tramite ctx.service.tickerscannerUrl, ctx.service.datahubUrl ecc., senza hardcodare indirizzi.
Registrazione tool e allowlist
Il registry carica i tool da DEFAULT_TOOLS a costruzione. Se MCP_TOOL_ALLOWLIST è impostata, solo i tool il cui nome è nella lista vengono registrati. Tool con name mancante o handler non funzione vengono scartati con log di warning.