Erros
As falhas chegam por dois canais diferentes, e a distinção importa: um é requisição quebrada, o outro é algo que o modelo deve ler e reagir.
Erros de tool
Tudo sobre o que o chamador pode agir — validação, não encontrado, escopo ou permissão insuficiente, um erro do endpoint — volta como uma resposta JSON-RPC bem-sucedida cujo resultado está marcado isError, carregando o envelope de erro da própria API como texto:
{ "jsonrpc": "2.0", "id": 2, "result": {
"isError": true,
"content": [{ "type": "text",
"text": "{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"Payable not found.\" } }" }]
} }
O vocabulário de code é o da API, sem mudança. Os que você mais vai encontrar:
code | Quando |
|---|---|
VALIDATION_ERROR | O corpo falhou na validação do endpoint; details.issues[] nomeia cada campo. Também quando os argumentos da tool (id, filtros) não batem com o schema dela — inclusive limit, cursor, sort_by ou fields dentro de filters, que são argumentos nomeados. |
BAD_REQUEST | Filtro, operador ou campo de fields desconhecido. |
NOT_FOUND | Não existe esse registro, ou ele é de outro workspace. |
CONFLICT | Duplicidade, ou um registro ainda em uso. |
UNPROCESSABLE_ENTITY | Regra de negócio — apagar uma categoria que tem filhas, baixar um título sem conta. |
SECURITY_BLOCKED | A aba Segurança barrou a ação neste canal. |
RATE_LIMITED | O orçamento da API para esta pessoa na organização acabou — veja Limite de requisições. |
E os quatro que o próprio MCP acrescenta, porque são sobre autorização, não sobre o recurso:
code | Quem resolve |
|---|---|
insufficient_scope | O escopo do token não alcança a tool: o recurso não está no token, falta acesso de escrita a ele, ou a tool move dinheiro e o token não traz o recurso de dinheiro (ou all). Use um token que alcance o recurso com o acesso pedido — pelo fluxo OAuth o acesso é só de leitura hoje; um token pessoal pode trazer escrita. |
insufficient_permission | Um admin da organização, concedendo a permissão que o erro nomeia. |
workspace_access_denied | O workspace_id não é um que a pessoa alcança (ou não existe). Um admin concede o workspace à pessoa, ou o agente passa outro, de finance_workspaces_list. |
membership_inactive | Incluir a pessoa do token na organização ou reativá-la — nenhuma permissão conserta um vínculo que não existe ou está inativo. |
São separados de propósito: quatro conversas diferentes, com pessoas diferentes. Um erro único diria "você não pode" sem dizer a quem pedir. Veja Autenticação.
Há também workspace_required: a chamada não trouxe workspace_id e a conexão não tem workspace padrão — a pessoa alcança vários. O agente chama finance_workspaces_list e repete a chamada com um dos id. Veja Autenticação → O workspace.
E os da confirmação de tools destrutivas — em todos eles, nada foi alterado:
code | Quando |
|---|---|
confirmation_required | Tool destrutiva chamada por um cliente que não pode confirmar: era 2025, ou 2026-07-28 sem elicitation de formulário. |
USER_DECLINED | Na era 2026-07-28, a pessoa recusou ou cancelou a confirmação. |
confirmation_replayed | A confirmação reenviada já rodou a tool uma vez. Chame de novo sem requestState para perguntar outra vez. |
confirmation_unavailable | O servidor não conseguiu garantir a confirmação naquele momento. Tente mais tarde. |
input_required não é erro
Na era 2026-07-28, o primeiro tools/call de uma tool destrutiva pode voltar resultType: "input_required" com um pedido de confirmação à pessoa. É o fluxo normal, não uma falha: o cliente mostra a pergunta e reenvia a mesma chamada com a resposta. Veja Confirmação de tools destrutivas.
Erros de protocolo
Uma mensagem malformada recebe um objeto de erro JSON-RPC, não um resultado:
| Código | Significado |
|---|---|
-32700 | Parse error — o corpo não é JSON válido |
-32600 | Invalid request — não é um objeto JSON-RPC, ou é um array (batching não é suportado) |
-32601 | Method not found |
-32602 | Invalid params — tool, prompt ou argumento inexistente, name ausente; na era 2026-07-28, também resource não encontrado |
-32002 | Resource não encontrado — só na era 2025 (a 2026-07-28 usa -32602) |
-32603 | Internal error — falha inesperada ao rodar a tool |
-32020 | Header mismatch — na 2026-07-28, um cabeçalho MCP-Protocol-Version, Mcp-Method ou Mcp-Name que não bate com o corpo (HTTP 400) |
-32022 | Unsupported protocol version — a versão pedida não é suportada; data.supported lista as que são (HTTP 400) |
Erros de transporte
Recusas que acontecem antes da mensagem JSON-RPC ser lida são respostas HTTP comuns: token ausente, inválido ou emitido para outro recurso, workspace padrão (X-Workspace-Id / ?workspace_id=) de outra organização, Origin fora da allowlist, limite de requisições do protocolo, Conta Kobana indisponível para validar o token (503), corpo acima de 14 MB (413, com o erro JSON-RPC -32600 Request body too large (limit 14680064 bytes) e id: null). Estão listadas em Autenticação → Modos de falha.
Por que isError e não erro JSON-RPC
Um 404 num título não é um defeito do cliente MCP — é informação sobre o mundo, e o modelo do outro lado precisa dela para se corrigir. Enterrá-la num erro de protocolo faria o cliente tratá-la como falha de transporte, esconder o texto e, no melhor caso, tentar de novo idêntico. Por isso a regra: se o chamador pode agir, é resultado; se a requisição está quebrada, é erro.
Observabilidade
Cada tools/call escreve uma linha estruturada com a tool, o workspace, a pessoa, o tipo do token (oauth ou personal), o status e a duração. As escritas ficam gravadas com o canal mcp e com a pessoa do token, então o que um agente fez aparece ao lado do que uma pessoa fez, nas mesmas telas.