Padrões de integração de apps conectados ao MCP

O servidor MCP estabelece o framework para conectar as funções do seu app (ferramentas MCP) à Connected Apps Platform. Para que ele possa selecionar, chamar e processar os resultados do seu serviço de forma mais confiável, sua configuração do MCP precisa seguir estritamente os padrões abaixo.

Princípios orientadores

Para cada função, concentre-se na intenção do usuário e nos casos de uso, não nos recursos da função. A descrição é a principal maneira de informar ao modelo para que serve sua ferramenta e a quais casos de uso ela pode responder.

Controle de versões

Para oferecer suporte a implantações de MCP escalonáveis e robustas, adote uma arquitetura de URI estruturada que use controle de versões baseado em caminho, por exemplo, /v1, /v2. Isso ajuda a manter a compatibilidade com versões anteriores e a controlar novos recursos. Complementar isso com subdomínios específicos do provedor, como https://gemini.mcp.company.com/mcp/v1, permite o gerenciamento granular de tráfego e a otimização de definições de ferramentas adaptadas ao contexto e aos comportamentos de processamento exclusivos de diferentes modelos de IA.

Compatibilidade de versões do protocolo MCP

A Connected Apps Platform é compatível com a especificação do Protocolo de Contexto de Modelo (MCP) até a versão 2025-11-25. As versões mais recentes da especificação ainda não são compatíveis.

  • Responsabilidade do desenvolvedor: você é responsável por garantir que seu servidor MCP siga estritamente uma versão de protocolo compatível com a plataforma de apps conectados (2025-11-25) durante o handshake initialize e em todas as definições de ferramentas e esquemas.
  • Compatibilidade com versões anteriores da plataforma: à medida que a Connected Apps Platform adotar versões mais recentes da especificação do MCP no futuro, nosso cliente vai manter a compatibilidade com versões anteriores do protocolo para que as integrações de produção atuais continuem funcionando sem interrupções.
  • Gerenciamento de upgrades: quando você estiver pronto para adotar uma especificação do MCP recém-compatível ou introduzir mudanças no esquema, exponha essas atualizações em um novo caminho de URI com controle de versão (por exemplo, /mcp/v2) e mantenha o endpoint existente (/mcp/v1) para o tráfego ativo.

As mudanças nos esquemas do MCP são permitidas entre as versões do app. Recomendamos que você use esse recurso e controle as versões dos endpoints do MCP para oferecer suporte a um lançamento suave de novos recursos ou dependa estritamente de mudanças compatíveis com versões anteriores.

Especificação do protocolo de transporte

