Transporte
Streamable HTTP, stateless. Uma mensagem JSON-RPC 2.0 por POST, uma resposta. Não há Mcp-Session-Id nem stream do servidor para o cliente: o servidor roda em várias réplicas, e cada POST é autocontido. Para reagir a eventos da conta, use os webhooks da API: o servidor não envia notificações espontâneas.
Versões do protocolo
O servidor fala as duas eras do protocolo no mesmo endpoint:
| Era | Versões | Como o cliente fala |
|---|---|---|
| Stateless | 2026-07-28 | Sem handshake. Toda requisição carrega a versão e as capacidades do cliente em params._meta, e server/discover descreve o servidor. |
| Com handshake | 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05 | initialize primeiro; depois, o cabeçalho MCP-Protocol-Version em cada requisição. |
Comportamentos que valem conhecer:
- Um
initializeque pede2026-07-28recebe2025-11-25: a era stateless se descobre porserver/discover, não porinitialize. initializena era2026-07-28é-32601(método não encontrado), com HTTP404.- Uma versão que o servidor não fala é
400com o erro JSON-RPC-32022, que lista as suportadas. - Na era
2026-07-28, cabeçalho que contradiz o corpo é400com-32020. - Na versão
2024-11-05, que não tem o campo, as instruções do servidor não são enviadas.
Era 2026-07-28
Não há handshake: toda requisição carrega a própria versão e as capacidades do cliente em params._meta, e o servidor não guarda nada entre uma requisição e outra.
Chave de params._meta | Obrigatória | Significado |
|---|---|---|
io.modelcontextprotocol/protocolVersion | sim | 2026-07-28 |
io.modelcontextprotocol/clientCapabilities | sim | Capacidades do cliente (um objeto; {} serve). Declare elicitation para receber a confirmação de tools destrutivas. |
io.modelcontextprotocol/clientInfo | recomendada | name e version do cliente |
Os cabeçalhos repetem o que está no corpo, e precisam concordar com ele:
| Cabeçalho | Tem que ser igual a |
|---|---|
MCP-Protocol-Version | A versão do envelope |
Mcp-Method | O method da mensagem |
Mcp-Name | O params.name em tools/call e prompts/get; o params.uri em resources/read |
As listagens dessa era (tools/list, resources/list, resources/templates/list, prompts/list) e o resources/read voltam com ttlMs: 0 e cacheScope: "private": o que volta depende de quem pergunta, então não deve ser reaproveitado nem compartilhado.
Cabeçalhos da requisição
| Cabeçalho | Obrigatório | Significado |
|---|---|---|
Authorization | sim | Bearer <token> emitido para o MCP: veja Autenticação |
Content-Type | sim | application/json |
Accept | sim | application/json, text/event-stream |
MCP-Protocol-Version | sim, depois do handshake e em toda requisição da era 2026-07-28 | Revisão do protocolo |
Mcp-Method, Mcp-Name | na era 2026-07-28 | O método, em toda requisição; o nome da tool ou do prompt, ou a URI do resource |
X-Account-Uid | não | uid de uma subconta, para operar nela em vez da conta do token |
Origin | condicional | Mandado por clientes de navegador; validado contra uma allowlist |
O corpo da requisição tem limite de 4 MiB; acima disso a resposta é 413.
Métodos
| Método | Era 2026-07-28 | Com handshake | Para quê |
|---|---|---|---|
server/discover | sim | — | Versões suportadas, capacidades e instruções do servidor |
initialize | — | sim | Negociação de versão, capacidades e instruções |
ping | — | sim | Teste de vida |
tools/list | sim | sim | As tools que este chamador pode rodar, com JSON Schema e anotações |
tools/call | sim | sim | Roda uma tool |
resources/list | sim | sim | Os registros mais recentes de cada tipo, como URIs |
resources/templates/list | sim | sim | Os templates de URI (kobana://banking/charge/bank_billets/{uid}, …) que este chamador pode ler |
resources/read | sim | sim | Lê um registro pela URI |
prompts/list | sim | sim | Os roteiros prontos que este chamador pode usar |
prompts/get | sim | sim | Monta um roteiro com os argumentos dados |
completion/complete | sim | sim | Sugestões para um argumento de prompt ou de template |
Resources, prompts e completions estão em Resources e prompts.
O servidor declara as capacidades tools, resources, prompts e completions, sem listChanged, subscribe nem logging: sendo stateless, não tem canal para entregar notificação. Batching JSON-RPC não é suportado: um corpo em array é recusado com -32600. Uma notificação (mensagem sem id) é aceita com 202 e corpo vazio.
A autenticação vem antes de qualquer método, inclusive do initialize e do server/discover: sem token, a resposta é o 401 que leva o cliente ao fluxo OAuth.
initialize
{ "jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": { "protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": { "name": "my-client", "version": "1.0.0" } } }
{ "jsonrpc": "2.0", "id": 1, "result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": {}, "resources": {}, "prompts": {}, "completions": {} },
"serverInfo": { "name": "kobana", "title": "Kobana", "version": "1.1.0" },
"instructions": "Kobana MCP server. Kobana is a Brazilian billing and payments platform. …"
} }
tools/list
Devolve apenas as tools que o chamador pode rodar, filtradas pelo escopo do token e pelas permissões de painel de quem o autorizou. O plano da conta não filtra: veja Autenticação. Cada tool traz um inputSchema fechado (additionalProperties: false): argumento não declarado é recusado antes de a tool rodar. E cada tool traz annotations, que o cliente usa para pedir confirmação:
| Anotação | Significado |
|---|---|
readOnlyHint | A tool só lê |
destructiveHint | A tool cancela, exclui, paga, transfere, aprova ou muda para onde dado e dinheiro saem da conta |
idempotentHint | Repetir a chamada tem o mesmo efeito |
openWorldHint | true nas tools que alcançam sistemas fora da Kobana (webhooks, canais da caixa postal, conexões bancárias, caixa EDI, conta de e-mail, consultas de boleto e de QR Code Pix); false nas demais |
tools/call
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": { "name": "banking_charge_bank_billet_list",
"arguments": { "filters": { "status": "overdue" }, "limit": 10,
"fields": ["amount", "expire_at", "status"] } } }
O resultado traz o JSON da resposta duas vezes: como texto, em content, para o cliente que só lê texto, e como objeto, em structuredContent, para o que interpreta o resultado.
{ "jsonrpc": "2.0", "id": 2, "result": {
"content": [{ "type": "text", "text": "{ \"data\": [ … ], \"meta\": { \"next_cursor\": \"…\" } }" }],
"structuredContent": { "data": [ … ], "meta": { "next_cursor": "…" } }
} }
Erros sobre os quais o chamador pode agir voltam com isError: true dentro do resultado, não como erro JSON-RPC: veja Erros.
Fora do MCP
Algumas ações da API ficam fora do MCP por decisão: tokens de acesso, usuários e certificados; envio e download de arquivo (upload multipart e resposta binária); e /me, que não tem escopo de recurso. Para essas, use a API REST.