Facturiadocs
MCP / IA

Conectar un agente

mcp.facturia.cl — el mismo motor, otra puerta de entrada. Cómo conectar Claude, qué pasa en el OAuth y por qué un grant de sandbox es un límite duro.

El mismo motor que la API REST, otra puerta de entrada: en vez de que una persona escriba curl, un agente de IA de terceros llama herramientas tipadas.

https://mcp.facturia.cl

Un solo endpoint MCP (/mcp) hablando Streamable HTTP, y un solo conjunto de endpoints OAuth en el mismo origen. No hay subdominios por empresa ni por cuenta: la tenencia es un claim del token, no un hostname.

El hecho arquitectónico

El servidor MCP es un cliente REST de /v1

No tiene lógica de negocio ni credenciales del motor: ni certificado del SII, ni llave de firma, ni acceso al esquema del motor. Cada pregunta de dominio — cuáles son los totales de un documento, si hay folios disponibles, qué dice el F29 — es un request a /v1, nunca una consulta.

Eso significa que todo lo que vale en esta documentación sobre estados, errores y garantías vale igual desde un agente.

Por qué el agente no es un desarrollador

Un agente no puede leer docs.facturia.cl antes de decidir qué hacer. De ahí salen tres compromisos de diseño de esta capa:

Suite completa, no un wrapper delgado. Emisión, recepción y la capa tributaria están todas aquí.

Ejecución directa, con una salida de emergencia para quien la quiera. El paso de aprobación de herramientas del propio cliente MCP es el humano en el ciclo por defecto. Las empresas que quieran más pueden encender un doble paso borrador-y-confirmación.

Ser AI-first es resolver ambigüedad, no rechazarla. draft_document acepta un receptor por nombre e ítems en prosa, porque así le habla una persona a un agente, y es trabajo de la superficie de herramientas volver eso exacto antes de que se firme nada.

Conectar Claude

En Claude: Settings → Connectors → Add custom connector, apuntando a https://mcp.facturia.cl/mcp.

El cliente descubre los endpoints de OAuth solo (RFC 9728), se registra solo (RFC 7591) y abre la pantalla de consentimiento. No hay configuración y no hay un secreto que copiar y pegar en un archivo.

Registro dinámico de cliente. Cualquier cliente MCP se registra en la primera conexión — sin aprobación previa, sin lista blanca de aplicaciones. El registro devuelve un client_id público; no hay client_secret, porque PKCE es el mecanismo de confidencialidad de un cliente público que no puede guardar un secreto.

POST https://mcp.facturia.cl/register        (RFC 7591)
GET  https://mcp.facturia.cl/.well-known/oauth-authorization-server

Autorización y consentimiento. Flujo estándar de authorization-code + PKCE. La pantalla de consentimiento no es un timbre de goma: ahí decides qué credencial de Facturia queda envuelta en el grant.

GET https://mcp.facturia.cl/authorize
  ?client_id=mcpc_01K2SC9X4M
  &redirect_uri=https://claude.ai/api/mcp/auth_callback
  &response_type=code
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
  &scope=documents:read documents:write tax:read
  &state=af0ifjsldkj

Token. POST /token cambia el código (con el verificador PKCE) por un access token de vida corta y un refresh token de vida más larga, revocable individualmente.

{
  "access_token": "mcpat_9lQpV3fA2mKcRt7wZxYb1Nde",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "mcprt_qT8vN2wLmR5xKpJ7hYdCbA3s",
  "scope": "documents:read documents:write tax:read"
}

Qué carga el token

El mismo modelo de autorización que una llave de API, porque debe comportarse igual una vez emitido:

  • una cuenta,
  • un modo — el token puede ser solo-sandbox, live o mixto, según lo que se concedió;
  • un conjunto de scopes, con el mismo vocabulario que los scopes REST (documents:read, documents:write, received:read, received:write, tax:read, tax:write, empresas:read);
  • una lista blanca de empresas — RUT explícitos, o "*".

Nombrar la empresa en una llamada de herramienta

La lista de un token puede abarcar varias empresas (el agente de un contador que lleva varios clientes, digamos), así que cada herramienta con alcance de empresa toma un argumento empresa explícito — el análogo directo del header Facturia-Empresa.

SituaciónComportamiento
Omitido donde se requiereLa herramienta devuelve empresa_required
Presente pero fuera de la listaempresa_not_allowed — nunca un «no encontrado» a secas
Un token con exactamente una empresaPuedes omitirlo; el servidor lo rellena
Herramientas de nivel cuenta (list_empresas, get_usage sin empresa)Rechazan el argumento

El límite del sandbox

Trampa

Un grant de sandbox es una capacidad, no una política

Un token con alcance de sandbox no puede alcanzar los datos de una empresa live ni emitir nada con efecto legal. No es una preferencia que se pueda cambiar en caliente: es un límite estructural.

Por eso es el default correcto para cualquier cosa exploratoria o de cara al público. El registro dinámico de cliente significa que el software que llama no está verificado por construcción, y el alcance del token es la defensa principal contra un agente comprometido o demasiado confiado.

La pantalla de consentimiento defiende lo mismo desde el otro lado: no viene nada premarcado. Eliges explícitamente qué empresas puede tocar este agente. Conceder "*" es posible pero exige un clic extra de confirmación — la asimetría es intencional, porque un grant a un agente de terceros demasiado confiado es un riesgo materialmente distinto de una llave de API de primera parte guardada en tu propio backend.

Revocación

El panel lista cada cliente MCP conectado bajo «Connected apps», al lado de las llaves de API. Revocar uno invalida de inmediato sus access y refresh tokens — la misma garantía, la misma superficie, el mismo efecto instantáneo que revocar una llave de API.

Límites de tasa

Las llamadas MCP pegan a los mismos servicios de backend que las REST y comparten los mismos buckets publicados. No hay cuota MCP separada, porque no hay un pipeline de emisión separado por debajo.

BucketLímiteQué herramientas
General300 req/mindraft_document, todas las list_* / get_*, query_rcv, get_periodo_summary
Emisión10 req/s, ráfaga 30emit_document, emit_tipo46
Declaración F2910 req/min por empresafile_f29
Artefactos60 req/minget_document_file (el minteo de la URL firmada, no la descarga posterior, que es pública y no medida)

Una llamada limitada devuelve el tipo rate_limit_error con un campo retry_after_seconds sobre el que un agente puede actuar directamente.

En esta página