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, sem token na URL. Uma requisição com ?access_token= (ou ?token= e afins) é recusada com 401, mesmo acompanhada de um cabeçalho válido: na URL o token vaza para logs, histórico do navegador e intermediários.

Esse token é um access token OAuth 2.1 emitido pelo authorization server da Kobana (https://account.kobana.com.br), um JWT assinado em RS256 e emitido para este recurso: o aud dele é https://mcp.finance.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.finance.*), e um token da API não vale aqui. É 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 Financeiro Inteligente, 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 workspace​

O org do token diz a organização; o workspace em que cada tool age é decidido a cada chamada, nesta ordem:

OrdemDe onde vem
1O argumento workspace_id da tool, quando vem na chamada
2O workspace padrão da conexão (abaixo)
—Nenhum dos dois: a tool volta o erro workspace_required

A URL do servidor não precisa de workspace — https://mcp.finance.kobana.com.br basta —, e conectar nunca falha por falta dele. Para saber onde pode agir, o agente chama finance_workspaces_list, sem argumentos: ela lista os workspaces da organização que a pessoa do token alcança.

{ "data": [
{ "id": "2b93f876-769a-4bdc-b23e-304957f313b4", "name": "Matriz", "default": true },
{ "id": "7c1d0e52-…", "name": "Filial Sul", "default": false }
] }

Toda outra tool — menos finance_schemas_get e a própria finance_workspaces_list — aceita o argumento opcional workspace_id (uuid):

{ "name": "finance_payables_list",
"arguments": { "workspace_id": "2b93f876-769a-4bdc-b23e-304957f313b4", "limit": 10 } }

O workspace padrão​

É o que vale quando a chamada não traz workspace_id, e é o que vem marcado default: true em finance_workspaces_list:

OndeExemplo
Cabeçalho X-Workspace-Id (opcional)X-Workspace-Id: 2b93f876-769a-4bdc-b23e-304957f313b4
Parâmetro na URL do servidor (opcional)https://mcp.finance.kobana.com.br/?workspace_id=2b93f876-…
Nenhum dos doisO único workspace que a pessoa alcança, se ela alcança exatamente um

O cabeçalho e o parâmetro de URL continuam aceitos, mas agora são opcionais e só definem o padrão: o argumento workspace_id sempre ganha deles. Em qualquer caso o valor é seletor, não concessão — ele é conferido contra a organização do token e o acesso da pessoa:

  • Sem workspace_id e sem padrão — a pessoa alcança vários workspaces —, a tool volta workspace_required. É um resultado de tool com isError: true, não um erro HTTP:

    { "error": { "code": "workspace_required", "message": "…" } }
  • Um workspace_id que a pessoa não alcança, ou que não existe, volta o erro de tool workspace_access_denied — a mesma resposta nos dois casos.

  • Um cabeçalho ou parâmetro de URL com um workspace de outra organização continua recusado com HTTP 403 UNKNOWN_WORKSPACE.

Resources (kobana://finance/…) e completions não têm argumento de workspace: usam o padrão da conexão. Sem padrão, ler um resource de registro falha com workspace_required — use as tools —, e as completions não sugerem nada. Veja Resources e prompts.

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-finance-mcp",
    error="invalid_token",
    resource_metadata="https://mcp.finance.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.finance.kobana.com.br/.well-known/oauth-protected-resource
    {
    "resource": "https://mcp.finance.kobana.com.br",
    "authorization_servers": ["https://account.kobana.com.br"],
    "bearer_methods_supported": ["header"],
    "resource_documentation": "https://docs.finance.kobana.com.br/pt/mcp/overview/introduction"
    }

    Não há scopes_supported: a Conta Kobana ainda não publica os escopos do Financeiro Inteligente, e um cliente que os pedisse seria recusado na autorização.

  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; a tela de consentimento avisa que ele não é um app verificado.

  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); o workspace vem de cada chamada, como acima. Nenhuma tool aceita organização como argumento.

Dois eixos de autorização​

O que um chamador vê é mais estreito que o catálogo, por dois filtros independentes. Nenhum dos dois pode alargar a superfície.

Eixo 1 — o escopo do token​

O teto do cliente, no claim scope. Leitura é tool de leitura, resource, prompt e completion; escrita é todo o resto, destrutivas incluídas. Mover dinheiro é um degrau acima da escrita.

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

Escopo do tokenResultado
finance/payables finance/people read writeLê e escreve contas a pagar e pessoas — e nada mais
finance/payables readSó lê contas a pagar
finance/all readLê tudo, não escreve nada
finance/payables finance/payable_dispatches read writeTambém envia contas a pagar ao banco

Enviar ao banco e cobrar exigem o recurso próprio — finance/payable_dispatches e finance/receivable_charges — com write ou all; finance/payables write não basta. delete, import e export sozinhos não contam como escrita.

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

:::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 mesma regra vale na API REST — veja Escopos.

Eixo 2 — as permissões da pessoa do token​

O sub do token é a pessoa que consentiu. No MCP, as tools são estreitadas para o que essa pessoa pode fazer no dashboard da organização, resolvido a cada requisição — as mesmas funções e permissões da tela Membros.

SituaçãoResultado
A pessoa nunca entrou no Financeiro Inteligente, ou não é membro da organizaçãoNega todas as tools. Quem não é membro não alcança nada pelo MCP.
Membro ativo, com acesso ao workspaceAs permissões dela, tool a tool. O dono (*) libera tudo; payables.* libera a família.
Membro ativo sem acesso ao workspaceNega todas as tools daquele workspace.
Membro suspenso, com convite pendente, removido, ou sem permissão nenhumaNega todas as tools. Um token sobrevivendo ao acesso da pessoa é exatamente o caso a fechar.
A consulta de permissões falhaNega todas as tools. Falha fechada.

As permissões são lidas a cada chamada: tirar uma permissão no dashboard vale já na tool seguinte, sem esperar o token expirar.

:::tip Postura recomendada para agentes Conecte o assistente com uma conta que só tem as permissões que o agente precisa, e, num token pessoal, marque só os recursos e acessos que ele vai usar. Os dois eixos se somam: o token de um analista somente-leitura expõe só as tools de leitura, faça o que fizer o modelo do outro lado. :::

Como os dois compõem​

O conjunto final é a interseção: tools ∩ escopos do token ∩ permissões da pessoa. Uma tool que o chamador não pode rodar não é listada.

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).
workspace_requiredO agente passa workspace_id — um dos id de finance_workspaces_list —, ou a conexão define um workspace padrão.
workspace_access_deniedUm admin concede o workspace à pessoa, ou o agente passa outro workspace_id.
membership_inactiveIncluir a pessoa na organização ou reativá-la — nenhuma permissão conserta um vínculo que não existe ou está inativo.