A Connected Apps Platform é compatível apenas com a especificação do Protocolo de Contexto de Modelo de transporte HTTP de streaming versão 2025-03-26 e mais recentes. Ele não é compatível com o HTTP legado com transporte SSE descrito pela especificação de 05/11/2024.

  • Endpoint HTTP único. O endpoint do MCP fornecido no Connected Console (por exemplo, https://api.example.com/mcp) é o URL único para onde os produtos do Google aplicáveis enviam todas as solicitações JSON-RPC (initialize, tools/list, tools/call) por meio do HTTP POST padrão.
  • Streaming de SSE em HTTP com suporte a streaming. O transporte SSE legado de vários endpoints não é compatível, mas eventos enviados pelo servidor, como text/event-stream, são compatíveis com HTTP transmissível. As solicitações de saída dos produtos do Google aplicáveis incluem Accept: application/json, text/event-stream, o que significa que seu servidor pode retornar um payload application/json padrão ou transmitir respostas incrementais usando Content-Type: text/event-stream diretamente no corpo da resposta HTTP POST.
  • GET stream e 405 Method Not Allowed. Os clientes podem tentar um stream GET opcional no endpoint para notificações de servidor para cliente. Se o servidor for sem estado ou apenas de solicitação-resposta, o retorno de HTTP 405 Method Not Allowed será explicitamente compatível e tratado de forma limpa pelo proxy do cliente do produto aplicável do Google.

Instruções do servidor

A Plataforma de Apps Conectados é otimizada para receber instruções do servidor, o que permite um grau de controle sobre o comportamento do modelo que não está disponível por outros meios.

Siga as instruções do servidor.

Tratar como uma "dica de modelo" com contexto de uso

Siga estas diretrizes ao fornecer dicas para os modelos.

  • Escreva instruções como uma "dica" ou um guia de alto nível para ajudar o LLM a entender o propósito geral e os recursos do servidor.
  • Descreva o que ele pode fazer, em vez de listar recursos ou descrever como o modelo deve usar as ferramentas e os recursos do servidor. Se o modelo entender o "o que" corretamente, ele poderá determinar o "como" com base na jornada do usuário.
  • Suponha que esse texto será adicionado diretamente ao comando do sistema do modelo. Mantenha o comando claro, diretivo e eficiente em termos de tokens.

Complemente, não duplique

Use esse espaço para o contexto global que se aplica a todas as ferramentas, evitando redundância com descrições de ferramentas individuais.

Exemplos de instruções do servidor

Os exemplos a seguir mostram o que fazer e o que não fazer ao escrever instruções de servidor.

Recomendável Não recomendado

Atue como um mantenedor especializado de repositórios do GitHub. Esse servidor oferece acesso detalhado a metadados de repositórios, Issue Tracker e fluxos de trabalho de PR. Use-o para manter a integridade do projeto, automatizar a triagem e garantir os padrões de código. Suponha que todas as ações sejam realizadas no contexto da organização autenticada, a menos que especificado de outra forma. Priorize a identificação de conversas desatualizadas ou PRs não vinculados para manter o repositório organizado.

Conciso, diretivo e complementar ao modelo

  • Define o "o que" (integridade do projeto, triagem) em vez do "como"
  • Menciona o escopo de autenticação que se aplica a todas as ferramentas

Este servidor tem ferramentas para o GitHub. Use a ferramenta list_issues quando o usuário perguntar sobre problemas. Use create_pull_request para fazer uma solicitação de envio. Use essas ferramentas com cuidado para ajudar o usuário a gerenciar o código. Sempre verifique o nome do repositório antes de chamar uma ferramenta. Se o usuário pedir um resumo, chame as ferramentas primeiro e depois resuma o resultado.

  • não liste novamente os nomes das ferramentas,
  • não diga ao modelo "como" pensar, o que pode entrar em conflito com o raciocínio integrado do modelo, que usa o contexto do usuário para fazer a escolha certa.
  • não explica a natureza do acesso do servidor ou as restrições específicas dele)

Diretrizes para ferramentas

As diretrizes a seguir descrevem as práticas recomendadas para criar configurações de servidor MCP para várias funções ou ferramentas no seu app.

Convenções de nomenclatura de ferramentas

Siga estas diretrizes para nomear sua ferramenta:

Use nomes intuitivos e legíveis por humanos

Use nomes legíveis por humanos com significados claros e intuitivos em vez de ambíguos. Por exemplo, get_user_information é mais simples do que userInfo.

Observe o estilo de uso de maiúsculas e minúsculas adequado

Siga as seguintes regras de uso de maiúsculas e minúsculas para nomes de funções de ferramentas e acionadores de apps:

  • Uso de maiúsculas e minúsculas na função da ferramenta. Use snake_case ou camelCase para nomes de funções de ferramentas definidos no esquema do MCP (por exemplo, get_user_information ou publishDraft).
  • Uso de maiúsculas e minúsculas no identificador de acionador do app. Os acionadores e as menções de apps (por exemplo, @MyTwoWordApp) não diferenciam maiúsculas de minúsculas. A plataforma normaliza as entradas do usuário em letras minúsculas (@mytwowordapp), PascalCase (@MyTwoWordApp) e camelCase (@myTwoWordApp).
  • Formatação do nome de exibição. Registre o título oficial do app usando PascalCase ou espaços padrão para uma exibição visual clara nos elementos da interface.
  • Tratamento de erros de digitação. Embora as variações de maiúsculas e minúsculas sejam tratadas automaticamente, erros de digitação de caracteres (por exemplo, @mytwowrodapp) dependem do reconhecimento de intent de fallback, em vez da correspondência direta de strings. Os desenvolvedores precisam incentivar a ortografia correta do identificador na documentação.

Usar nomenclatura explícita de verbo-substantivo

Use nomes específicos de verb_noun e evite ambiguidades. Por exemplo, publish_draft é melhor que handle_content.

