MCP Tool Search: perché installare dieci MCP server non distrugge più il context window

MCP Tool Search: perché installare dieci MCP server non distrugge più il context window

Collega dieci MCP server a un agente e fai partire una sessione: prima ancora di scrivere una parola, l'agente ha già ingoiato qualche centinaio di definizioni di tool. Ognuna porta in finestra il proprio nome, la propria descrizione e lo schema JSON dei parametri, e un singolo server di media complessità ne espone facilmente dieci o quindici. Il conto, su una manciata di server, arriva a decine di migliaia di token consumati per descrivere strumenti che in quella sessione userai forse due volte. È il motivo per cui, fino a poco fa, il consiglio sensato era "tieni accesi pochi server": ogni integrazione in più era un costo fisso pagato a ogni turno, sottratto allo spazio che serviva al codice e al ragionamento. Nella mia pipeline personale di automazione gestisco agenti collegati a CRM, gestionali e tool interni, e questo tetto è stato a lungo il vincolo più fastidioso: o capacità o context, raramente entrambi. La tool search con lazy-loading ribalta proprio questo compromesso, e vale la pena capire come, perché cambia il modo in cui si progetta un agente con molte integrazioni.

Perché collegare molti MCP server costava context fisso

Il Model Context Protocol, lo standard aperto introdotto da Anthropic e oggi governato da una fondazione neutrale sotto la Linux Foundation, funziona dichiarando i tool all'agente. Nel modello classico questa dichiarazione avviene tutta all'avvio: il client raccoglie da ogni server collegato l'elenco completo degli strumenti con i relativi schemi e li inserisce nel contesto di sistema, dove restano per l'intera sessione. È una scelta sensata per due o tre tool, diventa un problema quando i server sono molti, perché quel blocco di definizioni è la base su cui poggia tutto il resto della conversazione.

C'è anche un motivo tecnico, legato al prompt caching, per cui quel blocco non si può spostare a piacimento. Il caching dei provider funziona per prefix matching: la parte stabile del prompt (istruzioni di sistema, definizioni dei tool) viene messa in cache e riusata a sconto sui turni successivi, ma solo finché resta identica e in testa. Cambiare l'elenco dei tool a metà sessione invalida la cache e fa ripagare tutto il prefisso a prezzo pieno. Il risultato è una tensione precisa: le definizioni dei tool vogliono stare in testa e immutabili per il caching, ma se sono tante occupano un budget di attenzione enorme prima ancora che serva.

La regola da interiorizzare è che in un agente il costo di un tool non si paga quando lo usi, si paga quando lo dichiari. Dieci server collegati e mai chiamati pesano comunque su ogni singolo turno.

Cosa cambia con la tool search: gli schemi caricati on-demand

La tool search inverte la logica di caricamento. Invece di iniettare all'avvio lo schema completo di ogni strumento, fornisci alla API l'intero catalogo ma marchi i tool con defer_loading: true: questi non entrano nel contesto iniziale, dove resta solo un Tool Search Tool insieme ai pochi strumenti critici lasciati a caricamento immediato (defer_loading: false). Quando il task lo richiede, il modello cerca i tool pertinenti e ne fa espandere lo schema completo solo in quel momento. La ricerca esiste in due varianti, per pattern regex oppure in linguaggio naturale con algoritmo BM25, restituisce tipicamente da tre a cinque tool per query e regge un catalogo che la documentazione ufficiale dichiara fino a diecimila strumenti. È una funzionalità in beta pubblica (richiede gli header advanced-tool-use-2025-11-20 e, per i server MCP, mcp-client-2025-11-20) e supportata su Claude Sonnet 4.5 e 4.6 e Opus 4.5 e 4.6, non su Haiku: dettagli e formato esatto della richiesta sono nella documentazione del Tool Search Tool.

