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 e api_key) 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 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.dashboards.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.dashboards.*), 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 Dashboard Mágico, uso MCP, recursos e acessos, validade
Como o cliente usaSozinho, depois da autorizaçãoVocê cola no cliente como Authorization: Bearer <token>
Validade30 minutos, renovado 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 automações

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-dashboards-mcp",
    error="invalid_token",
    resource_metadata="https://mcp.dashboards.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.dashboards.kobana.com.br/.well-known/oauth-protected-resource
    {
    "resource": "https://mcp.dashboards.kobana.com.br",
    "authorization_servers": ["https://account.kobana.com.br"],
    "bearer_methods_supported": ["header"],
    "resource_documentation": "https://docs.dashboards.kobana.com.br"
    }
  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 org que escopa os dados — nenhuma tool aceita organização como argumento. Um token cuja organização não existe no Dashboard Mágico recebe 403 unknown_organization.

Autorização: as permissões de quem autorizou​

O que um chamador vê é mais estreito que o catálogo: as tools são filtradas pelas permissões de dashboard da pessoa que autorizou o cliente, naquela organização, resolvidas a cada requisição. O teto é sempre o que essa pessoa pode fazer na interface.

SituaçãoResultado
A pessoa não é membro da organizaçãoNega todas as tools (key_owner_not_member). Autorize de novo com uma conta que pertença à organização.
Vínculo ativoAs permissões e papéis da pessoa, aplicados tool a tool. owner e o curinga * liberam tudo; portal-users.* libera a família.
Vínculo suspenso, removido, ou sem nenhum papelNega todas as tools (membership_inactive).
A consulta de permissões falhaNega todas as tools. Falha fechada.

As permissões são lidas a cada chamada, então revogar um papel no dashboard vale já na tool seguinte, sem esperar o token expirar.

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 — nenhuma permissão conserta um vínculo morto.
key_owner_not_memberAutorizar de novo com uma conta que seja membro da 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 de leitura e completion; escrita é todo o resto, destrutivas incluídas.

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

Escopo do tokenResultado
dashboards/users dashboards/members read writeLê e escreve usuários do portal e membros do time (com os papéis) — e nada mais
dashboards/users readSó lê usuários do portal
dashboards/all readLê tudo, não escreve nada

Um recurso fora dos dez grupos só é alcançável com dashboards/all. 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.

:::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, com o recurso tirado do caminho: um token sem acesso de escrita ao recurso recebe 403 insufficient_scope em qualquer método que não seja GET.

Revogação do token pessoal​

Revogar um token pessoal na sua conta Kobana não corta o acesso na hora: o Dashboard Mágico 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 o vínculo da 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, no cabeçalho MCP-Protocol-Version ou no _meta; data.supported lista as que são. Veja Transporte.
401UNAUTHORIZEDToken ausente, malformado, inválido, expirado ou emitido para outro recurso (por exemplo, para a API REST).
403unknown_organizationO token é válido, mas a organização que ele nomeia não existe no Dashboard Mágico.
403FORBIDDENOrigin fora da allowlist (origin_not_allowed).
404NOT_FOUNDA requisição chegou por um host que não serve MCP.
429TOO_MANY_REQUESTSLimite 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 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.dashboards.* — nunca pelo host do app, nunca pelo host da API, cujas distributions apontam para a mesma origin. Qualquer outro caminho responde 404: o endpoint não anuncia que existe em outro lugar.

O identificador de recurso OAuth — e, portanto, a audience que o token precisa ter — é 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.