Granularidade da ferramenta

Siga as diretrizes abaixo sobre a granularidade das ferramentas.

Tratar ferramentas como endpoints atômicos

Trate as ferramentas como endpoints atômicos sem condições internas ou várias funcionalidades com os respectivos parâmetros obrigatórios. As ferramentas granulares permitem que o modelo encadeie as etapas de forma lógica, reduzindo as alucinações.

Usar esquemas mais simples

Se você precisar de objetos profundamente aninhados ou de uma lógica de esquema oneOf / anyOf complexa para validar entradas, é provável que sua ferramenta seja muito ampla.

Observar as proteções de pré-agregação e payload

Embita a pré-agregação de dados não seja estritamente aplicada pelo protocolo para payloads pequenos e com escopo, a pré-agregação de back-end é altamente necessária na prática ao trabalhar com grandes conjuntos de registros, histórico longitudinal e conjuntos de dados de várias fontes. A Connected Apps Platform aplica proteções em relação aos limites da janela de contexto, à latência de execução e às etapas de raciocínio do modelo. Para seguir essas proteções, siga estas diretrizes:

  • Filtrar e resumir no back-end. Sempre filtre, pré-agregue ou resuma grandes fluxos de dados no servidor MCP antes de retornar respostas aos produtos do Google aplicáveis.
  • Evite despejos brutos. Nunca despeje linhas de banco de dados brutas ou registros não indexados completos no payload de retorno da ferramenta.

Omitir ferramentas internas e de metadados

Exponha apenas os recursos voltados para o modelo na resposta tools/list do servidor:

  • Filtrar ferramentas auxiliares: omita ferramentas internas, administrativas ou de metadados que não devem ser chamadas pelo modelo (por exemplo, verificações de integridade do servidor, rotinas de configuração interna ou auxiliares de utilitários para desenvolvedores).
  • Eficiência da janela de contexto: excluir ferramentas desnecessárias mantém o esquema do MCP conciso, reduz o consumo de tokens da janela de contexto e evita confusões de roteamento de ferramentas do modelo. Os servidores MCP que expõem dezenas de ferramentas ou esquemas de "megas ferramentas" profundamente aninhados serão sinalizados durante a revisão para correções.

O que fazer e o que não fazer na granularidade da ferramenta

Os exemplos a seguir mostram o que fazer e o que não fazer em relação à nomenclatura de ferramentas e ao uso de granularidade.

Recomendável Não recomendado

Ferramentas granulares com nomes e parâmetros claros

O esquema de entrada de cada ferramenta é rigoroso. Se o LLM quiser criar um usuário, ele precisará fornecer um e-mail. Se quiser excluir, será necessário fornecer um ID. Não há adivinhação.

...
@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 da ferramenta: manage_user

Descrição: "Use esta ferramenta para criar, atualizar, excluir ou recuperar usuários."

