Errores
Las fallas llegan por dos canales diferentes, y la distinción importa: uno es una solicitud rota, el otro es algo que el modelo debe leer y a lo que debe reaccionar.
Errores de tool
Todo aquello sobre lo que el llamador puede actuar — argumento inválido, no
encontrado, alcance o permiso insuficiente, un error de la ruta — vuelve como
una respuesta JSON-RPC exitosa cuyo resultado está marcado isError, con
el sobre de error de la propia API como texto:
{ "jsonrpc": "2.0", "id": 2, "result": {
"isError": true,
"content": [{ "type": "text",
"text": "{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"Execution not found\" } }" }]
} }
El vocabulario de code es el de la API v1, sin
cambios. Los que más vas a encontrar:
code | Cuándo |
|---|---|
VALIDATION_ERROR | Los argumentos fallaron en la validación — de la propia tool (Invalid tool arguments.) o de la ruta; los detalles nombran los campos. |
NOT_FOUND | El registro no existe, fue eliminado o pertenece a otra organización. |
CONFLICT | Conflicto de estado — por ejemplo, nombre de entorno ya usado. |
IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_REQUEST_IN_PROGRESS | Mira Idempotencia. |
FEATURE_NOT_ENABLED | Kobana no habilitó esta operación para la organización. |
ENTITLEMENT_REQUIRED | Lanzamiento sin Kadu en el plan de la organización. |
MISSING_SECRETS, ENVIRONMENT_REQUIRED | Lanzamiento con secrets exigidos sin valor en el entorno, o sin un entorno válido. kadu_tasks_readiness_get lo verifica antes. |
COST_LIMIT_REACHED | La organización alcanzó el tope mensual de costo. |
RATE_LIMITED | Se alcanzó el límite de la ruta — mira Límite de Peticiones. |
USER_DECLINED | En la era 2026-07-28, rechazaste o cancelaste la confirmación de una tool destructiva. No cambió nada. |
confirmation_required | La tool es destructiva, el cliente no puede confirmar en el chat y el token no tiene una persona de la organización que pueda abrir un enlace de aprobación. No se ejecutó nada. |
confirmation_replayed | La confirmación enviada ya se había usado — cada una ejecuta una llamada una vez. Llama a la tool de nuevo para que se te pregunte otra vez. No se ejecutó nada. |
confirmation_unavailable | El servidor no pudo registrar la confirmación (o la aprobación por enlace) en este momento, así que rechazó la tool. No se ejecutó nada; inténtalo más tarde. |
Y los tres que añade el propio MCP, porque son de autorización, no del registro:
code | Quién lo resuelve |
|---|---|
insufficient_scope | El alcance del token no cubre la tool: el recurso no está en el token, o falta el nivel que exige (write o delete). Autoriza de nuevo concediendo el acceso que faltó, o usa un token personal que alcance el recurso con el nivel pedido. |
insufficient_permission | Un administrador de la organización, concediendo el permiso que nombra el error. |
not_a_member | Autorizar el cliente de nuevo con una cuenta que sea miembro de la organización — ningún permiso lo arregla. |
Esos tres están separados a propósito: son conversaciones diferentes, con personas diferentes. Un error único diría "no puedes" sin decir a quién pedírselo. Mira Autenticación.
No todo lo que no se ejecuta es un error
input_required. En la era2026-07-28, el primertools/callde una tool destructiva puede devolverresultType: "input_required"con un pedido de confirmación al usuario. El cliente muestra la pregunta y reenvía la misma llamada con la respuesta.approval_required. En los demás clientes, la misma llamada devuelve, sinisError,status: "approval_required"con el enlace de aprobación. Muestra el enlace; no llames a la tool de nuevo.
Los dos son el flujo normal — mira Confirmación de tools destructivas.
Errores de protocolo
Un mensaje mal formado recibe un objeto de error JSON-RPC, no un resultado:
| Código | Significado |
|---|---|
-32700 | Parse error — el cuerpo no es JSON válido (HTTP 400) |
-32600 | Invalid request — no es un objeto JSON-RPC, es un array (el batching no está soportado) o el cuerpo pasa de 1 MB |
-32601 | Method not found (HTTP 404 en la era 2026-07-28) |
-32602 | Invalid params — tool o prompt inexistente, name ausente, argumento de prompt inválido, resource sin permiso; en la era 2026-07-28, también resource no encontrado |
-32002 | Resource no encontrado — solo en la era 2025 (la 2026-07-28 usa -32602) |
-32603 | Internal error — falla inesperada al ejecutar la tool |
-32020 | Header mismatch — en la era 2026-07-28, una cabecera MCP no coincide con el cuerpo (HTTP 400) |
-32022 | Unsupported protocol version (HTTP 400) |
{ "jsonrpc": "2.0", "id": 3,
"error": { "code": -32601, "message": "Method not found: tools/describe" } }
Errores de transporte
Los rechazos que ocurren antes de leer el mensaje JSON-RPC son respuestas
HTTP comunes, con el sobre { "error": { "code", "message" } }: token ausente o
inválido, organización desconocida, Origin fuera de la lista, límite de
solicitudes, cuerpo demasiado grande, verificación del token no disponible.
Están listados en Autenticación → Modos de falla.
Por qué isError y no un error JSON-RPC
Un 404 en una ejecución no es un defecto del cliente MCP — es información
sobre el mundo, y el modelo del otro lado la necesita para corregirse.
Enterrarla en un error de protocolo haría que el cliente la tratara como falla
de transporte, ocultara el texto y, en el mejor caso, reintentara idéntico. Por
eso la regla es: si el llamador puede actuar, es resultado; si la solicitud
está rota, es error.
Observabilidad
Cada tools/call escribe una línea de log estructurada con la tool, la
organización, el id del token, el tipo de token (flujo OAuth o personal), el
estado y la duración — nunca los argumentos, el token ni el cuerpo. Lo que hace
la tool pasa por la misma ruta de la API, con los mismos efectos: un
lanzamiento se convierte en una ejecución como cualquier otra, con los mismos
eventos y webhooks. Las aprobaciones por enlace quedan registradas en
Configuración › Aprobaciones, con lo que se pidió, la decisión, cuándo y el
resultado.