Salta al contenuto principale

MCP server development: collegare Claude Code a tool esterni

Cluster 13 della serie Claude Code Workflow (primo Platform). MCP (Model Context Protocol) standardizza la connessione fra Claude Code e tool esterni: server stdio o HTTP, tool naming convention, auth, resource provisioning. Pattern per scrivere MCP server custom.

Cosa ne pensi di questo articolo?

MCP server development: collegare Claude Code a tool esterni
Claude Code WorkflowFoto:PixabayPexels

In Breve

Cluster 13 della serie Claude Code Workflow (primo Platform). MCP (Model Context Protocol) standardizza la connessione fra Claude Code e tool esterni: server stdio o HTTP, tool naming convention, auth, resource provisioning. Pattern per scrivere MCP server custom.

Risposta diretta

MCP risolve il problema di dover generare uno script e poi eseguirlo manualmente per interagire con il mondo esterno, riducendo i cicli lunghi e gli attriti. Con MCP, il modello chiama direttamente i tool esterni, come ad esempio "leggi gli ultimi 10 messaggi di posta da info@...", senza dover copiare e incollare o attendere risultati.

MCP (Model Context Protocol) è lo standard aperto di Anthropic per collegare LLM a tool esterni. Server MCP esponde un set di tool callable dal modello; Claude Code li indicizza e li invoca quando il task lo richiede. Per workflow tecnici, MCP è quel che separa "Claude che ti dà consigli" da "Claude che esegue azioni reali sui tuoi sistemi".

Disclaimer di indipendenza: non sono affiliato a qrx, ad Anthropic, né ai maintainer dei server MCP citati. Uso una manciata di MCP server sul portfolio (Gmail, Google Drive, claude-in-chrome, context7, firecrawl, exa, episodic-memory) installati come plugin Claude Code.

Cosa risolve MCP

Senza MCP, l'unico modo per far fare al modello qualcosa sul mondo esterno è chiedergli di generare uno script + tu lo esegui + restituisci l'output. Cicli lunghi, attriti high.

Con MCP, il modello chiama tool direttamente. Esempio: "leggi gli ultimi 10 messaggi di posta da info@..." con server Gmail MCP attivo = il modello chiama mcp__claude_ai_Gmail__list_messages e processa il risultato. Zero copy-paste, zero attriti.

Architettura essenziale

Server MCP esponde:

  • Tool: funzioni callable con input schema (JSONSchema). Il modello vede nome + description + schema e decide quando chiamarle.
  • Resource: dati statici (file, URL) che il modello può citare nel context.
  • Prompt template: template parametrici per casi d'uso ricorrenti.

Trasporto:

  • stdio: server gira come subprocess del Claude Code CLI. Comunicazione via stdin/stdout. No auth (gira locale come utente Claude Code).
  • HTTP: server remoto. Comunicazione via HTTP request/response. Auth tipicamente OAuth2 o API key.

Configurazione MCP

File: ~/.claude/mcp.json (user-level) o .claude/mcp.json (project-level). Esempio illustrativo:

{
  "mcpServers": {
    "gmail": {
      "command": "node",
      "args": ["/path/to/gmail-mcp-server/dist/index.js"],
      "env": {
        "GOOGLE_CLIENT_ID": "...",
        "GOOGLE_CLIENT_SECRET": "..."
      }
    },
    "context7": {
      "command": "npx",
      "args": ["@context7/mcp-server"]
    }
  }
}

Claude Code rilegge la config a ogni avvio sessione. Restart CLI dopo modifiche.

Tool naming convention

Tool MCP visibili al modello hanno path mcp__<server>__<tool>. Esempi:

  • mcp__gmail__list_messages (Gmail server, tool list_messages)
  • mcp__context7__resolve_library_id (context7 server)
  • mcp__firecrawl__scrape (firecrawl server)

Il modello sa quale tool chiamare basandosi su description del tool (analoga a quella delle skill - verbo + sostantivo specifico + condizione restrittiva).

Scrivere un MCP server custom

SDK ufficiali: TypeScript + Python (riferimento modelcontextprotocol/servers repo). Pattern minimo (illustrativo):

from mcp import server

app = server.Server("my-custom-server")

@app.tool()
async def query_internal_db(query: str) -> str:
    """Esegui una query SQL sul DB interno X.
    Use when investigating data in the internal X dataset."""
    # esegui query reale, return risultato come str
    ...

if __name__ == "__main__":
    app.run_stdio()

Decoratore @app.tool() registra la funzione come tool MCP. Il docstring diventa la description visibile al modello. Same regola che vale per skill: verbo+sostantivo+condizione concreta.

Quando scrivere MCP server custom

Tre situazioni dove vale la pena:

  1. Tool interno proprietario: lookup su CRM custom, query su DB interno, trigger di job legacy. MCP server custom espone questi tool al modello in modo strutturato.
  2. Workflow ripetitivo: una catena di N azioni che fai ogni settimana. Wrappa in tool MCP che orchestra le azioni internamente; il modello chiama un tool unico invece di N step.
  3. Bridging: tool che esiste come API HTTP non-MCP. MCP server wrapper espone i tool API come tool MCP. Pattern comune per portare API legacy nel mondo agentic.