...
@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"
    """
    ...

Declarar anotações de ferramentas para segurança

Configure anotações de protocolo nas definições da ferramenta para transmitir o comportamento de execução e acionar portas de segurança integradas nos produtos do Google aplicáveis:

  • Portas de confirmação de tempo de execução: os produtos do Google aplicáveis usam annotations.destructiveHint: true e annotations.openWorldHint: true como sinalizações principais para acionar solicitações de confirmação do usuário no tempo de execução. Declare destructiveHint: true em ações de mudança de estado, gravação ou destrutivas e defina openWorldHint: true para ferramentas que interagem com ambientes de mundo aberto ou externos para que a plataforma solicite nativamente a confirmação do usuário antes da execução.
  • Dica de consulta somente leitura: defina readOnlyHint: true em ferramentas de consulta que apenas buscam dados sem modificar o estado do back-end.
  • Padrões de anotação explícitos: de acordo com a especificação do Protocolo de Contexto de Modelo, omitir readOnlyHint faz com que os clientes assumam readOnlyHint: false e destructiveHint: true por padrão para segurança. Declarar explicitamente as anotações em todas as ferramentas garante um roteamento de modelos previsível e a segurança adequada da execução.

Descrições de ferramentas

A descrição é o único contexto que o modelo tem para decidir se a ferramenta pode resolver o problema atual. Siga estas diretrizes para escrever descrições:

Escreva instruções, não comentários

Escreva as descrições das ferramentas como instruções, e não como comentários de código, que geralmente são passivos. Os LLMs respondem bem a diretivas.

Explique o "como"

Uma boa descrição preenche a lacuna entre "Tenho uma ferramenta" e "Sei como conectar essa ferramenta a uma conversa".

Explique o motivo

Diferencie essa ferramenta de outras semelhantes. Por exemplo, "Use esta para usuários internos, use customer_update para externos".

Diga ao modelo onde encontrar os argumentos, por exemplo, "da ferramenta order_search".

Especifique o formato

Especifique unidades (metros x pés) e formatos (datas ISO, versões semânticas).

Evitar a discrição do modelo

Não instrua o modelo a usar o "melhor julgamento" nem sugira ações opcionais não guiadas.

Exemplos de descrições de ferramentas

Os exemplos a seguir mostram o que fazer e o que não fazer ao escrever descrições de ferramentas.

Recomendável Não recomendado

Fonte de informações

"Atualiza o e-mail de um usuário. É obrigatório usar o UUID "id" retornado pela ferramenta search_users. Não deduza nem adivinhe os IDs de usuário."

(Ele vincula explicitamente a saída de uma ferramenta à entrada desta.)

"Atualiza o endereço de e-mail do usuário."

(O modelo pode adivinhar um ID como 12345.)

Formato e restrição

"Agendar uma reunião. "date" precisa estar no formato ISO 8601 (AAAA-MM-DD). Se o usuário disser 'amanhã' ou outra referência relativa, calcule a data com base no contexto atual."

"Agendar uma reunião para a data informada."

(parece correto para um humano, por exemplo, "amanhã", mas falha na validação do esquema, que precisa de "2025-10-12")

Expectativas de saída

"Recupera os registros do servidor. Retorna as últimas 50 linhas de texto bruto. Para análise, solicite janelas de tempo menores para evitar limites de tokens."

"Receber registros do servidor".

O modelo pode chamar uma ferramenta esperando um resumo, receber um despejo JSON bruto de 5 MB e resultar em uma experiência ruim para o usuário.

@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...

    ...

Essa descrição funciona como um mini-manual. Ele processa a origem (onde conseguir o ID), as restrições (tipos enumerados válidos) e a ação.

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

Isso depende dos nomes das variáveis para fazer todo o trabalho. O modelo precisa adivinhar os valores válidos para "status".

Parâmetros da ferramenta

Além da ferramenta em si, descreva os parâmetros para que eles fiquem claros.

Tipos explícitos

Use tipos fortes e específicos (string, integer, boolean, array).

Usar tipos enumerados para conjuntos de valores fixos

Se um parâmetro aceitar apenas um conjunto fixo de valores (por exemplo, daylight, cool, warm), liste-os em uma matriz enum. Isso melhora drasticamente a precisão.

Defina claramente os parâmetros obrigatórios

Defina claramente quais parâmetros são obrigatórios para que a função funcione.

Aplicar correspondência de esquema semântico

Ao integrar seu app, pode ser necessário fazer uma correspondência de esquema semântico entre os parâmetros das suas ferramentas e o setor para o qual você está desenvolvendo. Você vai receber o esquema vertical esperado (um esquema JSON) durante o processo de integração.

Exemplos de parâmetros de ferramentas

Os exemplos a seguir mostram o que fazer e o que não fazer ao lidar com parâmetros de ferramentas.

Recomendável Não recomendado

Formatos e unidades de argumentos

radius: o raio em metros. Precisa ser um valor flutuante maior que 0."

(evita alucinações de unidade)

radius: "O raio do círculo."

Formatos e contexto de ID

user_id: "O UUID do banco de dados (por exemplo, 550e8400-e29b...). Não use endereços de e-mail aqui."

Observação: como prática recomendada, todos os campos de ID numéricos precisam ser tratados como valores de string. Em particular, se o ID puder ter mais de 10 dígitos, ele corre o risco de ser truncado por sistemas internos (forçado a um contêiner de 32 bits) e essa versão ser usada pelo modelo em chamadas de ferramentas futuras.

(evita erros de tipo)

user_id: "O ID do usuário."

Expectativas de valor de retorno

"Atualiza o registro e retorna o objeto JSON atualizado, incluindo o novo carimbo de data/hora."

Informa ao modelo que ele não precisa chamar uma ferramenta "get" imediatamente após a "update" para verificar a mudança.

"Atualiza o registro."


@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."""
    ...

O LLM não sabe qual sintaxe a "consulta" aceita (SQL? Regex? Texto simples?) Ele não sabe qual é o "limite" máximo.

Respostas e tratamento de erros

De acordo com o princípio central de que a resposta é o próximo comando, a ferramenta informa o resultado da execução subjacente retornando um payload de dados, que é colado diretamente na janela de contexto do LLM. O sucesso ou a falha do resultado determina o que acontece em seguida:

  • Se for bem-sucedido: o modelo precisa do valor de retorno para saber o que aconteceu e decidir a próxima etapa.
  • Se falhar: o modelo precisa saber por que falhou e como corrigir o problema. Uma falha (erro 500) interrompe a conversa. Uma mensagem de erro descritiva permite que o modelo se corrija.

Se a lógica subjacente da ferramenta for bem-sucedida ou falhar, você precisará formatar o payload do valor de retorno para que o modelo possa analisá-lo facilmente. Siga estas práticas recomendadas ao empacotar o payload de resposta.

Usar JSON

Formate dados estruturados em TextContent (restrição temporária). Como structuredContent ainda não é compatível com a Connected Apps Platform, serialize os dados manualmente. Mesmo que retorne uma lista simples, json.dumps().

Incluir URLs na resposta

Os URLs retornados precisam ser relativamente curtos e não ter muitos parâmetros. Recomendamos usar serviços de encurtamento de URL para economizar na contagem de tokens e reduzir o risco de alucinações.

Payloads autodescritivos contra alucinações

Sempre combine códigos brutos ou IDs internos com nomes de exibição legíveis por humanos, unidades de medida explícitas e intervalos de referência. Nunca retorne chaves de dicionário compactadas ou códigos numéricos não mapeados que forcem o modelo a inferir o contexto.

Implementar um tratamento de erros robusto

Retorne mensagens de erro claras e significativas para que o modelo entenda o que deu errado e informe o usuário. Consulte o tratamento de erros do MCP.

Usar try/except

Envolva a lógica da ferramenta em blocos try/except e retorne erros em formato de string.

Fornecer erros acionáveis

Sugira a próxima etapa na mensagem de erro (por exemplo, "Tente usar a ferramenta X primeiro").

Confirmar ações

Não retorne strings vazias para ferramentas de efeito colateral (criar/atualizar/excluir).

Exemplos de respostas e tratamento de erros

Os exemplos a seguir mostram o que fazer e o que não fazer em relação a respostas e tratamento de erros.

Recomendável Não recomendado

Serialização explícita


...
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)

Capturar e informar


...
@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."

A ferramenta "funciona" tecnicamente (retorna uma string), mas a string contém os detalhes do erro. O modelo lê isso, percebe que o ID não existe e pode pedir ao usuário o ID correto.


...
@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 falhar, o servidor vai gerar um erro 500. O LLM recebe um erro de execução genérico e não sabe o motivo (o ID estava errado? O banco de dados está inativo? Permission denied?). É provável que ele tente novamente a mesma entrada incorreta.

Respostas vazias

...
@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.

Os LLMs costumam ficar confusos com respostas vazias. Eles podem alucinar "A ferramenta falhou" ou apenas repetir a chamada.

Payload autodescritivo contra alucinações

Sempre combine códigos brutos ou IDs internos com nomes de exibição legíveis por humanos, unidades de medida explícitas e intervalos de referência normais.

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

Isso informa ao modelo exatamente o que o valor significa, sem forçá-lo a inferir unidades ou limites de referência.

IDs brutos, compactação personalizada ou códigos não mapeados

Retornar IDs internos brutos, abreviações de dicionários personalizados ou códigos numéricos sem rótulos.

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

(Força o modelo a adivinhar a que 105 se refere, levando a unidades alucinadas, falta de contexto ou explicações imprecisas.)

Tratamento de erros do MCP

É fundamental lidar com erros de maneira adequada.

  • Para erros recuperáveis (como um ID do usuário inválido ou um parâmetro opcional ausente), retorne uma string de texto normal com detalhes descritivos do erro na resposta da ferramenta. Isso permite que o modelo inspecione o feedback, entenda o que deu errado e se corrija ou peça esclarecimentos ao usuário.
  • Para erros de terminal (como limitação de taxa, falhas de autenticação ou permissão ou interrupções do servidor de back-end), gere um McpError com o código de erro apropriado para que a plataforma possa lidar com a falha de forma sistemática.

Exemplo de corpo de resposta de erro (JSON)

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

Message contém um dump JSON do campo ErrorData do MCP. Ao retornar o code correto e o message visível para o modelo, a Connected Apps Platform pode ler a mensagem de erro e transmitir uma explicação útil em linguagem natural para o usuário. Por exemplo, "Não foi possível encontrar o local com esse ID. Você pode verificar o nome?"

O MCP permite que os clientes se conectem a servidores MCP usando a especificação JSON-RPC 2.0. O JSON-RPC tem certos erros predefinidos enviados para erros comuns, como solicitação inválida, erros de análise etc. Este guia aborda como os servidores MCP podem enviar erros personalizados.

Código
de status
Mensagem Uso Precisa de um
retorno
explícito?
Erros do usuário/cliente
-32300 USER_RATE_LIMITED O usuário atingiu o limite máximo de uso. SIM
-32301 MISSING_REQUIRED_INFORMATION A solicitação de entrada não tem todas as informações necessárias SIM
-32302 USER_PERMISSION_DENIED O usuário negou permissão para usar a ferramenta. Por exemplo, o usuário precisa ter uma conta corporativa, restrição de idade, localidade etc. ou não ter uma assinatura corporativa da ferramenta. SIM
Erros de aplicativo/erros de lógica de negócios
-32400 RUNTIME_ERROR A execução de código do servidor gerou um erro SIM
-32401 NULL_POINTER_EXCEPTION Tentativa de executar um ponteiro/objeto nulo SIM
-32402 OUT_OF_MEMORY Memória insuficiente no código do servidor para alocar a um objeto SIM
Erros de infraestrutura
-32500 DEADLINE_EXCEEDED A solicitação está demorando mais do que o tempo permitido. Pode acontecer por vários motivos, como servidor sobrecarregado, problemas de rede etc. SIM
-32501 RESOURCE_EXHAUSTED O servidor ficou sem memória, espaço em disco, threads, tempo de CPU etc. SIM
-32502 SERVICE_UNAVAILABLE O serviço dependente (por exemplo, outro microsserviço, banco de dados, cache etc.) está indisponível. SIM
Erros JSON-RPC (esses erros fazem parte do transporte MCP)
-32700 PARSE_ERROR O servidor não conseguiu analisar a solicitação NÃO
-32600 INVALID_REQUEST Solicitação do cliente inválida NÃO
-32601 METHOD_NOT_FOUND Nome de ferramenta do MCP inválido NÃO
-32602 INVALID_PARAMS Parâmetros de solicitação inválidos, incluindo parâmetros ausentes ou tipos de parâmetros incompatíveis NÃO
-32603 INTERNAL_ERROR Resposta padrão NÃO

Confira a seguir um exemplo de como gerar um erro do MCP no servidor usando o SDK oficial para Python (mcp). Gere um McpError que contenha um payload ErrorData, que o SDK serializa automaticamente no formato de erro JSON-RPC necessário com o status de erro preenchido.

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."
    ),
  )

Contexto da ferramenta

Os produtos do Google aplicáveis oferecem suporte a uma API Tool Context para transmitir indicadores para servidores MCP. Essa API é usada em casos de uso válidos que exigem informações sensíveis, por exemplo, metadados que não fazem parte da definição principal da ferramenta, como no caso de uma localidade para ferramentas que precisam de localização. A API Tool Context só é exposta pelo Connected Console.

Quando você registra um indicador como current_user_location_fine com seu app no Connected Console, os produtos do Google aplicáveis aumentam as solicitações de MCP tools/call com uma entrada _meta adicional que fornece os dados solicitados. O conjunto de indicadores compatíveis é:

  • current_user_location_fine (somente Gemini, para setores permitidos)
  • 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"
      }
    }
  }
}

Para analisar esses dados:

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)"

Renderização da UX

Apps do MCP

