Standard di integrazione delle app connesse MCP

Il server MCP stabilisce il framework per collegare le funzioni della tua app (strumenti MCP) alla Connected Apps Platform. Per consentirgli di selezionare, chiamare ed elaborare i risultati del tuo servizio in modo più affidabile, la configurazione MCP deve rispettare rigorosamente i seguenti standard.

Principi guida

Per ogni funzione, concentrati sullo user intent e sui casi d'uso, non sulle funzionalità della funzione. La descrizione è il modo principale per indicare al modello lo scopo dello strumento e i casi d'uso a cui può rispondere.

Versioni

Per supportare deployment MCP scalabili e solidi, adotta un'architettura URI strutturata che utilizzi il controllo delle versioni basato su percorso, ad esempio /v1, /v2. In questo modo, puoi mantenere la compatibilità con le versioni precedenti e controllare le nuove funzionalità. L'integrazione con sottodomini specifici del provider, come https://gemini.mcp.company.com/mcp/v1, consente una gestione granulare del traffico e l'ottimizzazione delle definizioni degli strumenti in base al contesto e ai comportamenti di elaborazione unici dei diversi modelli di AI.

Compatibilità della versione del protocollo MCP

La Connected Apps Platform supporta la specifica Model Context Protocol (MCP) fino alla versione 2025-11-25. Le versioni più recenti delle specifiche non sono ancora supportate.

  • Responsabilità dello sviluppatore: è tua responsabilità assicurarti che il tuo server MCP rispetti rigorosamente una versione del protocollo supportata dalla piattaforma Connected Apps (2025-11-25) durante l'handshake initialize e in tutte le definizioni di strumenti e schemi.
  • Compatibilità con le versioni precedenti della piattaforma: man mano che la Connected Apps Platform adotterà nuove versioni delle specifiche MCP in futuro, il nostro client manterrà la compatibilità con le versioni precedenti del protocollo supportate in precedenza, in modo che le integrazioni di produzione esistenti continuino a funzionare senza interruzioni.
  • Gestione degli upgrade: quando è tutto pronto per adottare una nuova specifica MCP supportata o introdurre modifiche allo schema, esponi questi aggiornamenti su un nuovo percorso URI con controllo delle versioni (ad esempio, /mcp/v2) mantenendo l'endpoint esistente (/mcp/v1) per il traffico attivo.

Le modifiche agli schemi MCP sono consentite tra le versioni dell'app. Ti consigliamo di sfruttare questa funzionalità e di creare versioni degli endpoint MCP per supportare un'implementazione graduale delle nuove funzionalità o di fare affidamento esclusivamente su modifiche compatibili con le versioni precedenti.

Specifica del protocollo di trasporto

La piattaforma Connected Apps supporta rigorosamente la specifica Model Context Protocol per il trasporto HTTP trasmissibile in streaming, versione 2025-03-26 e successive. Non supporta il trasporto HTTP legacy con SSE descritto dalla specifica del 5 novembre 2024.

  • Endpoint HTTP singolo. L'endpoint MCP fornito nella Connected Console (ad esempio https://api.example.com/mcp) è l'unico URL a cui i prodotti Google applicabili inviano tutte le richieste JSON-RPC (initialize, tools/list, tools/call) tramite HTTP POST standard.
  • Streaming SSE all'interno di HTTP trasmissibile in streaming. Il trasporto SSE multi-endpoint legacy non è supportato, ma gli eventi inviati dal server come text/event-stream sono supportati all'interno di Streamable HTTP. Le richieste in uscita dai prodotti Google applicabili includono Accept: application/json, text/event-stream, il che significa che il tuo server può restituire un payload application/json standard o trasmettere risposte incrementali utilizzando Content-Type: text/event-stream direttamente nel corpo della risposta HTTP POST.
  • GET stream & 405 Method Not Allowed. I client possono tentare uno stream GET facoltativo sull'endpoint per le notifiche server-client. Se il tuo server è stateless o solo di richiesta-risposta, la restituzione di HTTP 405 Method Not Allowed è esplicitamente supportata e gestita in modo pulito dal proxy client del prodotto Google applicabile.

Istruzioni per il server

La Connected Apps Platform è ottimizzata per l'acquisizione delle istruzioni del server, consentendo un livello di controllo sul comportamento del modello non disponibile con altri mezzi.

Segui le istruzioni del server.

Trattalo come un "suggerimento per il modello" con il contesto di utilizzo

Segui queste linee guida per fornire suggerimenti ai modelli.

  • Scrivi le istruzioni come un "suggerimento" o una guida di alto livello per aiutare l'LLM a comprendere lo scopo e le funzionalità generali del server.
  • Descrivi cosa può fare, anziché elencare le funzionalità o descrivere come il modello deve utilizzare gli strumenti e le risorse del server. Se il modello comprende correttamente il "cosa", può determinare il "come" in modo abbastanza preciso in base al percorso dell'utente.
  • Supponi che questo testo venga aggiunto direttamente al prompt di sistema del modello. Mantieni un tono chiaro, direttivo ed efficiente in termini di token.

Integra, non duplicare

