Saltar al contenido principal

Autenticación

El servidor MCP acepta un Bearer token en la cabecera Authorization, y nada más — sin cookie, sin certificado de cliente.

:::warning Nunca en la URL Un token en la query string (?access_token=…, o parámetros como token y api_key) no autentica, aunque venga junto a una cabecera válida: la petición responde 401 con error="invalid_request" en WWW-Authenticate. Un token en la URL se filtra en logs de proxy y CDN, en el Referer y en el historial — la especificación de autorización de MCP y la RFC 6750 lo prohíben. :::

Ese token es un access token OAuth 2.1 emitido por el authorization server de Kobana (https://account.kobana.com.br): un JWT firmado en RS256 y emitido para este recurso, cuyo aud es https://mcp.dashboards.kobana.com.br. Llega por uno de dos caminos — el flujo OAuth, que hace el propio cliente, o un token personal que creas en tu cuenta Kobana — y se verifica igual en los dos casos.

Authorization: Bearer eyJhbGciOiJSUzI1NiIs…

:::info Cada superficie tiene su propia audience Un token emitido para el MCP no vale en la API REST (api.dashboards.*), y un token de la API no vale aquí. Es lo que impide que el token entregado a un asistente se reutilice contra la API — y al revés. :::

Dos formas de conectarse​

Flujo OAuthToken personal
Cómo lo obtienesPegas la URL en el cliente; abre el inicio de sesión de Kobana y autorizasLo creas en Cuenta Kobana → Tokens y Acceso → Nuevo Token Personal: app Dashboard Mágico, uso MCP, recursos y accesos, validez
Cómo lo usa el clienteSolo, después de la autorizaciónLo pegas en el cliente como Authorization: Bearer <token>
Validez30 minutos, renovado por el clienteDe 7 días a 1 año, a tu elección
AlcanceSolo el nivel de acceso — hoy, readLos recursos y accesos que marcaste
Bueno paraClaude, ChatGPT, IDEs y cualquier cliente con OAuthClientes sin soporte de OAuth, scripts y automatizaciones

El token personal tiene que crearse con el uso MCP. Un token creado para la API REST tiene la audience de la API y aquí se rechaza con 401 — y lo contrario también vale.

El flujo OAuth​

No ejecutas ninguno de estos pasos: el cliente MCP (Claude, ChatGPT, un IDE) lo hace todo solo a partir de la URL. Están aquí para cuando algo falle a mitad de camino.

  1. Desafío. Una petición sin token recibe 401 con el desafío que todo resource server OAuth 2.1 debe enviar (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 del recurso. El cliente lee el documento señalado. Es público y no lleva ningún secreto — solo punteros:

    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 del authorization server (RFC 8414), en https://account.kobana.com.br/.well-known/oauth-authorization-server.

  4. Registro dinámico del cliente (RFC 7591). El cliente se registra solo; la pantalla de consentimiento avisa que no es una app verificada.

  5. Autorización con PKCE y resource (RFC 8707). Inicias sesión en Kobana, eliges la organización (si tienes más de una) y autorizas.

  6. Token. El cliente cambia el código por un access token de vida corta y lo envía en cada petición, renovándolo cuando expira.

El token lleva quién eres (sub) y la organización que autorizaste (org). Es el org lo que delimita los datos — ninguna tool acepta organización como argumento. Un token cuya organización no existe en Dashboard Mágico recibe 403 unknown_organization.

Autorización: los permisos de quien autorizó​

Lo que un llamador ve es más estrecho que el catálogo: las tools se filtran por los permisos de dashboard de la persona que autorizó el cliente, en esa organización, resueltos en cada petición. El techo es siempre lo que esa persona puede hacer en la interfaz.

SituaciónResultado
La persona no es miembro de la organizaciónNiega todas las tools (key_owner_not_member). Autoriza de nuevo con una cuenta que pertenezca a la organización.
Vínculo activoLos permisos y roles de la persona, aplicados tool a tool. owner y el comodín * lo liberan todo; portal-users.* libera la familia.
Vínculo suspendido, eliminado, o sin ningún rolNiega todas las tools (membership_inactive).
La consulta de permisos fallaNiega todas las tools. Falla cerrada.

Los permisos se leen en cada llamada, así que revocar un rol en el dashboard vale ya en la tool siguiente, sin esperar a que el token expire.

Una tool que el llamador no puede ejecutar no aparece en tools/list. Cuando tools/call rechaza, el código dice quién lo resuelve:

CódigoQuién lo resuelve
insufficient_scopeUsar un token que alcance el recurso con el acceso pedido — por ejemplo, un token personal con escritura en ese recurso.
insufficient_permissionUn admin de la organización, concediendo el permiso (el error dice cuál).
membership_inactiveReactivar a la persona — ningún permiso arregla un vínculo muerto.
key_owner_not_memberAutorizar de nuevo con una cuenta que sea miembro de la organización.

:::tip Postura recomendada para agentes Autoriza el cliente con una cuenta que tenga solo los permisos que el agente necesita. Un cliente autorizado por un analista de solo lectura expone solo las tools de lectura, haga lo que haga el modelo del otro lado. :::

Alcance del token​

Además de los permisos, el MCP aplica el alcance que trae el token, en el claim scope. Las dos verificaciones se suman: una tool solo aparece si las dos lo permiten. Lectura es tool de lectura, resource, prompt de lectura y completion; escritura es todo lo demás, destructivas incluidas.

Token con recursos — el caso del token personal. Los recursos definen hasta dónde llega el token, y read/write valen solo dentro de ellos:

Alcance del tokenResultado
dashboards/users dashboards/members read writeLee y escribe usuarios del portal y miembros del equipo (con sus roles) — y nada más
dashboards/users readSolo lee usuarios del portal
dashboards/all readLee todo, no escribe nada

Un recurso fuera de los diez grupos solo se alcanza con dashboards/all. delete, import y export solos no cuentan como escritura.

Token sin recursos — el caso del flujo OAuth. Vale solo el nivel de acceso: lectura con read, write o all; escritura con write o all.

:::info Los clientes conectados por el flujo OAuth quedan solo con lectura El authorization server concede solo read a los clientes registrados dinámicamente — Claude, ChatGPT, el MCP Inspector, IDEs. Para ellos, el MCP lista solo las tools de lectura, y una tool que escribe devuelve insufficient_scope. Para que un agente escriba hoy, usa un token personal con acceso de escritura a los recursos que necesita. :::

La misma regla vale en la API REST, con el recurso tomado de la ruta: un token sin acceso de escritura al recurso recibe 403 insufficient_scope en cualquier método que no sea GET.

Revocación del token personal​

Revocar un token personal en tu cuenta Kobana no corta el acceso en el momento: Dashboard Mágico verifica el token por su cuenta, sin consultar a Kobana en cada llamada, y sigue aceptándolo hasta su vencimiento. Por eso:

  • elige la validez más corta que el uso permita;
  • marca solo los recursos y accesos que el agente necesita;
  • para cortar un agente de inmediato, suspende o quita el vínculo de la persona con la organización — los permisos se leen en cada llamada y valen al instante.

Modos de fallo​

HTTPcodeCausa
400-32022 (JSON-RPC)Versión del protocolo no soportada, en la cabecera MCP-Protocol-Version o en _meta; data.supported lista las que sí. Ve Transporte.
401UNAUTHORIZEDToken ausente, malformado, inválido, expirado o emitido para otro recurso (por ejemplo, para la API REST).
403unknown_organizationEl token es válido, pero la organización que nombra no existe en Dashboard Mágico.
403FORBIDDENOrigin fuera de la allowlist (origin_not_allowed).
404NOT_FOUNDLa petición llegó por un host que no sirve MCP.
429TOO_MANY_REQUESTSLímite de peticiones alcanzado — ver Límite de peticiones.
503SERVICE_UNAVAILABLENo pudimos hablar con el authorization server para verificar el token. Es de nuestro lado: reintenta después del Retry-After.

Todo 401 lleva el desafío WWW-Authenticate de arriba, que devuelve al cliente al flujo OAuth.

Las negativas de permiso no son errores HTTP: vuelven como resultado de tool marcado isError, para que el modelo las lea y reaccione — ver Errores.

Host y edge​

/mcp tiene que ser alcanzable solo por mcp.dashboards.* — nunca por el host de la app, nunca por el host de la API, cuyas distributions apuntan al mismo origin. Cualquier otro camino responde 404: el endpoint no anuncia que existe en otro lugar.

El identificador de recurso OAuth — y, por tanto, la audience que el token necesita tener — se deriva de la configuración del servidor, nunca del Host de la petición, para que un Host falsificado no pueda apuntar un cliente a otro identificador.