Os produtos do Google aplicáveis são compatíveis com integrações de apps do MCP para jornadas do usuário selecionadas, permitindo a criação de interfaces do usuário personalizadas. Siga a especificação para instruções gerais de integração.

A integração de apps do MCP nos produtos do Google aplicáveis tem as seguintes ressalvas.

Ingestão de recursos no momento do registro

Os produtos do Google aplicáveis buscam recursos de interface durante o tempo de ingestão da ferramenta, de forma semelhante à lista e às descrições de ferramentas. Isso significa que as atualizações de recursos, como mudanças no JavaScript, não serão detectadas automaticamente e vão exigir uma nova ingestão da ferramenta.

Um único recurso de interface não pode exceder 15 MB, e os recursos de interface cumulativos no servidor não podem exceder 100 MB.

Os recursos de interface precisam usar um dos tipos MIME compatíveis: text/html, text/javascript, text/css ou text/html;profile=mcp-app. Os tipos MIME não padrão ou específicos da plataforma não serão validados ao serem enviados para a visualização.

Diretrizes de CSP

Os produtos do Google aplicáveis seguem a especificação oficial de apps do MCP, que inclui CSP [1], [2], e bloqueiam todas as solicitações que violam as diretivas de CSP.

Os produtos do Google aplicáveis também exigem a adição de blob: e data: à CSP, se usada. Eles não serão adicionados por padrão. É escolha dos desenvolvedores adicioná-los (ou não) à CSP.

Script-src é uma exceção

As únicas diretivas permitidas são: unsafe-inline (adicionada por padrão), wasm-unsafe-eval e data: (se incluída em resource_domains). Se o iframe estiver carregando scripts externos, isso poderá ser resolvido agrupando o JS em HTML ou usando o hash de integridade de sub-recursos (SRI, na sigla em inglês).

  • Opção 1: JS inline / em pacote no HTML (mais simples)

    • Código JS do pacote:

      • Insira o conteúdo de component-init.js diretamente nas tags <script> no payload HTML retornado para o recurso de interface:

        <script>
        // Paste component-init.js content directly here
        </script>
        
    • Remover tags remotas de <script src>

      • Exclua as referências de <script src="https://api.mycompany.com/..."> do documento HTML.
    • Ferramenta de reingestão / atualização

  • Opção 2: usar o hash de integridade de sub-recursos (SRI, na sigla em inglês):

    Use essa opção se o script precisar permanecer hospedado externamente em https://api.company.com/....

    • Calcular o hash SHA-256 do script
      • Gere o hash SHA-256 em base64 de component-init.js
    • Adicione o hash a resourceDomains (precisa incluir o prefixo sha256- para corresponder ao atributo integrity)
    • Atualizar a tag HTML <script>
      • Adicione os atributos integrity e crossorigin à tag script no widget HTML.
    • Verificar o cabeçalho CORS na CDN/no servidor
      • Verifique se api.company.com exibe component-init.js com Access-Control-Allow-Origin: * (ou permite scf.usercontent.goog) para que o navegador possa ler o corpo da resposta para verificação de SRI.
    • Ferramenta de reingestão / atualização

Diretrizes de segurança para a descrição da ferramenta MCP

Como a descrição é o único contexto que o modelo tem para entender os recursos da ferramenta, ela precisa ser escrita de forma precisa e segura para evitar comportamentos indesejados. Siga as diretrizes abaixo ao elaborar as descrições das ferramentas.

  • Descreva a funcionalidade, mas não dite o comportamento. A descrição precisa descrever com precisão o que a ferramenta faz, não comandar o modelo para realizar ações subsequentes.
  • Defina o escopo e os requisitos. Indique claramente o objetivo principal da ferramenta, as circunstâncias específicas (Quando) para o uso dela e todas as Entradas (parâmetros/argumentos) necessárias.
  • Garanta a veracidade. A descrição precisa ser uma representação fiel do código subjacente da ferramenta. Não afirme que uma ferramenta é somente leitura se ela realizar uma operação de gravação ou exclusão.

Riscos de segurança e como evitá-los

Área de risco Recomendável Evite essa prática a todo custo

Injeção de comando

Use uma linguagem objetiva e declarativa para indicar claramente a finalidade e a funcionalidade da ferramenta.