I numeri che Anthropic ha pubblicato presentando la feature danno la misura del problema. Nel loro post di ingegneria sull'advanced tool use, una configurazione di cinque server con cinquantotto tool consuma circa 55.000 token prima ancora che la conversazione cominci, un singolo connettore come quello di Jira ne porta da solo circa 17.000, e nei sistemi interni di Anthropic le definizioni dei tool erano arrivate a occupare 134.000 token. Con la tool search attiva, Anthropic dichiara una riduzione del consumo di token intorno all'85%, accompagnata da un miglioramento di accuratezza sulle valutazioni MCP con cataloghi ampi (nei loro test interni il modello di punta passa dal 79,5% all'88,1%). Sono cifre del vendor, misurate sui propri benchmark: il segnale è netto, ma l'entità reale va verificata sul proprio carico prima di darla per acquisita.

Detto in termini pratici: dieci server collegati non valgono più dieci blocchi di definizioni sempre presenti. Valgono il Tool Search Tool più gli schemi dei pochi tool che la sessione attraversa davvero. La capacità non la perdi, la paghi a consumo. Per chi costruisce agenti con molte integrazioni, questa è la differenza tra dover scegliere quali sistemi collegare e poterli collegare tutti lasciando che sia il modello a tirare dentro lo strumento giusto al momento giusto, secondo lo stesso approccio che descrivo nei miei MCP server personalizzati per il workflow aziendale.

Se stai progettando un agente che deve parlare con molti sistemi del tuo stack e vuoi capire come imposto questa architettura senza farla collassare sotto il proprio peso, nel mio hub dedicato all'AI per lo sviluppo raccolgo gli articoli con la metodologia che applico sul campo.

Come si configura il lazy-loading dei tool

Sul piano operativo la leva si chiama deferred loading, e va capita per quello che è: non un flag nel file di configurazione locale dei server, ma un attributo che viaggia nella richiesta alla API. Su un singolo tool si imposta defer_loading: true nel suo blocco di definizione; per un intero server MCP collegato come connettore si applica lo stesso principio a livello di toolset, tramite il default_config del server. Insieme va dichiarato il Tool Search Tool, che è esso stesso un tool e resta sempre caricato. A livello concettuale, la parte della richiesta che governa un server differito assomiglia a questo:

{
  "tools": [
    { "type": "tool_search_tool_regex_20251120", "name": "tool_search" }
  ],
  "mcp_servers": [
    {
      "type": "url",
      "url": "https://mcp.gestionale-interno.example/sse",
      "name": "gestionale-interno",
      "default_config": { "defer_loading": true }
    }
  ]
}

Due vincoli, dichiarati nella documentazione, vanno tenuti a mente: marcare come differiti tutti i tool, incluso il Tool Search Tool, produce un errore 400, e un pattern regex di ricerca non può superare i 200 caratteri. Il principio architetturale da rispettare resta la cache-safety: i tool vanno trattati come stati stabili del prompt, mai modificati a metà sessione. Il caricamento differito è compatibile con il prompt caching perché non altera il prefisso condiviso; cambiare l'elenco dei server attivi durante la sessione, invece, lo rompe e fa ripagare tutto il prefisso. La mia regola pratica è decidere la topologia dei server all'inizio e lasciare che sia il lazy-loading a gestire il dettaglio, la stessa disciplina di prefisso stabile che ho analizzato parlando di prompt caching a livello di workspace.

Quanto context consuma davvero un MCP server prima ancora di usarlo?

Con il caricamento classico, un MCP server consuma context proporzionalmente al numero di tool che espone, non al numero di tool che usi: dieci strumenti dichiarati sono dieci schemi in finestra, anche a zero chiamate. Con la tool search attiva, lo stesso server costa quanto il suo indice più gli schemi effettivamente risolti, che su una sessione mirata sono spesso uno o due. È la ragione per cui la metrica giusta quando si dimensiona un agente non è "quanti server posso collegare" ma "quanti tool sono rilevanti per il task corrente".

Questo sposta anche il punto di attenzione nella diagnosi dei costi. Quando un agente con molte integrazioni costa troppo o rallenta, la prima cosa che guardo non è il numero di chiamate, è quanto contesto se ne va in definizioni mai usate. Spesso il collo di bottiglia non è il lavoro che l'agente fa, è la dotazione che si porta dietro a vuoto.

Il pattern di selezione: pochi tool sempre, molti a richiesta

Il lazy-loading non elimina la necessità di progettare: la sposta. Il pattern che applico è una gerarchia a due livelli. Un nucleo ristretto di tool resta caricato sempre, quelli che servono a quasi ogni task (lettura del filesystem, esecuzione di comandi, accesso al repository). Tutto il resto, le integrazioni verticali verso i sistemi del cliente, vive dietro la tool search e si materializza solo quando il modello ne ha bisogno. La progettazione consiste nel decidere cosa sta nel nucleo e cosa sta nella riserva, e nello scrivere descrizioni dei tool che siano trigger affidabili, perché è sulla descrizione che la tool search decide se quel tool è pertinente.

Qui entra in gioco un'asimmetria interessante con i server custom. Un server generico, scaricato da un marketplace, espone spesso decine di tool dei quali ne userai una frazione, e affida tutto alla bravura della ricerca. Un server scritto su misura espone solo le operazioni che servono, con descrizioni calibrate sul dominio reale: la tool search funziona meglio perché lo spazio di ricerca è già pulito. Per questo, anche nell'era del caricamento differito, continuo a preferire pochi server custom a molti server generici. Il lazy-loading rende sostenibile la quantità, ma la qualità delle definizioni resta una scelta di progettazione, come ho visto smontando l'architettura del Tool Registry nel codice emerso dal leak dello scaffolding di Claude Code.

Quando il lazy-loading non basta, e serve orchestrare

C'è un limite oltre il quale la sola tool search non risolve. Se un task richiede di concatenare molte chiamate a tool diversi, far passare ogni risultato intermedio dentro il contesto del modello torna a essere costoso, perché ogni output rientra in finestra. È lo scenario per cui esiste il Programmatic Tool Calling: lasciare che il modello scriva codice che orchestra le chiamate ai tool, tenendo i risultati intermedi fuori dal contesto e portando dentro solo ciò che serve alla decisione finale. È un altro modo di attaccare lo stesso problema, il context come risorsa scarsa, ma a un livello più alto: non più "quali schemi carico", bensì "quali risultati mi tengo".

Per un consulente che costruisce automazioni reali, la combinazione dei due meccanismi cambia le scelte di architettura. Collegare molti sistemi non è più un lusso da centellinare: la tool search rende la dotazione economica, il Programmatic Tool Calling rende economica l'orchestrazione, e la responsabilità progettuale si concentra dove deve stare, sulla qualità dei server e delle loro descrizioni.

La tool search è già pronta per la produzione?

La risposta onesta è che il meccanismo è solido ma la qualità del recupero va misurata sul proprio caso. La feature è in beta pubblica, e il suo punto debole non è il risparmio di context, che è reale e consistente, bensì l'accuratezza della ricerca: se il modello cerca lo strumento giusto e non lo trova, il task fallisce in modo silenzioso. Test indipendenti hanno riportato accuratezze di retrieval intorno al 60% su cataloghi e descrizioni non ottimizzati, un valore che non basta quando l'agente deve compiere azioni reali e irreversibili. Non è un argomento contro la tool search, è un argomento a favore del lavoro di progettazione che la rende affidabile.

Da qui discende la pratica che applico prima di mettere in produzione un agente con molte integrazioni: trattare le descrizioni dei tool come si tratta un indice di ricerca, non come una didascalia. Una descrizione scritta come trigger esplicito (cosa fa lo strumento, su quali entità, in quali casi va scelto) alza l'accuratezza del recupero molto più di qualunque ottimizzazione di basso livello. E i tool davvero critici, quelli il cui fallimento non è accettabile, li lascio fuori dal differimento, sempre caricati: la tool search è per la coda lunga delle integrazioni, non per il nucleo su cui l'agente non può sbagliare.

Il quadro, messo insieme, è una buona notizia per chiunque costruisca agenti con molte integrazioni, ma non un invito a smettere di pensare. La tool search con lazy-loading ha tolto il tetto che obbligava a scegliere tra capacità e context, e questo apre la porta ad architetture che fino a ieri erano antieconomiche, dall'agente che parla con l'intero stack del cliente al singolo workflow che attraversa cinque sistemi. Ma il costo non sparisce, si sposta: dalla dichiarazione dei tool alla qualità delle loro descrizioni, dal numero di server alla pulizia del loro perimetro, dalle chiamate singole all'orchestrazione dei risultati. Chi progetta gli agenti tenendo a mente dove si è spostato quel costo costruisce sistemi che scalano; chi crede che il caricamento differito abbia reso il context gratis si ritrova, qualche mese dopo, con un agente lento e costoso e nessuna idea del perché. Se stai mettendo in piedi un agente con molte integrazioni e vuoi una lettura onesta di dove stai spendendo context e dove invece puoi collegare di più senza pagarlo, puoi usare il modulo di preventivo gratuito: sette domande, due minuti, e ti dico se il tuo caso rientra nel mio perimetro o se ti conviene un'altra figura.

Ultima modifica: