Pular para o conteúdo principal

Autenticação

O servidor MCP aceita um Bearer token no cabeçalho Authorization, e nada além disso — sem cookie, sem certificado de cliente.

:::warning Nunca na URL Token na query string (?access_token=…, ou parâmetros como token, bearer, bearer_token, id_token, api_key e apikey) não autentica, mesmo acompanhado de um cabeçalho válido: a requisição responde 401 com error="invalid_request" no WWW-Authenticate. Um token na URL vaza em logs de proxy e CDN, no Referer e no histórico — a especificação de autorização do MCP e a RFC 6750 proíbem esse uso. :::

Esse token é um access token emitido pelo authorization server da Kobana (a Conta Kobana, https://account.kobana.com.br), um JWT assinado em RS256 e emitido para este recurso: o aud dele é https://mcp.dunning.kobana.com.br. Ele chega por um de dois caminhos — o fluxo OAuth, feito pelo próprio cliente, ou um token pessoal que você cria na sua conta Kobana — e é verificado do mesmo jeito nos dois casos.

Authorization: Bearer eyJhbGciOiJSUzI1NiIs…

:::info Cada superfície tem a sua audience Um token emitido para o MCP não vale na API REST (api.dunning.*), e um token da API não vale aqui: os dois são recusados com 401. Um token cujo aud lista mais de um valor também é recusado — ele valeria nas duas superfícies. É o que impede que o token entregue a um assistente seja reaproveitado contra a API, e o contrário. :::

Dois jeitos de conectar​

Fluxo OAuthToken pessoal
Como você obtémCola a URL no cliente; ele abre o login da Kobana e você autorizaCria em Conta Kobana → Tokens e Acesso → Novo Token Pessoal: app Régua de Cobrança, uso MCP, recursos e acessos, validade
Como o cliente usaSozinho, depois da autorizaçãoVocê cola no cliente como Authorization: Bearer <token>
ValidadeCurta, renovada pelo clienteDe 7 dias a 1 ano, escolhida por você
EscopoSó o nível de acesso — hoje, readOs recursos e acessos que você marcou
Bom paraClaude, ChatGPT, IDEs e qualquer cliente com OAuthClientes sem suporte a OAuth, scripts e agentes que precisam escrever

O token pessoal tem que ser criado com o uso MCP. Um token criado para API REST tem a audience da API e é recusado aqui com 401 — e o contrário também vale.

O fluxo OAuth​

Você não executa nenhum destes passos: o cliente MCP (Claude, ChatGPT, uma IDE) faz tudo sozinho a partir da URL. Eles estão aqui para quando algo falhar no meio.

  1. Desafio. Uma requisição sem token recebe 401 com o desafio que todo resource server OAuth 2.1 deve mandar (RFC 9728):

    WWW-Authenticate: Bearer realm="kobana-dunning-mcp",
    error="invalid_token",
    resource_metadata="https://mcp.dunning.kobana.com.br/.well-known/oauth-protected-resource"
  2. Metadata do recurso. O cliente lê o documento apontado. Ele é público e não carrega segredo nenhum — só ponteiros:

    curl https://mcp.dunning.kobana.com.br/.well-known/oauth-protected-resource
    {
    "resource": "https://mcp.dunning.kobana.com.br",
    "authorization_servers": ["https://account.kobana.com.br"],
    "bearer_methods_supported": ["header"],
    "scopes_supported": [
    "dunning/agreements", "dunning/audit_logs", "dunning/charges",
    "dunning/classifications", "dunning/collection_rules", "dunning/disputes",
    "dunning/email_layouts", "dunning/exports", "dunning/imports",
    "dunning/interactions", "dunning/metrics", "dunning/negativations",
    "dunning/negotiation_campaigns", "dunning/notification_channels",
    "dunning/notification_preferences", "dunning/notifications", "dunning/people",
    "dunning/protests", "dunning/tasks", "dunning/templates",
    "dunning/webhook_endpoints", "read"
    ],
    "resource_documentation": "https://docs.dunning.com.br/en/mcp/overview/introduction"
    }

    scopes_supported é o que um cliente deve pedir: os 21 recursos dunning/<recurso> mais read. dunning/all e os verbos (write, …) ficam de fora de propósito — o authorization server não os concede a um cliente registrado dinamicamente. Sem essa lista, o cliente pediria os escopos de todos os produtos Kobana, e a autorização seria recusada.

  3. Metadata do authorization server (RFC 8414), em https://account.kobana.com.br/.well-known/oauth-authorization-server.

  4. Registro dinâmico do cliente (RFC 7591). O cliente se registra sozinho.

  5. Autorização com PKCE e resource (RFC 8707). Você faz login na Kobana, escolhe a organização (se tiver mais de uma) e autoriza.

  6. Token. O cliente troca o código por um access token de vida curta e passa a mandá-lo em toda requisição, renovando quando expira.

O token carrega quem você é (sub) e a organização que você autorizou (org, a conta Kobana). É o org que escopa os dados — nenhuma tool aceita organização como argumento. Um token cuja organização não existe na Régua de Cobrança recebe 403 unknown_organization.

Permissões da pessoa​

Aqui está a diferença mais importante em relação à API REST. Na API, o token age com a autoridade da integração. No MCP, nunca: as tools são filtradas pelas permissões de dashboard da pessoa dona do token (o sub) naquela organização, lidas a cada requisição. O teto é sempre o que essa pessoa pode fazer na interface.

A pessoa é localizada pela identidade Kobana que a Régua de Cobrança registra quando ela entra no dashboard com a conta Kobana. Por isso, quem nunca entrou no dashboard da Régua de Cobrança com a conta Kobana não tem tool nenhuma: recebe key_owner_not_member, mesmo sendo membro da organização. Resolve-se entrando uma vez no dashboard com a conta Kobana — ou, se a pessoa ainda não é membro, pedindo um convite. Um convite para outra organização também vale: lá, o vínculo é encontrado pelo e-mail da pessoa.

SituaçãoResultado
A pessoa não é membro da organização, ou nunca entrou na Régua de Cobrança com a conta KobanaNega todas as tools (key_owner_not_member).
Vínculo inativo, ou sem nenhuma permissão nem papelNega todas as tools (membership_inactive).
A consulta de permissões falhaNega todas as tools. Falha fechada.
Vínculo ativoAs permissões e papéis da pessoa, aplicados tool a tool. dunning.dashboard.* libera tudo; dunning.dashboard.charges.* libera a família de cobranças.

As permissões são lidas a cada chamada, então revogar um papel no dashboard vale já na chamada seguinte, sem esperar o token expirar. Recursos administrativos — membros, papéis, chaves, configurações — nunca são alcançáveis por token, e nem têm tool.

Uma tool que o chamador não pode rodar não é listada em tools/list. Quando tools/call recusa, o código diz quem resolve:

CódigoQuem resolve
insufficient_scopeUsar um token que alcance o recurso com o acesso pedido — por exemplo, um token pessoal com escrita nesse recurso.
insufficient_permissionUm admin da organização, concedendo a permissão (o erro nomeia qual).
membership_inactiveReativar a pessoa na organização — nenhuma permissão conserta um vínculo inativo.
key_owner_not_memberA pessoa entrar uma vez no dashboard da Régua de Cobrança com a conta Kobana, ou pedir um convite para a organização.

:::tip Postura recomendada para agentes Autorize o cliente com uma conta que só tenha as permissões que o agente precisa. Um cliente autorizado por um analista somente-leitura expõe só as tools de leitura, faça o que fizer o modelo do outro lado. :::

Escopo do token​

Além das permissões, o MCP aplica o escopo que o token carrega, no claim scope. As duas checagens se somam: uma tool só aparece se as duas deixarem. Leitura é tool de leitura, resource, prompt e completion; escrita é todo o resto, destrutivas incluídas.

O escopo chega em um de dois formatos.

Token com recursos dunning/… — o caso do token pessoal. Os recursos definem até onde o token chega, e read/write/all valem só dentro deles:

Escopo do tokenResultado
dunning/charges dunning/people read writeLê e escreve cobranças e devedores — e nada mais
dunning/charges readSó lê cobranças
dunning/all readLê tudo, não escreve nada

delete, import e export sozinhos não contam como escrita.

Token sem recursos dunning/… — o caso do fluxo OAuth. Vale só o nível de acesso: leitura com read, write ou all; escrita com write ou all.

Um token que não traz nem recurso nem nível de acesso não alcança tool nenhuma — só dunning_me.

O recurso de cada tool é o primeiro segmento do caminho da API: /collection-rules/... é collection_rules. Os contatos de um devedor ficam em people, os passos de régua em collection_rules e as campanhas de negociação em negotiation_campaigns. Os 21 recursos são:

agreements, audit_logs, charges, classifications, collection_rules, disputes, email_layouts, exports, imports, interactions, metrics, negativations, negotiation_campaigns, notification_channels, notification_preferences, notifications, people, protests, tasks, templates, webhook_endpoints.

:::info Clientes conectados pelo fluxo OAuth ficam só com leitura O authorization server concede apenas read a clientes registrados dinamicamente — Claude, ChatGPT, o MCP Inspector, IDEs. Para eles, o MCP lista só as tools de leitura, e uma tool que escreve volta insufficient_scope. Para um agente escrever hoje, use um token pessoal com acesso de escrita nos recursos de que ele precisa. :::

A checagem de escopo se repete na /v1 quando a tool é despachada — defesa em profundidade. Se ela recusar lá, a tool volta o 403 INSUFFICIENT_SCOPE da API como erro de tool.

Revogação do token pessoal​

Revogar um token pessoal na sua conta Kobana não corta o acesso na hora: a Régua de Cobrança verifica o token localmente, sem consultar a Kobana a cada chamada, e ele continua aceito até a validade dele. Por isso:

  • escolha a validade mais curta que o uso permite;
  • marque só os recursos e acessos de que o agente precisa;
  • para cortar um agente imediatamente, desative a pessoa na organização — as permissões são lidas a cada chamada e valem na hora.

Modos de falha​

HTTPcodeCausa
400-32022 (JSON-RPC)Versão do protocolo não suportada; data.supported lista as que são. Veja Transporte.
400-32020 (JSON-RPC)Na era 2026-07-28, um cabeçalho diverge do corpo. Veja Transporte.
401UNAUTHORIZEDToken ausente, malformado, inválido, expirado, emitido para outro recurso (por exemplo, para a API REST) ou enviado na URL.
403unknown_organizationO token é válido, mas a organização que ele nomeia não existe na Régua de Cobrança.
403FORBIDDENorigin_not_allowed: um Origin de navegador que não é o próprio servidor. Requisição sem Origin passa.
404NOT_FOUNDA requisição chegou por um host que não serve MCP.
413-32600 (JSON-RPC)Corpo acima de 2 MB (Request body too large) — o mesmo teto da API v1.
429RATE_LIMITEDLimite de requisições atingido — veja Limite de requisições.
503SERVICE_UNAVAILABLENão conseguimos falar com o authorization server para verificar o token. É do nosso lado: tente de novo depois do Retry-After.

Todo 401 carrega o desafio WWW-Authenticate acima, que manda o cliente de volta ao fluxo OAuth.

Negativas de escopo e de permissão não são erros HTTP: elas voltam como resultado de tool marcado isError, para que o modelo leia e reaja — veja Erros.

Host e borda​

/mcp tem que ser alcançável só por mcp.dunning.* — nunca pelo host do app, nunca pelo host da API, que apontam para a mesma aplicação. Por qualquer outro host, o endpoint responde 404: ele não anuncia que existe em outro lugar.