:::caution O que o eixo 2 não cobre O estreitamento por permissão vale só para o MCP. Um token da API, chamado direto em api.finance.*, continua limitado apenas pelos escopos. :::

Segurança › Canais​

As regras da aba Segurança › Canais continuam valendo por cima dos dois eixos — elas são aplicadas pelo próprio endpoint. Um agente de IA age pelo canal MCP - Inteligência Artificial, onde, por padrão, enviar ao banco começa fechado: finance_payables_send_to_bank só funciona depois que a solicitação for aprovada.

Revogação do token pessoal​

Revogar um token pessoal na sua Conta Kobana não corta o acesso na hora: o Financeiro Inteligente verifica o token sozinho, 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, suspenda ou remova a pessoa na organização, ou tire o acesso dela ao workspace — 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, no cabeçalho MCP-Protocol-Version ou no _meta; data.supported lista as que são. Veja Transporte.
401UNAUTHORIZEDToken ausente, malformado, inválido, revogado, expirado, emitido para outro recurso (a API, por exemplo) ou enviado na URL (?access_token=).
403UNKNOWN_ORGANIZATION / UNKNOWN_WORKSPACEO org do token não é um cliente, ou o workspace de X-Workspace-Id / ?workspace_id= não é da organização.
403FORBIDDENOrigin fora da allowlist (origin_not_allowed).
404NOT_FOUNDA requisição chegou por um host que não serve MCP, ou pediu um caminho que não existe no servidor.
429RATE_LIMITEDLimite de requisições atingido — veja Limite de requisições.
503SERVICE_UNAVAILABLEA Conta Kobana não respondeu para validar o token. Não é problema do token: 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​

O endpoint só é alcançável por mcp.finance.* — nunca pelo host do app nem pelo da API, que apontam para a mesma origin. Qualquer outro caminho responde 404, sempre em JSON e para qualquer método — { "error": { "code": "NOT_FOUND", "message": "Not found." } }, nunca uma página HTML. O identificador de recurso OAuth é derivado da configuração do servidor, nunca do Host da requisição, para que um Host forjado não consiga apontar um cliente para outro identificador.