Quando NON scrivere MCP custom

  1. Tool generico esistente: Postgres, Slack, GitHub, GDrive, ecc. hanno server MCP open source già fatti. Usa quelli, non reinventare.
  2. Tool one-shot: una azione che farai 2-3 volte. Meglio bash script + Claude che lo esegue, niente MCP overhead.
  3. Tool fortemente stateful: MCP è ottimizzato per chiamate stateless. State management complesso richiede design attento (e spesso un'API proper invece di MCP).

Server MCP che uso sul portfolio

  • claude-in-chrome: browser automation via Chrome DevTools Protocol. Util per smoke test post-deploy, screenshot manuali, debug UI.
  • Gmail / Google Drive / Google Calendar: integrazione con G Workspace personale. Lookup mail, lettura doc, scheduling.
  • context7: documentation lookup per librerie (es. "give me current docs of Angular 21 standalone components"). Più aggiornato del training data del modello.
  • firecrawl / exa: web scraping + semantic search controllati. Util per research durante /gsd-plan-phase.
  • episodic-memory: search/read di conversazioni passate di Claude Code (terze parti). Util per "ricordo che 6 mesi fa avevamo discusso X - trovami quella conversazione".

Sicurezza MCP

MCP server espone capability al modello. Misuse risks:

  1. Tool con side effect potenzialmente dannosi: es. "delete file", "drop table". Il modello potrebbe invocarli per errore. Mitigation: confirm-step nel tool (server chiede conferma all'utente prima di agire) o restrict scope (tool che fa delete solo su path specifico).
  2. Credential leakage: env vars del MCP server visibili nei log. Mitigation: log redacted, secret in OS-level secrets manager invece di .env.
  3. Prompt injection: dati ritornati dal tool potrebbero contenere istruzioni che il modello segue. Mitigation: sanitize output prima di restituire (escape control sequence, no eval di stringhe).

Discovery dei tool MCP attivi

In una sessione Claude Code, lista dei tool MCP attivi è visibile in system context (tipicamente reminder a inizio sessione). Su molte installazioni, è disponibile uno strumento per cercare tool MCP "lazy-loaded" (caricabili al volo se servono).

Sul mio setup, lo strumento ToolSearch carica schema dei tool al volo quando li chiamo (es. ToolSearch con query "select:mcp__gmail__list_messages" carica schema solo se serve invocarlo). Risparmia context window all'avvio.

Anti-pattern: troppi MCP server

Installare ogni server MCP esistente "perché magari serve" inflaziona il system context all'avvio sessione + introduce conflitti di tool naming (raro ma possibile). Installa solo i server che usi attivamente.

Sul mio setup, 8 server attivi. Provati a un certo punto 15+, ho fatto pruning lasciando solo quelli con uso almeno settimanale.

Cosa ho imparato scrivendo questo articolo

La sorpresa è quanto MCP abbia cambiato il mio rapporto con i tool esterni. Prima dovevo dire al modello "scrivi uno script per X, poi eseguilo tu, poi parsi l'output e mi dici". Ora dico "fai X" e il modello chiama il tool MCP appropriato. Si sente come passare da CLI a GUI: stessa potenza, attriti drasticamente ridotti.

Secondo insight: MCP custom è un piccolo investimento con ritorno grande sul brownfield. 2-3 ore per scrivere un MCP server custom su un sistema interno = settimane di tempo risparmiato a lungo termine. Il pattern "wrap API legacy in MCP" è quello che ha portato il mio portfolio dal "Claude consiglia" al "Claude esegue".

Anti-pattern evitati

  • MCP custom per tool generici. Postgres, GitHub, Slack hanno già server open source. Reinventarli è waste.
  • Tool MCP senza description chiara. Stesso problema delle skill: verbo+sostantivo+condizione. Description vaghi = invocazioni rumorose.

Una storia ricevuta che vale la pena condividere

Sezione segnaposto. Se hai scritto MCP server custom non-banali, scrivimi a federico@federicocalo.dev.


← Cluster precedente: Memory management (track GSD) Prossimo cluster: Hooks system →

Domande frequenti

Cosa risolve lo standard aperto di Anthropic chiamato MCP?

Lo standard MCP risolve il problema di collegare i modelli LLM a tool esterni, permettendo al modello di chiamare direttamente le funzionalità dei tool senza dover generare uno script e poi eseguirlo manualmente.

Come funziona l'architettura essenziale dello standard MCP?

L'architettura essenziale dello standard MCP prevede che i server MCP rispondano a richieste di configurazione, trasporto e tool naming convention, permettendo al modello di chiamare le funzionalità dei tool in modo efficiente.

Come si scrive un MCP server custom?

Per scrivere un MCP server custom è necessario utilizzare l' SDK ufficiale in TypeScript o Python e seguire il pattern minimo, che consiste nel registrare la funzione come tool MCP tramite un decoratore e specificare la descrizione del tool nel docstring.

Quando vale la pena scrivere un MCP server custom?

Scrivere un MCP server custom è utile nelle tre situazioni in cui il modello deve interagire con un sistema o una funzionalità specifica che non è già supportata da uno dei server MCP esistenti.

Fonti e approfondimenti

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti