- Home
- Documentation
- MCP
- Ciclo di vita del runtime MCP
Ciclo di vita del runtime MCP
Questo documento descrive come i server MCP vengono scoperti, connessi, esposti come strumenti, aggiornati e terminati nel runtime del coding-agent.
Panoramica del ciclo di vita
Sezione intitolata “Panoramica del ciclo di vita”- L’avvio dell’SDK chiama
discoverAndLoadMCPTools()(a meno che MCP non sia disabilitato). - La discovery (
loadAllMCPConfigs) risolve le configurazioni dei server MCP dalle sorgenti di capability, filtra le voci disabilitate/progetto/Exa e preserva i metadati della sorgente. - La fase di connessione del Manager (
MCPManager.connectServers) avvia la connessione per server +tools/listin parallelo. - Il gate di avvio rapido attende fino a 250ms, poi può restituire:
MCPToolcompletamente caricati,- errori per server,
- o
DeferredMCPTooldalla cache per i server ancora in attesa.
- Il wiring dell’SDK unisce gli strumenti MCP nel registro degli strumenti del runtime per la sessione.
- La sessione attiva può aggiornare gli strumenti MCP tramite i flussi
/mcp(disconnectAll+ ri-discovery +session.refreshMCPTools). - La terminazione avviene quando i chiamanti invocano
disconnectServer/disconnectAll; il manager cancella anche le registrazioni degli strumenti MCP per i server disconnessi.
Fase di discovery e caricamento
Sezione intitolata “Fase di discovery e caricamento”Percorso di ingresso dall’SDK
Sezione intitolata “Percorso di ingresso dall’SDK”createAgentSession() in src/sdk.ts esegue l’avvio MCP quando enableMCP è true (predefinito):
- chiama
discoverAndLoadMCPTools(cwd, { ... }), - passa
authStorage, lo storage della cache e l’impostazionemcp.enableProjectConfig, - imposta sempre
filterExa: true, - registra nei log gli errori di caricamento/connessione per server,
- memorizza il manager restituito in
toolSession.mcpManagere nel risultato della sessione.
Se enableMCP è false, la discovery MCP viene completamente saltata.
Discovery e filtraggio della configurazione
Sezione intitolata “Discovery e filtraggio della configurazione”loadAllMCPConfigs() (src/mcp/config.ts) carica gli elementi canonici del server MCP attraverso la discovery delle capability, poi li converte nella MCPServerConfig legacy.
Comportamento del filtraggio:
enableProjectConfig: falserimuove le voci a livello di progetto (_source.level === "project").- I server con
enabled: falsevengono saltati prima dei tentativi di connessione. - I server Exa vengono filtrati per impostazione predefinita e le chiavi API vengono estratte per l’integrazione nativa dello strumento Exa.
Il risultato include sia configs che sources (metadati usati successivamente per l’etichettatura del provider).
Comportamento in caso di errore a livello di discovery
Sezione intitolata “Comportamento in caso di errore a livello di discovery”discoverAndLoadMCPTools() distingue due classi di errore:
- Errore grave della discovery (eccezione da
manager.discoverAndConnect, tipicamente dalla discovery della configurazione): restituisce un set di strumenti vuoto e un errore sintetico{ path: ".mcp.json", error }. - Errore di runtime/connessione per server: il manager restituisce un successo parziale con la mappa
errors; gli altri server continuano.
Quindi l’avvio non fa fallire l’intera sessione dell’agente quando singoli server MCP falliscono.
Modello di stato del Manager
Sezione intitolata “Modello di stato del Manager”MCPManager traccia il ciclo di vita del runtime con registri separati:
#connections: Map<string, MCPServerConnection>— server completamente connessi.#pendingConnections: Map<string, Promise<MCPServerConnection>>— handshake in corso.#pendingToolLoads: Map<string, Promise<{ connection, serverTools }>>— connessi ma strumenti ancora in caricamento.#tools: CustomTool[]— vista corrente degli strumenti MCP esposta ai chiamanti.#sources: Map<string, SourceMeta>— metadati del provider/sorgente anche prima del completamento della connessione.
getConnectionStatus(name) deriva lo stato da queste mappe:
connectedse presente in#connections,connectingse in connessione pendente o caricamento strumenti pendente,disconnectedaltrimenti.
Stabilimento della connessione e tempistica di avvio
Sezione intitolata “Stabilimento della connessione e tempistica di avvio”Pipeline di connessione per server
Sezione intitolata “Pipeline di connessione per server”Per ogni server scoperto in connectServers():
- memorizzare/aggiornare i metadati della sorgente,
- saltare se già connesso/pendente,
- validare i campi di trasporto (
validateServerConfig), - risolvere le sostituzioni di auth/shell (
#resolveAuthConfig), - chiamare
connectToServer(name, resolvedConfig), - chiamare
listTools(connection), - mettere in cache le definizioni degli strumenti (
MCPToolCache.set) in modalità best-effort.
Comportamento di connectToServer() (src/mcp/client.ts):
- crea un trasporto stdio o HTTP/SSE,
- esegue
initializeMCP +notifications/initialized, - utilizza un timeout (
config.timeouto 30s predefinito), - chiude il trasporto in caso di errore di inizializzazione.
Gate di avvio rapido + fallback differito
Sezione intitolata “Gate di avvio rapido + fallback differito”connectServers() attende una gara tra:
- tutti i task di connessione/caricamento strumenti completati, e
STARTUP_TIMEOUT_MS = 250.
Dopo 250ms:
- i task completati con successo diventano
MCPToolattivi, - i task rifiutati producono errori per server,
- i task ancora pendenti:
- usano le definizioni degli strumenti dalla cache se disponibili (
MCPToolCache.get) per creareDeferredMCPTool, - altrimenti attendono fino al completamento di quei task pendenti.
- usano le definizioni degli strumenti dalla cache se disponibili (
Questo è un modello di avvio ibrido: ritorno rapido quando la cache è disponibile, attesa per correttezza quando la cache non è disponibile.
Comportamento di completamento in background
Sezione intitolata “Comportamento di completamento in background”Ogni toolsPromise pendente ha anche una continuazione in background che alla fine:
- sostituisce la porzione di strumenti di quel server nello stato del manager tramite
#replaceServerTools, - scrive la cache,
- registra nei log gli errori tardivi solo dopo l’avvio (
allowBackgroundLogging).
Esposizione degli strumenti e disponibilità nella sessione attiva
Sezione intitolata “Esposizione degli strumenti e disponibilità nella sessione attiva”Registrazione all’avvio
Sezione intitolata “Registrazione all’avvio”discoverAndLoadMCPTools() converte gli strumenti del manager in LoadedCustomTool[] e decora i percorsi (mcp:<server> via <providerName> quando noto).
createAgentSession() poi inserisce questi strumenti in customTools, che vengono wrappati e aggiunti al registro degli strumenti del runtime con nomi come mcp_<server>_<tool>.
Chiamate agli strumenti
Sezione intitolata “Chiamate agli strumenti”MCPToolchiama gli strumenti attraverso unaMCPServerConnectiongià connessa.DeferredMCPToolattendewaitForConnection(server)prima di chiamare; questo permette agli strumenti dalla cache di esistere prima che la connessione sia pronta.
Entrambi restituiscono output strutturato dello strumento e convertono gli errori di trasporto/strumento in contenuto dello strumento MCP error: ... (l’abort rimane abort).
Percorsi di aggiornamento/ricaricamento (avvio vs ricaricamento dal vivo)
Sezione intitolata “Percorsi di aggiornamento/ricaricamento (avvio vs ricaricamento dal vivo)”Percorso di avvio iniziale
Sezione intitolata “Percorso di avvio iniziale”- discovery/caricamento una tantum in
sdk.ts, - gli strumenti vengono registrati nel registro degli strumenti della sessione iniziale.
Percorso di ricaricamento interattivo
Sezione intitolata “Percorso di ricaricamento interattivo”Il percorso /mcp reload (src/modes/controllers/mcp-command-controller.ts) esegue:
mcpManager.disconnectAll(),mcpManager.discoverAndConnect(),session.refreshMCPTools(mcpManager.getTools()).
session.refreshMCPTools() (src/session/agent-session.ts) rimuove tutti gli strumenti mcp_, ri-wrappa gli ultimi strumenti MCP e ri-attiva il set di strumenti in modo che le modifiche MCP si applichino senza riavviare la sessione.
Esiste anche un percorso di follow-up per le connessioni tardive: dopo aver atteso un server specifico, se lo stato diventa connected, ri-esegue session.refreshMCPTools(...) in modo che gli strumenti appena disponibili vengano riassociati nella sessione.
Salute, riconnessione e comportamento in caso di errore parziale
Sezione intitolata “Salute, riconnessione e comportamento in caso di errore parziale”Il comportamento attuale del runtime è intenzionalmente minimale:
- Nessun monitor autonomo della salute nel manager/client.
- Nessun ciclo di riconnessione automatica quando un trasporto si interrompe.
- Il manager non si iscrive a
onClose/onErrordel trasporto; lo stato è guidato dal registro. - La riconnessione è esplicita: flusso di ricaricamento o invocazione diretta di
connectServers().
Operativamente:
- il fallimento di un server non rimuove gli strumenti dai server sani,
- gli errori di connessione/lista sono isolati per server,
- la cache degli strumenti e gli aggiornamenti in background sono best-effort (warning/errori registrati nei log, nessun arresto forzato).
Semantica della terminazione
Sezione intitolata “Semantica della terminazione”Terminazione a livello di server
Sezione intitolata “Terminazione a livello di server”disconnectServer(name):
- rimuove le voci pendenti/metadati della sorgente,
- chiude il trasporto se connesso,
- rimuove gli strumenti
mcp_di quel server dallo stato del manager.
Terminazione globale
Sezione intitolata “Terminazione globale”disconnectAll():
- chiude tutti i trasporti attivi con
Promise.allSettled, - cancella le mappe pendenti, le sorgenti, le connessioni e la lista degli strumenti del manager.
Nel wiring attuale, la terminazione esplicita è usata nei flussi dei comandi MCP (per ricaricamento/rimozione/disabilitazione). Non esiste un hook separato di disposal automatico del manager nel percorso di avvio stesso; i chiamanti sono responsabili di invocare i metodi di disconnessione del manager quando necessitano di un arresto MCP deterministico.
Modalità di errore e garanzie
Sezione intitolata “Modalità di errore e garanzie”| Scenario | Comportamento | Errore grave vs best-effort |
|---|---|---|
| La discovery lancia un’eccezione (percorso di caricamento capability/config) | Il loader restituisce strumenti vuoti + errore sintetico .mcp.json | Avvio sessione best-effort |
| Configurazione server non valida | Server saltato con voce di errore di validazione | Best-effort per server |
| Timeout di connessione/errore di inizializzazione | Errore del server registrato; gli altri continuano | Best-effort per server |
tools/list ancora pendente all’avvio con cache disponibile | Strumenti differiti restituiti immediatamente | Avvio rapido best-effort |
tools/list ancora pendente all’avvio senza cache | L’avvio attende il completamento dei pendenti | Attesa forzata per correttezza |
| Errore tardivo di caricamento strumenti in background | Registrato nei log dopo il gate di avvio | Logging best-effort |
| Trasporto interrotto a runtime | Nessuna riconnessione automatica; le chiamate future falliscono fino a riconnessione/ricaricamento | Recupero best-effort tramite azione manuale |
Superficie dell’API pubblica
Sezione intitolata “Superficie dell’API pubblica”src/mcp/index.ts ri-esporta le API del loader/manager/client per i chiamanti esterni. src/sdk.ts espone discoverMCPServers() come wrapper di convenienza che restituisce la stessa forma di risultato del loader.
File di implementazione
Sezione intitolata “File di implementazione”src/mcp/loader.ts— facciata del loader, normalizzazione degli errori della discovery, conversioneLoadedCustomTool.src/mcp/manager.ts— registri di stato del ciclo di vita, flusso parallelo di connessione/lista, aggiornamento/disconnessione.src/mcp/client.ts— configurazione del trasporto, handshake di inizializzazione, lista/chiamata/disconnessione.src/mcp/index.ts— esportazioni dell’API del modulo MCP.src/sdk.ts— wiring di avvio nel registro sessione/strumenti.src/mcp/config.ts— discovery/filtraggio/validazione della configurazione usata dal manager.src/mcp/tool-bridge.ts— comportamento runtime diMCPTooleDeferredMCPTool.src/session/agent-session.ts— riassociazione dal vivorefreshMCPTools.src/modes/controllers/mcp-command-controller.ts— flussi interattivi di ricaricamento/riconnessione.src/task/executor.ts— proxy MCP del subagent tramite connessioni del manager padre.