Use comandos imperativos para modificar o comportamento do modelo ou alterar os fluxos do sistema (por exemplo, "você PRECISA dizer...", "Depois de correr, você PRECISA…"). Termos imperativos como "DEVE" ou "CRÍTICO" são aceitáveis apenas ao definir restrições de parâmetros estruturados ou regras de uso.

Use uma formatação padrão e simples para o texto de descrição da ferramenta.

Usar formatação para chamar a atenção, por exemplo, letras maiúsculas em excesso e tags como VERY IMPORTANT: ou **CRITICAL**.

Foque apenas na função e no comportamento esperado da ferramenta.

Inclua instruções de simulação ou comandos para ignorar instruções anteriores.

Ocultação e sequestro de ferramentas

A descrição precisa ser específica e limitada aos recursos reais e relacionados da ferramenta.

Criar uma descrição muito ampla ou vaga da ferramenta ou alegar que uma única ferramenta executa muitas funções não relacionadas.

Escolha um nome exclusivo, descritivo e sensato para a ferramenta.

Usar um nome de ferramenta que seja uma pequena variação de uma ferramenta confiável ou um nome genérico (por exemplo, do_everything_tool, assistant_tool).

Não mencione os nomes de outros apps ou ferramentas de plataformas externas na descrição.

Mencione explicitamente outras ferramentas ou crie novas regras para quando ou como elas devem ser usadas.

Permita que o planejador do modelo selecione a ferramenta mais adequada com base no contexto do usuário.

Incluir linguagem anticompetitiva ou qualquer tipo de comando de SEO que instrua o modelo a preferir sua ferramenta em vez de outras semelhantes.

Manipulação de gatilhos

A descrição não faz referência nem reage a frases gerais do histórico de conversas.

Criar uma lógica condicional que acione uma ação prejudicial com base em frases comuns e inofensivas do usuário (por exemplo, "obrigado", "para resumir").

Abuso de parâmetros

Defina apenas os parâmetros necessários para a função da ferramenta e use nomes específicos para os dados de entrada (por exemplo, file_id, search_term).

Defina parâmetros de função com nomes que espelham o estado interno do agente (por exemplo, system_prompt, conversation_history, full_context).

Exfiltração de dados

Privacidade desde a concepção: identificadores opacos e autenticação gerenciada pelo host.

Use IDs não sensíveis, não PIIs brutas. Todo o processamento de dados precisa estar dentro de limites autorizados e seguros, e não pode ser referenciado na descrição pública como sendo enviado externamente. A execução da ferramenta vai herdar as permissões de forma silenciosa pelo handshake do OAuth.

Todas as informações sensíveis precisam ser limpas antes de serem enviadas aos produtos do Google aplicáveis.

Solicitar PII, PHI ou qualquer outra informação pessoal e/ou sensível do usuário, dados pessoais ou comerciais ou entidade em qualquer capacidade que viole os Termos de Serviço dos produtos do Google aplicáveis.

Mencionar ou exigir o envio de dados do usuário (consulta, local, contexto) para URLs de terceiros não autorizados, serviços de registro ou sistemas externos.

Práticas recomendadas de funcionalidade e nomenclatura

Além de proteger a descrição da ferramenta, é preciso garantir que o modelo possa selecioná-la e executá-la de forma confiável, sem confusão. Siga as práticas recomendadas de nomenclatura e funcionais:

  • Precisão do parâmetro. Verifique se todos os nomes e tipos de parâmetros na descrição correspondem exatamente à implementação real da ferramenta.
  • Nomes sensatos. O nome da ferramenta precisa ser uma dica forte e clara sobre a função dela. Evite nomes muito genéricos, como "execute". O nome também precisa ser consistente com o ecossistema de ferramentas mais amplo.

Apêndice: lista de permissões de infraestrutura e rede

Se a infraestrutura de hospedagem, o gateway de API ou o firewall restringirem as conexões de entrada por endereço IP de origem, inclua na lista de permissões os seguintes blocos CIDR de saída do 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

Verifique se o ambiente permite o tráfego desses intervalos de IP na porta HTTPS 443 para que os produtos do Google aplicáveis possam acessar o servidor MCP remoto para inicialização do MCP, descoberta de ferramentas e execução de solicitações.