Factuarea API
Servidor MCP

Errores y límites de peticiones

Formas de error JSON-RPC mapeadas desde el contrato v1, la tabla completa de códigos y throttling por token / por plan con Retry-After.

El servidor MCP habla JSON-RPC 2.0 estricto. Los fallos vuelven como un objeto error, nunca como un cuerpo de error HTTP al estilo de la API REST — pero la semántica es idéntica: la misma violación de regla de negocio que devuelve 422 sobre REST devuelve aquí el error JSON-RPC equivalente, con el code y el http_status de v1 conservados en data.

Esta página cubre el mapeo JSON-RPC específico de MCP y los buckets de throttling de MCP. Para el contrato REST canónico — el envoltorio de error por code y las cuotas por tier — consulta Errores y Límites de peticiones.

Forma del error

{
  "jsonrpc": "2.0",
  "id": "<request id>",
  "error": {
    "code": -32008,
    "message": "invoice_cannot_be_modified",
    "data": {
      "http_status": 422,
      "code": "invoice_cannot_be_modified",
      "hint": "La factura ya emitida no puede modificarse.",
      "param": "status"
    }
  }
}
  • error.code — el código numérico JSON-RPC (siempre en el rango -32099..-32000 definido por la implementación, o -32603 para errores internos).
  • error.message — un identificador de cadena estable (p. ej. insufficient_scope, invoice_cannot_be_modified).
  • error.data.code — el mismo code canónico de v1 que devuelve la API REST, para que puedas ramificar según un único valor en ambas superficies.
  • error.data.http_status — el estado HTTP que devolvería la llamada REST equivalente (422 / 404 / 409 / …), para clientes que prefieren razonar en términos HTTP.
  • error.data.hint — un mensaje legible para personas (en español, acorde con el idioma de la app). Otros campos (param, subcode, required_scope, …) aparecen cuando son relevantes.

Tabla de códigos

JSON-RPC codemessage / data.codeHTTP equiv.Significado
-32001invalid_token401Credencial ausente, malformada o desconocida; o el usuario ya no es miembro de la empresa.
-32002client_revoked403El cliente OAuth fue revocado.
-32003invalid_token_type403Tipo de credencial incorrecto para esta superficie.
-32004plan_limit_exceeded / plan_upgrade_required402Se alcanzó un límite de uso del plan, o la acción requiere un plan superior. data incluye resource, current, limit.
-32005insufficient_scope / module_not_in_plan / feature_flag_disabled403La credencial carece del scope requerido, el módulo no está en el plan, o un feature flag está desactivado. data incluye required_scope / module / flag.
-32006rate_limit_exceeded429Se superó un bucket de throttling. data incluye retry_after y bucket; la respuesta también establece la cabecera Retry-After.
-32007addon_not_active403El add-on de developer API de la empresa está inactivo (fuera de su periodo de gracia).
-32008(código v1)422 / 404 / 409 / …Una violación de regla de negocio, recurso inexistente o conflicto. message y data.code son el código de error canónico de v1; data.http_status te indica la categoría.
-32603internal_error500Error inesperado del servidor.

-32005 y -32008 cubren cada uno varias subcausas. Ramifica siempre según data.code (la cadena), no solo según el code numérico, cuando necesites distinguirlas — p. ej. insufficient_scope y module_not_in_plan afloran ambos como -32005.

Scope insuficiente

Cuando una tool necesita un scope que la credencial no tiene:

{
  "jsonrpc": "2.0",
  "id": "req-42",
  "error": {
    "code": -32005,
    "message": "insufficient_scope",
    "data": {
      "http_status": 403,
      "code": "insufficient_scope",
      "required_scope": "invoices:write",
      "provided_scopes": ["invoices:read", "clients:read"],
      "hint": "La credencial no tiene el scope requerido para esta operación."
    }
  }
}

Las tools que tu credencial no puede alcanzar también quedan ocultas en tools/list, así que un agente bien comportado normalmente no las intentará — este error es la red de seguridad.

Límites de peticiones

Las peticiones se limitan en tres buckets independientes. Superar cualquiera de ellos devuelve -32006 con una cabecera Retry-After (segundos).

Por token, por categoría de tool

Cada credencial tiene contadores por minuto separados por categoría de tool, de modo que un uso destructivo intensivo no pueda agotar tus lecturas:

CategoríaLímite por defectoTools de ejemplo
read / write60 / minsearch_invoices, create_invoice
send20 / minsend_invoice, send_quote
generate30 / minget_invoice_facturae_link
destructive10 / mindelete_invoice, bulk_delete_clients

El bucket se resuelve a partir de la categoría de la tool. El contador se incrementa antes de que la tool se ejecute, así que las llamadas rechazadas (scope incorrecto, error de validación) también consumen cuota — esto es anti-abuso deliberado, acorde con el patrón estándar OAuth/REST.

Por plan, cada hora

Un tope horario a nivel de empresa por slug de plan. El plan Enterprise se salta este bucket por completo.

Por cliente OAuth, global

Las apps OAuth comparten además un bucket global por cliente de 1000 / min, de modo que una sola app que se porte mal no pueda saturar el servidor a través de todos sus usuarios.

Cabeceras de límite de peticiones

Las respuestas correctas llevan el presupuesto restante para que puedas reducir el ritmo de forma proactiva:

HeaderSignificado
X-RateLimit-Limit-Token / X-RateLimit-Remaining-TokenEl bucket por token (por categoría).
X-RateLimit-Limit-Hour / X-RateLimit-Remaining-HourEl bucket por plan horario (ausente en Enterprise).
Retry-AfterEn un 429, segundos a esperar antes de reintentar.

Límites de los endpoints de auth

Los endpoints OAuth tienen sus propios límites, independientes de los buckets de MCP:

EndpointLímite
POST /api/oauth/register10 / hora por IP
POST /api/oauth/token60 / min por (cliente, IP)

Respeta siempre Retry-After. Reintentar antes de que transcurra mantiene el bucket lleno y solo retrasa tu recuperación. Combínalo con idempotencia en las escrituras para que un reintento retrasado nunca duplique un documento.

En esta página