Utilizza questo spazio per il contesto globale che si applica a tutti gli strumenti, evitando ridondanze con le descrizioni dei singoli strumenti.

Esempi di istruzioni per il server

I seguenti esempi mostrano cosa fare e cosa non fare per scrivere correttamente le istruzioni del server.

Consigliati Non consigliato

Agisci come gestore specializzato di repository GitHub. Questo server fornisce un accesso approfondito ai metadati del repository, all'Issue Tracker e ai workflow delle PR. Utilizzalo per mantenere l'integrità del progetto, automatizzare il triage e garantire gli standard del codice. Se non diversamente specificato, si presume che tutte le azioni vengano eseguite nel contesto dell'organizzazione autenticata. Dai la priorità all'identificazione di thread inattivi o PR non collegati per mantenere organizzato il repository.

Concise, direttive e complementari al modello

  • Definisce il "cosa" (integrità del progetto, triage) anziché il "come"
  • Menziona l'ambito di autenticazione che si applica a tutti gli strumenti

Questo server dispone di strumenti per GitHub. Devi utilizzare lo strumento list_issues quando l'utente chiede informazioni sui problemi. Puoi utilizzare create_pull_request per creare una richiesta di pull. Utilizza questi strumenti con attenzione per aiutare l'utente a gestire il proprio codice. Controlla sempre il nome del repository prima di chiamare uno strumento. Se l'utente chiede un riepilogo, chiama prima gli strumenti e poi riassumi l'output

  • non elencare di nuovo i nomi degli strumenti,
  • non dire al modello "come" pensare, perché questo può entrare in conflitto con il ragionamento integrato del modello, che utilizzerà il contesto dell'utente per fare la scelta giusta.
  • non spiega la natura dell'accesso del server o i suoi vincoli specifici)

Linee guida per gli strumenti

Le seguenti linee guida descrivono le best practice per la creazione di configurazioni del server MCP per varie funzioni o strumenti all'interno della tua app.

Convenzioni di denominazione degli strumenti

Attieniti alle seguenti linee guida per assegnare un nome allo strumento:

Utilizza nomi intuitivi e leggibili

Utilizza nomi leggibili con significati chiari e intuitivi anziché ambigui. Ad esempio, get_user_information è più semplice di userInfo.

Utilizza lo stile di maiuscole/minuscole corretto

Rispetta le seguenti regole per l'uso delle maiuscole per i nomi delle funzioni degli strumenti e i trigger delle app:

  • Involucro della funzione dello strumento. Utilizza snake_case o camelCase per i nomi delle funzioni degli strumenti definiti nello schema MCP (ad esempio, get_user_information o publishDraft).
  • Alloggiamento della maniglia di attivazione dell'app. Gli attivatori e le menzioni delle app (ad esempio, @MyTwoWordApp) non fanno distinzione tra maiuscole e minuscole. La piattaforma normalizza gli input degli utenti in minuscolo (@mytwowordapp), PascalCase (@MyTwoWordApp) e camelCase (@myTwoWordApp).
  • Formattazione del nome visualizzato. Registra il titolo ufficiale dell'app utilizzando PascalCase o spazi standard per una visualizzazione chiara negli elementi UI.
  • Gestione degli errori di battitura. Mentre le variazioni di maiuscole e minuscole vengono gestite automaticamente, gli errori di battitura dei caratteri (ad esempio @mytwowrodapp) si basano sul riconoscimento dell'intent di riserva anziché sulla corrispondenza diretta delle stringhe. Gli sviluppatori devono incoraggiare l'ortografia corretta degli handle nella documentazione.

Utilizza una denominazione esplicita verbo-sostantivo

Utilizza nomi specifici per verb_noun ed evita ambiguità, ad esempio publish_draft è meglio di handle_content.

Granularità dello strumento

Attieniti alle seguenti linee guida relative alla granularità degli strumenti.

Tratta gli strumenti come endpoint atomici

Tratta gli strumenti come endpoint atomici senza condizioni interne o più funzionalità con i rispettivi parametri obbligatori. Gli strumenti granulari consentono al modello di concatenare i passaggi in modo logico, riducendo le allucinazioni.

Utilizza schemi più semplici

Se hai bisogno di oggetti con nidificazione profonda o di una logica di schema oneOf/anyOf complessa per convalidare gli input, è probabile che il tuo strumento sia troppo ampio.

Osserva le misure di salvaguardia relative alla pre-aggregazione e al payload

Sebbene la pre-aggregazione dei dati non sia applicata rigorosamente dal protocollo per payload piccoli e con ambito, la pre-aggregazione del backend è fortemente richiesta in pratica quando si lavora con set di record di grandi dimensioni, cronologia longitudinale e set di dati provenienti da più origini. La piattaforma Connected Apps applica misure di protezione relative ai limiti della finestra di contesto, alla latenza di esecuzione e ai passaggi di ragionamento del modello. Per rispettare questi guardrail, segui queste linee guida:

  • Filtra e riepiloga nel backend. Filtra, pre-aggrega o riepiloga sempre i flussi di dati di grandi dimensioni sul tuo server MCP prima di restituire le risposte ai prodotti Google applicabili.
  • Evita i dump non elaborati. Non inserire mai righe di database non elaborate o log completi non indicizzati nel payload restituito dallo strumento.

Ometti strumenti interni e meta

Esponi solo le funzionalità rivolte al modello nella risposta tools/list del tuo server:

  • Filtra gli strumenti di supporto: ometti tutti gli strumenti interni, amministrativi o meta che non sono destinati a essere chiamati dal modello (ad esempio, controlli di integrità del server, routine di configurazione interna o strumenti di supporto per gli sviluppatori).
  • Efficienza della finestra contestuale: l'esclusione degli strumenti non necessari mantiene conciso lo schema MCP, riduce il consumo di token della finestra contestuale e previene la confusione nel routing degli strumenti del modello. I server MCP che espongono decine di strumenti o schemi di "mega-strumenti" con nidificazione profonda verranno segnalati durante la revisione per le correzioni.

Cosa fare e cosa non fare in merito alla granularità degli strumenti

I seguenti esempi mostrano cosa fare e cosa non fare in merito alla denominazione degli strumenti e all'utilizzo della granularità.

Consigliati Non consigliato

Strumenti granulari con nomi e parametri chiari

Lo schema di input per ogni strumento è rigido. Se l'LLM vuole creare un utente, deve fornire un indirizzo email. Se vuole eliminare, deve fornire un ID. Non ci sono congetture.

...
@mcp.tool()
def create_user(email: str, role: str = "viewer") -> str:
    """Register a new user. Returns the new User ID."""
    # Logic is purely creation
    return "user_123"

@mcp.tool()
def delete_user(user_id: str) -> str:
    """Permanently remove a user by their ID."""
    # Logic is purely deletion
    return f"User {user_id} deleted"

@mcp.tool()
def update_user_role(user_id: str, new_role: str) -> str:
    """Change an existing user's permission level."""
    return f"User {user_id} is now {new_role}"

    ...

Nome dello strumento: manage_user

Description: "Use this tool to create, update, delete, or retrieve users."

...
@mcp.tool()
def manage_user(
    action: Literal["create", "update", "delete", "get"],
    user_id: Optional[str] = None,
    email: Optional[str] = None,
    role: Optional[str] = "viewer"
) -> str:
    """
    Use this to manage users.
    WARNING: logic is hidden inside Python, not visible in the schema.
    """
    if action == "create":
        if not email: return "Error: Email required for creation" # Runtime error, not schema error
        return f"Created user {email}"
    elif action == "delete":
        if not user_id: return "Error: User ID required"
        return f"Deleted {user_id}"
    
    return "Action completed"
    """
    ...

Dichiara le annotazioni degli strumenti per la sicurezza

Configura le annotazioni del protocollo all'interno delle definizioni degli strumenti per comunicare il comportamento di esecuzione e attivare i controlli di sicurezza integrati nei prodotti Google applicabili:

  • Gate di conferma di runtime: i prodotti Google applicabili utilizzano annotations.destructiveHint: true e annotations.openWorldHint: true come flag chiave per attivare i prompt di conferma dell'utente di runtime. Dichiara destructiveHint: true per le azioni di modifica dello stato, di scrittura o distruttive e imposta openWorldHint: true per gli strumenti che interagiscono con ambienti open world o esterni, in modo che la piattaforma chieda in modo nativo all'utente di confermare prima dell'esecuzione.
  • Suggerimento per le query di sola lettura: imposta readOnlyHint: true sugli strumenti di query che recuperano solo i dati senza modificare lo stato del backend.
  • Valori predefiniti delle annotazioni esplicite: in base alla specifica del Model Context Protocol, l'omissione di readOnlyHint fa sì che i client assumano readOnlyHint: false e destructiveHint: true per impostazione predefinita per motivi di sicurezza. La dichiarazione esplicita delle annotazioni su tutti gli strumenti garantisce un routing del modello prevedibile e una corretta sicurezza dell'esecuzione.

Descrizioni degli strumenti

La descrizione è l'unico contesto che il modello ha per decidere se lo strumento può risolvere il problema attuale. Attieniti alle seguenti linee guida per la scrittura delle descrizioni:

Scrivi istruzioni, non commenti

Scrivi le descrizioni degli strumenti come istruzioni e non come commenti del codice, che spesso sono passivi. Gli LLM rispondono bene alle istruzioni.

Spiega il "come"

Una buona descrizione colma il divario tra "Ho uno strumento" e "So come collegare questo strumento a una conversazione".

Spiega il "perché"

Distingui questo strumento da altri simili, ad esempio "Utilizza questo strumento per gli utenti interni, utilizza customer_update per quelli esterni".

Indica al modello dove trovare gli argomenti, ad esempio "dallo strumento order_search".

Specifica il formato

Specifica le unità (metri o piedi) e i formati (date ISO, versioni semantiche).

Evita la discrezionalità del modello

Non chiedere al modello di utilizzare il suo "miglior giudizio" o di suggerire azioni facoltative e non guidate.

Esempi di descrizioni degli strumenti

I seguenti esempi mostrano cosa fare e cosa non fare per scrivere le descrizioni degli strumenti.

Consigliati Non consigliato

Fonte attendibile

"Aggiorna l'email di un utente. Devi utilizzare rigorosamente l'"id" UUID restituito dallo strumento search_users. Non dedurre o indovinare gli ID utente."

(Collega esplicitamente l'output di uno strumento all'input di questo.)

"Aggiorna l'indirizzo email dell'utente."

(Il modello potrebbe indovinare un ID come 12345.)

Formato e vincolo

"Pianifica una riunione. "date" deve essere nel formato ISO 8601 (AAAA-MM-GG). Se l'utente dice "domani" o un altro riferimento relativo, calcola la data in base al contesto attuale."

"Pianifica una riunione per la data indicata."

(sembra corretto per un essere umano, ad esempio "domani", ma non supera la convalida dello schema, che richiede "2025-10-12")

Aspettative di output

"Recupera i log del server. Restituisce le ultime 50 righe di testo non elaborato. Per l'analisi, richiedi finestre temporali più piccole per evitare i limiti di token."

"Scarica i log del server".

(Il modello potrebbe chiamare uno strumento aspettandosi un riepilogo, ricevere un dump JSON non elaborato di 5 MB e offrire un'esperienza utente scadente).

@mcp.tool()
def update_campaign_status(campaign_id: str, status: str) -> str:
    """
    Promotes or pauses an advertising campaign.
    
    CRITICAL USAGE RULES:
    1. 'campaign_id': Must be the 32-character UUID retrieved from 'list_campaigns'.
    2. 'status': Must be exactly one of: ['active', 'paused', 'archived'].
    
    Returns: A confirmation string with the new status and timestamp.
    """
    # Logic...

    ...

Questa descrizione funge da mini-manuale. Gestisce l'origine (dove ottenere l'ID), i vincoli (enum validi) e l'azione.

@mcp.tool()
def update_campaign_status(id: str, status: str) -> str:
    """
    Updates the campaign status in the database.
    """
    # Logic...

In questo modo, i nomi delle variabili svolgono tutto il lavoro. Lascia che il modello indovini i valori validi per "status"

Parametri dello strumento

Oltre allo strumento stesso, descrivi i parametri per renderli univoci.

Tipi espliciti

Utilizza tipi specifici e ben definiti (string, integer, boolean, array).

Utilizza gli enum per gli insiemi di valori fissi

Se un parametro accetta solo un insieme fisso di valori (ad esempio daylight, cool, warm), elencali in un array enum. Questo migliora drasticamente l'accuratezza.

Indicare chiaramente i parametri obbligatori

Definisci chiaramente quali parametri sono obbligatori per il funzionamento della funzione.

Applica la corrispondenza dello schema semantico

Durante l'integrazione dell'app, potrebbe essere necessaria una corrispondenza semantica dello schema tra i parametri degli strumenti e il vertical per cui stai sviluppando. Riceverai lo schema verticale previsto (uno schema JSON) durante la procedura di onboarding.

Esempi di parametri degli strumenti

I seguenti esempi mostrano cosa fare e cosa non fare per la gestione dei parametri degli strumenti.

Consigliati Non consigliato

Formati e unità di misura degli argomenti

radius: "Il raggio in metri. Deve essere un numero in virgola mobile > 0."

(prevents unit hallucination)

radius: "Il raggio del cerchio."

Formati e contesto degli ID

user_id: "L'UUID del database (ad esempio, 550e8400-e29b…). Non utilizzare indirizzi email qui."

Nota: come best practice, tutti i campi ID numerici devono essere trattati come valori di stringa. In particolare, se l'ID potrebbe avere più di 10 cifre, rischi che venga troncato dai sistemi interni (forzato in un contenitore a 32 bit) e che questa versione venga utilizzata dal modello nelle future chiamate allo strumento.

(evita errori di tipo)

user_id: "L'ID dell'utente."

Aspettative relative al valore restituito

"Aggiorna il record e restituisce l'oggetto JSON aggiornato, incluso il nuovo timestamp."

(Indica al modello che non è necessario chiamare uno strumento "get " subito dopo l'"update" per verificare la modifica.)

"Aggiorna il record."


@mcp.tool()
def search_logs(query: str, limit: int = 10) -> str:
    """
    Searches server error logs using Lucene syntax (e.g. 'level:ERROR AND service:auth').
    
    Args:
        query: A Lucene-formatted search string.
        limit: Max results to return. capped at 50.
    
    Returns:
        A formatted string of log entries with timestamps.
    """
    ...
  
@mcp.tool()
def search_logs(query: str, limit: int = 10) -> str:
    """Searches the logs."""
    ...

L'LLM non sa quale sintassi supporta "query" (SQL? Regex? Testo normale?) Non sa qual è il "limite" massimo.

Risposte e gestione degli errori

In conformità con il principio fondamentale La risposta è il prompt successivo, lo strumento segnala il risultato della sua esecuzione sottostante restituendo un payload di dati, che viene poi incollato direttamente nella finestra contestuale dell'LLM. L'esito positivo o negativo del risultato determina cosa succede dopo:

  • Se l'operazione ha esito positivo: il modello ha bisogno del valore restituito per sapere cosa è successo e decidere il passaggio successivo.
  • Se non riesce: il modello deve sapere perché non è riuscito e come risolvere il problema. Un arresto anomalo (errore 500) interrompe la conversazione; un messaggio di errore descrittivo consente al modello di correggersi autonomamente.

Indipendentemente dal fatto che la logica di base dello strumento abbia esito positivo o negativo, devi formattare il payload del valore restituito in modo che il modello possa analizzarlo facilmente. Segui queste best practice per la creazione del payload di risposta.

Utilizza JSON

Formatta i dati strutturati in TextContent (vincolo temporaneo). Poiché structuredContent non è ancora supportato in Connected Apps Platform, serializza manualmente i dati. Anche se restituisci un elenco semplice, json.dumps().

Includi gli URL nella risposta

Gli URL restituiti devono essere relativamente brevi e senza molti parametri. È consigliabile utilizzare i servizi di abbreviazione URL per risparmiare sul conteggio dei token e ridurre il rischio di allucinazioni.

Payload anti-allucinazione autodescrittivi

Abbina sempre i codici non elaborati o gli ID interni a nomi visualizzati leggibili, unità di misura esplicite e intervalli di riferimento. Non restituire mai chiavi di dizionario compresse o codici numerici non mappati che costringono il modello a dedurre il contesto.

Implementa una gestione degli errori efficace

Restituisci messaggi di errore chiari e significativi in modo che il modello possa capire cosa è andato storto e informare l'utente. Consulta la gestione degli errori MCP.

Utilizza try/except

Aggrega la logica dello strumento in blocchi try/except e restituisci gli errori convertiti in stringhe.

Fornire errori utili

Suggerisci il passaggio successivo nel messaggio di errore (ad esempio, "Prova a utilizzare prima lo strumento X").

Conferma azioni

Non restituire stringhe vuote per gli strumenti con effetti collaterali (creazione/aggiornamento/eliminazione).

Esempi di risposte e gestione degli errori

Gli esempi riportati di seguito mostrano cosa fare e cosa non fare in merito alle risposte e alla gestione degli errori.

Consigliati Non consigliato

Serializzazione esplicita


...
import json

@mcp.tool()
def query_metrics(metric_id: str) -> str:
    result = {"id": metric_id, "value": 42, "unit": "ms"}
    # GOOD: Returns '{"id": "cpu", "value": 42}' -> Valid JSON
    return json.dumps(result, indent=2)

...
@mcp.tool()
def query_metrics(metric_id: str) -> str:
    result = {"id": metric_id, "value": 42, "unit": "ms"}
    # BAD: Returns "{'id': 'cpu', 'value': 42}" -> Invalid JSON
    return str(result)

Cattura e informa


...
@mcp.tool()
def get_user_details(user_id: str) -> str:
    try:
        user = db.get_user(user_id)
        if not user:
             # GOOD: Informative error returned as content
            return f"Error: User with ID '{user_id}' not found. Please verify the ID using 'search_users'."
        return json.dumps(user)
    except Exception as e:
        return f"Error: Database connection failed ({str(e)}). Please try again later."

(Lo strumento "ha esito positivo" dal punto di vista tecnico (restituisce una stringa), ma la stringa contiene i dettagli dell'errore. Il modello legge questo messaggio, si rende conto che l'ID non esiste e può chiedere all'utente l'ID corretto.


...
@mcp.tool()
def get_user_details(user_id: str) -> str:
    # BAD: Unhandled exception if ID not found
    user = db.get_user(user_id)
    return json.dumps(user)

Se get_user non va a buon fine, il server genera un errore 500. L'LLM riceve un errore di esecuzione generico e non ne conosce il motivo (l'ID era errato? Database inattivo? Permission denied?). È probabile che riprovi con lo stesso input errato).

Risposte vuote

...
@mcp.tool()
def post_story(story_content: str) -> str:
    service_name = "story_service"
    api_client.post("/stories", json={"content": story_content})
    # GOOD: Explicit confirmation of state change.
    return f"Service '{service_name}' successfully posted content. Status is now 'posted'."

...
@mcp.tool()
def post_story(storyContent: str):
    subprocess.post(["postsrv", "story", storyContent])
    # BAD: Returns null/empty string. Model is confused.

Gli LLM spesso si confondono con le risposte vuote. Potrebbero avere allucinazioni del tipo "Lo strumento non è riuscito" o semplicemente ripetere la chiamata.

Payload anti-allucinazione autodescrittivo

Associa sempre i codici non elaborati o gli ID interni a nomi visualizzati leggibili, unità di misura esplicite e intervalli di riferimento normali.

{"lab_code": "2345-7", "display_name": "Glucose [Mass/volume] in Blood", "value": 105, "unit": "mg/dL", "reference_range": "70-99 mg/dL"}

(In questo modo, il modello sa esattamente cosa significa il valore senza dover dedurre unità o soglie di riferimento).

ID non elaborati, compressione personalizzata o codici non mappati

Restituzione di ID interni non elaborati, abbreviazioni di dizionari personalizzati o codici numerici senza etichette.

{"code": "2345-7", "v": 105}

(Costringe il modello a indovinare a cosa si riferisce 105, il che porta ad allucinazioni sulle unità, mancanza di contesto o spiegazioni imprecise).

Gestione degli errori MCP

È fondamentale gestire gli errori in modo corretto.

  • Per gli errori recuperabili (ad esempio un ID utente non valido o un parametro facoltativo mancante), restituisci una stringa di testo normale contenente dettagli descrittivi dell'errore nella risposta dello strumento. In questo modo, il modello può esaminare il feedback, capire cosa è andato storto e correggersi autonomamente o chiedere chiarimenti all'utente.
  • Per gli errori terminali (come limitazione di frequenza, errori di autenticazione o autorizzazione o interruzioni del server di backend), genera un McpError con il codice di errore appropriato in modo che la piattaforma possa gestire l'errore in modo sistematico.

Esempio di corpo della risposta di errore (JSON)

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32302,
    "message": "User permission denied for the requested operation.",
    "data": null
  },
  "id": 1
}

Message contiene un dump JSON del campo ErrorData dell'MCP. Restituendo il code corretto e il message visibile al modello, la Connected Apps Platform può leggere il messaggio di errore e trasmettere all'utente una spiegazione utile in linguaggio naturale. Ad esempio, "Mi dispiace, non sono riuscito a trovare il luogo con questo ID. Puoi controllare il nome?"

MCP consente ai client di connettersi ai server MCP utilizzando la specifica JSON-RPC 2.0. JSON-RPC prevede l'invio di alcuni errori predefiniti per errori comuni come richieste non valide, errori di analisi e così via. Questa guida spiega come i server MCP possono inviare errori personalizzati.

Codice
di stato
Messaggio Utilizzo Devi
restituire
esplicitamente?
Errori utente/cliente
-32300 USER_RATE_LIMITED L'utente ha raggiunto il limite massimo di utilizzo. SÌ
-32301 MISSING_REQUIRED_INFORMATION La richiesta di input non contiene tutte le informazioni necessarie SÌ
-32302 USER_PERMISSION_DENIED L'utente ha negato l'autorizzazione a utilizzare lo strumento. Ad esempio, l'utente deve avere un account aziendale, un limite di età, un'impostazione internazionale e così via o non deve avere un abbonamento aziendale allo strumento. SÌ
Errori relativi all'applicazione/Errori di logica di business
-32400 RUNTIME_ERROR L'esecuzione del codice del server ha generato un errore SÌ
-32401 NULL_POINTER_EXCEPTION Tentativo di eseguire un puntatore/oggetto null SÌ
-32402 OUT_OF_MEMORY Memoria insufficiente nel codice del server da allocare a un oggetto SÌ
Errori dell'infrastruttura
-32500 DEADLINE_EXCEEDED La richiesta sta richiedendo più tempo del previsto. Può verificarsi per molti motivi, ad esempio server sovraccarico, problemi di rete e così via. SÌ
-32501 RESOURCE_EXHAUSTED Il server ha esaurito la memoria, lo spazio su disco, i thread, il tempo di CPU e così via. SÌ
-32502 SERVICE_UNAVAILABLE Il servizio dipendente (ad es. un altro microservizio, database, cache e così via) non è disponibile SÌ
Errori JSON-RPC (questi errori fanno parte del trasporto MCP)
-32700 PARSE_ERROR Il server non è riuscito ad analizzare la richiesta NO
-32600 INVALID_REQUEST Richiesta del client con formato non valido NO
-32601 METHOD_NOT_FOUND Nome dello strumento MCP non valido NO
-32602 INVALID_PARAMS Parametri di richiesta non validi, inclusi parametri mancanti o tipi di parametri non corrispondenti NO
-32603 INTERNAL_ERROR Risposta predefinita NO

Di seguito è riportato un esempio di come generare un errore MCP nel server utilizzando l'SDK Python ufficiale (mcp). Genera un McpError contenente un payload ErrorData, che l'SDK serializza automaticamente nel formato di errore JSON-RPC richiesto con lo stato dell'errore compilato.

from mcp import types
from mcp.shared.exceptions import McpError

@mcp.tool()
def foo_tool() -> list[types.TextContent]:
  """Always returns an error."""
  raise McpError(
    types.ErrorData(
        code=-32302, # USER_PERMISSION_DENIED
        message="Message to show to the model."
    ),
  )

Contesto dello strumento

I prodotti Google applicabili supportano un'API Tool Context per passare indicatori ai server MCP. Questa API viene utilizzata in casi d'uso validi che richiedono informazioni sensibili, ad esempio metadati che non fanno parte della definizione dello strumento di base, come nel caso di impostazioni internazionali per strumenti che richiedono la localizzazione. L'API Tool Context è esposta solo tramite Connected Console.

Quando registri un indicatore come current_user_location_fine con la tua app nella Connected Console, i prodotti Google applicabili migliorano le richieste MCP tools/call con una voce _meta aggiuntiva che fornisce i dati richiesti. L'insieme di indicatori supportati è:

  • current_user_location_fine (solo Gemini, per i verticali consentiti)
  • user_locale
  • current_user_location_coarse
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "find-restaurant",
    "arguments": {"query": "restaurants near me"},
    "_meta": {
      "current_user_location_fine": {
        "latitude_degrees": 37.7749,
        "longitude_degrees": -122.4194,
        "accuracy_meters": 112.4221
      },
      "user_locale": {
        "language_code": "en",
        "region_code": "US"
      }
    }
  }
}

Per analizzare questi dati:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("remote_mcp")

@mcp.tool()
async def find_restaurants(query: str, ctx: Context) -> str:
   # Access context directly from _meta
   request_context = ctx.request_context
   meta_dict = ctx.request_context.meta.model_dump() if ctx.request_context.meta else {}

   location_context = meta_dict.get("current_user_location_fine", {})
   lat = location_context.get("latitude_degrees")
   lng = location_context.get("longitude_degrees")
   if lat and lng:
       return f"Finding '{query}' near ({lat}, {lng})"
   return f"Finding '{query}' (no location provided)"

Rendering della UX

App MCP

I prodotti Google applicabili supportano le integrazioni delle app MCP per user journey selezionati per consentire la creazione di interfacce utente personalizzate. Segui la specifica per le istruzioni generali di integrazione.

L'integrazione delle app MCP sui prodotti Google applicabili presenta i seguenti avvertimenti.

Importazione delle risorse al momento della registrazione

I prodotti Google applicabili recuperano le risorse dell'interfaccia utente durante l'importazione dello strumento, analogamente all'elenco e alle descrizioni degli strumenti. Ciò significa che eventuali aggiornamenti delle risorse, ad esempio modifiche in JavaScript, non verranno rilevati automaticamente e richiederanno la nuova importazione dello strumento.

Una singola risorsa UI non deve superare i 15 MB e le risorse UI cumulative sul tuo server non devono superare i 100 MB.

Le risorse UI devono utilizzare uno dei tipi MIME supportati: text/html, text/javascript, text/css o text/html;profile=mcp-app. I tipi MIME non standard o specifici della piattaforma non supereranno la convalida durante il push all'anteprima.

Linee guida per i CSP

I prodotti Google applicabili seguono la specifica ufficiale delle app MCP, che include CSP [1], [2], e bloccano tutte le richieste che violano le direttive CSP.

I prodotti Google applicabili richiedono inoltre l'aggiunta di blob: e data: alla CSP, se utilizzata. Questi non verranno aggiunti per impostazione predefinita. Spetta agli sviluppatori scegliere se aggiungerli o meno alla CSP.

Script-src è un'eccezione

Le uniche istruzioni consentite sono: unsafe-inline (aggiunta per impostazione predefinita), wasm-unsafe-eval e data: (se inclusa in resource_domains). Se l'iframe carica script esterni, il problema può essere risolto raggruppando JS in HTML o utilizzando l'hash SRI (Subresource Integrity).

  • Opzione 1: JS in linea/pacchetto in HTML (più semplice)

    • Codice JS del bundle:

      • Inserisci i contenuti di component-init.js direttamente all'interno dei tag <script> nel payload HTML restituito per la risorsa UI:

        <script>
        // Paste component-init.js content directly here
        </script>
        
    • Rimuovi i tag <script src> remoti

      • Elimina i riferimenti a <script src="https://api.mycompany.com/..."> dal documento HTML.
    • Strumento di reimportazione/aggiornamento

  • Opzione 2: utilizza l'hash SRI (Subresource Integrity):

    Utilizza questa opzione se lo script deve rimanere ospitato esternamente all'indirizzo https://api.company.com/....

    • Calcola l'hash SHA-256 dello script
      • Genera l'hash SHA-256 base64 di component-init.js
    • Aggiungi l'hash a resourceDomains (deve includere il prefisso sha256- per corrispondere all'attributo integrity)
    • Aggiorna il tag HTML <script>
      • Aggiungi gli attributi integrity e crossorigin al tag di script nel widget HTML
    • Verifica l'intestazione CORS su CDN/server
      • Assicurati che api.company.com fornisca component-init.js con Access-Control-Allow-Origin: * (o consenta scf.usercontent.goog) in modo che il browser possa leggere il corpo della risposta per la verifica SRI.
    • Strumento di reimportazione/aggiornamento

Linee guida sulla sicurezza per la descrizione dello strumento MCP

Poiché la descrizione è l'unico contesto che il modello ha per comprendere le funzionalità dello strumento, deve essere scritta in modo accurato e sicuro per evitare comportamenti indesiderati. Rispetta le seguenti linee guida quando redigi le descrizioni degli strumenti.

  • Descrivi la funzionalità, ma non imporre il comportamento. La descrizione deve descrivere con precisione ciò che fa lo strumento, non ordinare al modello di eseguire azioni successive.
  • Definisci l'ambito e i requisiti. Indica chiaramente l'obiettivo principale dello strumento, le circostanze specifiche (When) per il suo utilizzo e tutti gli input richiesti (parametri/argomenti).
  • Garantisci la veridicità. La descrizione deve essere una rappresentazione veritiera del codice sottostante dello strumento. Non dichiarare che uno strumento è di sola lettura se esegue un'operazione di scrittura o eliminazione.

Rischi per la sicurezza e come evitarli

Area di rischio Consigliati Evita questa pratica a tutti i costi

Prompt injection

Utilizza un linguaggio oggettivo e dichiarativo per indicare chiaramente lo scopo e la funzionalità dello strumento.

Utilizza comandi imperativi per ignorare il comportamento del modello o alterare i flussi del sistema (ad esempio, "DEVI dire…", "Dopo la corsa, DEVI…"). I termini imperativi come DEVE o CRITICO sono accettabili solo quando si definiscono vincoli di parametri strutturati o regole di utilizzo.

Utilizza una formattazione standard e semplice per il testo della descrizione dello strumento.

Utilizzare una formattazione che attiri l'attenzione, ad esempio un uso eccessivo di lettere maiuscole e tag come VERY IMPORTANT: o **CRITICAL**.

Concentrati esclusivamente sulla funzione dello strumento e sul comportamento previsto.

Includere istruzioni per il gioco di ruolo o comandi per ignorare le istruzioni precedenti.

Tool shadowing e hijacking

Assicurati che la descrizione sia specifica e limitata alle funzionalità effettive e correlate dello strumento.

Rendere la descrizione dello strumento eccessivamente generica o vaga oppure affermare che un singolo strumento esegue molte funzioni non correlate.

Scegli un nome dello strumento univoco, descrittivo e sensato.

Utilizzare un nome di strumento che sia una variante minore di uno strumento attendibile o un nome generico (ad esempio do_everything_tool, assistant_tool).

Non menzionare per nome altre app o strumenti di piattaforme esterne nella descrizione.

Fare riferimento esplicitamente ad altri strumenti o creare nuove regole su quando o come utilizzare altri strumenti.

Consenti allo strumento di pianificazione del modello di selezionare lo strumento più appropriato in base al contesto dell'utente.

Includere un linguaggio anticoncorrenziale o qualsiasi tipo di prompt SEO che indichi al modello di preferire il tuo strumento rispetto a strumenti simili.

Manipolazione dei trigger

La descrizione non fa riferimento né reagisce a frasi generali della cronologia delle conversazioni.

Crea una logica condizionale che attiva un'azione dannosa in base a frasi comuni e innocue degli utenti (ad esempio, "grazie", "per riassumere").

Abuso dei parametri

Definisci solo i parametri necessari per la funzione dello strumento e utilizza nomi specifici per i dati di input (ad esempio file_id, search_term).

Definisci i parametri della funzione con nomi che rispecchiano lo stato interno dell'agente (ad esempio, system_prompt, conversation_history, full_context).

Esfiltrazione di dati

Privacy by design: identificatori opachi e autenticazione gestita dall'host.

Utilizza ID non sensibili, non PII non elaborate. Tutta la gestione dei dati deve avvenire entro limiti autorizzati e sicuri e non deve essere indicata nella descrizione pubblica come inviata esternamente. L'esecuzione dello strumento erediterà le autorizzazioni in modo silenzioso tramite l'handshake OAUth.

Tutte le informazioni sensibili devono essere sottoposte a sanitizzazione prima di essere inviate ai prodotti Google applicabili.

Richiedere PII, PHI o qualsiasi altra informazione personale e/o sensibile all'utente, dati personali o aziendali o entità in qualsiasi modo che violi i Termini di servizio dei prodotti Google applicabili.

Menzionare o richiedere l'invio di dati utente (query, posizione, contesto) a URL di terze parti, servizi di logging o sistemi esterni non autorizzati.

Best practice funzionali e di denominazione

Oltre a proteggere la descrizione dello strumento, devi assicurarti che il modello possa selezionarlo ed eseguirlo in modo affidabile senza confusione. Segui queste best practice funzionali e di denominazione:

  • Accuratezza dei parametri. Assicurati che tutti i nomi e i tipi di parametri nella descrizione corrispondano esattamente all'implementazione effettiva dello strumento.
  • Nomi sensati. Il nome dello strumento deve essere un'indicazione chiara e forte della sua funzione. Evita nomi troppo generici come "execute". Il nome deve anche essere coerente con l'ecosistema di strumenti più ampio.

Appendice: inserimento nella lista consentita di infrastrutture e reti

Se la tua infrastruttura di hosting, il tuo API Gateway o il tuo firewall limitano le connessioni in entrata in base all'indirizzo IP di origine, inserisci nella lista consentita i seguenti blocchi CIDR in uscita di Google:

  • 108.177.64.0/20
  • 142.250.88.0/22
  • 172.217.80.0/20
  • 192.178.20.0/22
  • 192.179.0.0/20
  • 74.125.232.0/24
  • 136.121.40.0/21

Assicurati che il tuo ambiente consenta il traffico da questi intervalli IP sulla porta HTTPS 443, in modo che i prodotti Google applicabili possano raggiungere il tuo server MCP remoto per l'inizializzazione di MCP, il rilevamento degli strumenti e l'esecuzione delle richieste.