Notta Docs

Servidor MCP

Conecta tu agente LLM al servidor MCP remoto de Notta por HTTP, dos herramientas sobre un catálogo de 31 operaciones, con OAuth, techo por empresa y aprobación humana

Notta expone un servidor MCP (Model Context Protocol) remoto en https://app.notta.cl/api/mcp. Es un solo servidor, por HTTP streamable, con OAuth: no hay paquete que instalar ni API key que pegar en un archivo de configuración.

El catálogo son 31 operaciones: veinticuatro de consulta y siete detrás de un permiso de escritura: emitir documentos tributarios, dejar un documento preparado como borrador para que alguien lo revise, acusar o reclamar las facturas de tus proveedores ante el SII, destrabar un documento cuyo seguimiento ante el SII se detuvo, reenviarle a tu cliente uno que ya emitiste, y guardar o corregir una contraparte de tu catálogo. Esos permisos vienen apagados de fábrica: los enciende tu empresa en /app/mcp y quien conecta la app tiene que marcar su casilla al autorizar.

Las siete no se gobiernan igual, y la diferencia importa. Un documento que emite tu agente sale directo si está bajo el umbral que fijes; un acuse o un reclamo lo apruebas siempre, sin umbral y sin excepción, porque no se deshace: dado un acuse ya no se puede reclamar, y una factura aceptada que tu proveedor cede a factoring no se corrige con una nota de crédito. Destrabar un documento no pasa por ningún umbral ni por aprobación: no crea ni cambia nada, solo vuelve a preguntarle el estado al Servicio. Preparar un borrador tampoco: crea una fila en tus borradores y nada más, sin folio, sin llegar al SII y sin avisarle a nadie, y después sigue haciendo falta que alguien lo emita. Reenviar tampoco: manda otra vez, al mismo destino que Notta ya resolvió, un documento que ya existe. Esas tres comparten el permiso dte:write con la emisión, así que hoy no se pueden conceder por separado.

Mantener el catálogo de contrapartes es la excepción del grupo: tiene permiso propio (empresas:write), no sale de Notta y no crea ningún documento. Sirve para que el agente que te acaba de facturar a un cliente nuevo lo GUARDE, en vez de que se lo dictes otra vez la próxima. Y llega hasta ahí: por este canal no puede tocar el correo al que le llegan los documentos de esa contraparte (ese correo decide a dónde va cada factura que le emitas) ni borrarla del catálogo. Las dos cosas se hacen desde /app/empresas.

Conéctalo

Con Claude Code:

claude mcp add --transport http notta https://app.notta.cl/api/mcp

En claude.ai: Ajustes → Conectores → Agregar conector personalizado, y pega esa misma URL. En ChatGPT, Ajustes → Conectores en modo desarrollador. Cualquier otro cliente con HTTP streamable y OAuth (Cursor, Gemini CLI) usa la URL tal cual.

Al conectar por primera vez, tu agente pide autorización OAuth, y lo que esa conexión se lleva lo decides tú en la pantalla de consentimiento. Puede leer: tus documentos (DTE) y su estado, y generar un enlace de 15 minutos a su PDF o a su XML firmado (sin sesión, para reenviarlo o cederlo); en qué quedaron las emisiones que dejaste esperando aprobación (si se aprobaron, si se rechazaron y por qué, o si vencieron); el historial de tus documentos de venta recientes, para prellenar uno nuevo; tus folios (CAF); tu Registro de Compras y Ventas (RCV); tu bandeja de compras por Casilla de Intercambio con sus plazos; el perfil de tu empresa y sus sucursales del SII, tu estado de certificación ante el SII y tu catálogo de contrapartes; el inventario de tus certificados digitales (nunca la clave de firma); y tu plan y cuota de uso. La escritura va aparte, en casillas que marcas tú y que solo aparecen si tu empresa la habilitó: emitir documentos tributarios a tu nombre (facturas de venta y de compra, notas de crédito y de débito, guías de despacho y facturas de exportación); sobre el umbral que fije tu empresa, cada documento espera la aprobación de una persona. Y acusar recibo o reclamar las facturas de tus proveedores ante el SII; cada acción la aprueba una persona antes de registrarse, porque son irreversibles y excluyentes entre sí. La casilla de emisión concede además destrabar un documento cuyo seguimiento ante el SII se detuvo: Notta vuelve a preguntarle el estado al Servicio. No crea documentos ni cambia ninguno, y no espera aprobación porque no hay nada que aprobar. Y preparar documentos y dejarlos como borrador para que los revises antes de emitir; un borrador no tiene folio, no llega al SII y no le avisa a nadie, y sigue haciendo falta que alguien lo emita. Y reenviarle a tu cliente un documento que ya emitiste, al correo que Notta ya tiene resuelto para él; no crea ningún documento, no cambia el que se manda, y por este canal no se puede elegir otra dirección. En su propia casilla, aparte de la de emisión, va crear y editar las contrapartes de tu catálogo (razón social, giro, dirección, comuna y si es cliente o proveedor), para que tu agente guarde al cliente nuevo en vez de que se lo dictes otra vez; no puede tocar el correo al que le llegan los documentos de esa contraparte ni borrarla del catálogo. Administra o revoca las apps conectadas desde /app/mcp en el dashboard.

La pantalla de consentimiento te dice qué app pide acceso, a qué empresa y a qué dominio van los datos (salen de Notta hacia el proveedor de esa app, que puede procesarlos fuera de Chile), y marca como no verificada a cualquier app que no pueda comprobar. Si administras varias empresas, ahí mismo eliges a cuál conectar la app (una conexión por empresa), sin cancelar ni volver a empezar. Solo se ofrecen las empresas en las que tienes membresía.

Autorización

El servidor implementa OAuth 2.1 con PKCE (S256 obligatorio) y registro dinámico de clientes. Tu cliente MCP descubre los endpoints por metadata; no hay que copiarlos a mano:

MetadataURL
Recurso protegido (RFC 9728)https://app.notta.cl/.well-known/oauth-protected-resource
Servidor de autorización (RFC 8414)https://app.notta.cl/.well-known/oauth-authorization-server
Manifiesto MCPhttps://notta.cl/.well-known/mcp.json

Una solicitud de autorización que pida un permiso que no se puede conceder no se rechaza: se recorta. El grant sale con los permisos que sí correspondían y la respuesta del token declara cuáles son (RFC 6749 §3.3), así que tu cliente siempre sabe con qué se quedó. scope=read sigue siendo válido y significa toda la lectura. El token queda atado a una empresa y al ambiente SII de esa empresa (cert o prod): ningún parámetro del cliente lo cambia.

Los permisos efectivos de cada llamada son la intersección de tres cosas (lo que la app pidió, el techo de la empresa y lo que permite tu rol) y se recalculan en cada petición: bajar el techo en /app/mcp corta la escritura de todas las apps conectadas en la petición siguiente, sin esperar a que expire ningún token. El día que el SII autoriza a tu empresa a emitir en producción, las conexiones MCP de esa empresa se revocan y el techo vuelve a apagarse: hay que reconectar y encenderlo de nuevo, a propósito, sabiendo que ahora los documentos tienen validez tributaria.

El manifiesto es público y sin token: publica el catálogo completo. Lo que un token concreto puede ejecutar depende del permiso que le diste al autorizar. Si tu agente no habla MCP, el corpus de estas docs está en https://notta.cl/llms.txt y /llms-full.txt.

Las dos herramientas

El servidor no expone una tool por endpoint: expone dos, sobre un catálogo de operaciones que se descubre en caliente.

ToolArgumentosQué hace
discover{ operation? }Sin argumentos, devuelve a qué empresa y ambiente SII está conectado tu agente, qué puede y qué no puede hacer (con el porqué y el cómo habilitarlo) y el catálogo de operaciones que tu conexión alcanza. Con operation, el esquema completo de parámetros de esa operación y un ejemplo de llamada.
execute{ operation, params?, body? }Ejecuta una operación del catálogo. params lleva los parámetros de ruta, los filtros y los headers que la operación declara (Idempotency-Key, X-Cert-Id); body, el cuerpo JSON de las que escriben. Todo se valida contra el esquema OpenAPI: una clave no declarada nunca llega a la API.
discover({ operation: "listDtes" })
 
execute({
  operation: "listDtes",
  params: { limit: 10, sort: "fecha_emision", dir: "desc" }
})

Lo que limita a execute es el catálogo, no el verbo: una operación que no está en él no viaja, y el guardia de /api/v1 la vuelve a comparar contra el mismo catálogo con tu token. Emitir se ve así:

execute({
  operation: "emitDte",
  params: { "Idempotency-Key": "0198f2c1-0000-7000-8000-000000000001" },
  body: {
    tipo_dte: 33,
    receptor: { rut: "11111111-1", razon_social: "Cliente Ejemplo SpA" },
    items: [{ nombre: "Consultoría mayo", cantidad: 1, precio_unitario: 650000 }]
  }
})

La Idempotency-Key la pone tu agente, no el servidor. Genera una por documento y reutiliza EXACTAMENTE ese valor si tienes que reintentar: una clave nueva en el reintento no es un reintento, es un segundo documento real ante el SII. discover({ operation: "emitDte" }) publica el esquema completo del cuerpo y de los headers que la operación exige.

También puedes llamar POST /api/v1/dtes directo con el token de la conexión: recibe el mismo guardia, el mismo techo y el mismo umbral. Y si prefieres no encender la escritura por MCP, la API REST con una API key sigue siendo el camino: mismo shape, misma cuenta, pero sin pasar por el techo ni por el panel de aprobación.

Catálogo de operaciones

OperaciónEndpointQué devuelve
listDtesGET /dtesTus DTEs, con limit (máx. 100), sort (folio, monto_total, fecha_emision, sii_status, created_at) y dir
emitDtePOST /dtesLa única operación del catálogo que crea un documento: emite una factura, nota de crédito, nota de débito o guía de despacho. Exige el permiso dte:write y pasa por el gate de abajo
previewDtePOST /dtes/previewLa vista previa antes de emitir: guarda un borrador y devuelve su enlace (/app/dtes/drafts/{id}, con el PDF y el botón para emitirlo) más los montos que calcularía el motor. No firma, no pide folio, no llega al SII y no manda correo. Valida con el MISMO schema que emitDte, así que un 200 aquí significa que la emisión no va a fallar por el payload. Exige dte:write porque crea la fila del borrador
getDteGET /dtes/{id}El detalle de un DTE con sus líneas
getDteEventsGET /dtes/{id}/eventsLa historia de estados SII de ese DTE (queued → sending → EPR/RPR/RFR/RCT/RSC). Este es el endpoint para seguir un documento, no el de abajo
refreshDteStatusPOST /dtes/{id}/refresh-statusLa escotilla para un documento sin veredicto confirmado (stuck, sin_permiso_sii, o un reloj frío de más de 25 h): vuelve a consultarle el estado al SII si tiene Track ID. Sin Track ID responde 409 dte.refresh_status.no_track_id, con next_action: operator_review; revisa sii_glosa y contacta a soporte. Exige el permiso dte:write, el mismo que emitir. Tres respuestas 2xx, y solo una actúa: refresh_enqueued (202). already_terminal (200) significa que el SII ya juzgó el documento (puede ser un rechazo: mira sii_glosa) y poll_in_progress (200) que el seguimiento sigue vivo y trae retry_after en segundos. Llamarlo en bucle no acelera nada
resendDeliveryPOST /dtes/{id}/resend-deliveryReenvía al receptor un documento ya emitido: no crea nada, no pide folio y no toca al SII. Exige dte:write, el mismo permiso que emitir. Por MCP no admite cuerpo, así que el destino lo resuelve Notta (catálogo de contrapartes y casilla de intercambio del receptor) y el agente no puede elegir otra dirección; con una API key clásica sí se puede indicar correo_receptor. El 202 dice que el envío quedó encolado, no que el correo llegó
getDtePdfUrlGET /dtes/{id}/pdf-urlUna URL firmada (vence en 15 minutos) para descargar el PDF sin sesión, para reenviarla a tu cliente
getDteXmlUrlGET /dtes/{id}/xml-urlUna URL firmada (vence en 15 minutos) para descargar el XML firmado sin sesión, para reenviarlo o cederlo
getDteTotalsGET /dtes/totalesConteo y suma (neto/exento/IVA/total) por período, tipo y estado: agregado en SQL, sin el detalle de cada documento
getPendingActionGET /dtes/pendientes/{id}En qué quedó una emisión que el gate dejó esperando: pending, approved (con el DTE resultante), rejected (con el motivo que escribió la persona) o expired
listSiiRecentDocumentsGET /sii/documents/recentTus últimas ventas (33/34) emitidas, para prellenar un documento nuevo
getSiiDocumentTemplateGET /sii/documents/{id}/templateEl detalle de un documento anterior, como plantilla para uno nuevo
listCafGET /cafTus CAF (folios), con folios restantes y aviso de folios bajos
listRcvGET /rcvTu Registro de Compras y Ventas por período, o el detalle de un RUT
listRcvDocumentsGET /rcv/documentsEl mismo registro documento por documento, con el evento del receptor y la referencia de cada NC/ND
listRecepcionGET /recepcionTu bandeja de compras por Casilla de Intercambio, con el plazo de 8 días corridos para acusar o reclamar ya calculado por fila
registrarEventoRecepcionPOST /recepcion/{id}/eventoLa operación que declara algo ante el SII a tu nombre: acusa recibo o reclama una factura de proveedor. Exige el permiso recepcion:write y siempre queda esperando aprobación humana, sin umbral
getProfileGET /profileEl perfil de tu empresa: giro, dirección, comuna, actividad económica y la Unidad del SII que se imprime en el PDF
listSucursalesGET /sucursalesLas sucursales del SII de tu empresa, con el id que se manda como sucursal_id al emitir desde una de ellas. Solo lectura: registrarlas, editarlas o borrarlas no se puede por MCP, porque el código lo entrega el SII y lo copia una persona desde Mi SII
getSiiCertStateGET /sii/cert-stateEl estado de tu proceso de certificación ante el SII
getSiiReadinessGET /sii/readinessEl resumen de aplicabilidad y estado de tu certificación SII
getOnboardingReadinessGET /onboarding/readinessQué le falta a tu empresa para poder emitir
getSuggestedDteTypesGET /onboarding/suggested-typesLos tipos de DTE sugeridos según tu postulación ante el SII
getTiposAutorizadosGET /sii/tipos-autorizadosQué tipos de documento tiene habilitados tu empresa, uno por uno
listEmpresasGET /sii/empresasTu catálogo de contrapartes
getEmpresaGET /sii/empresas/{id}La ficha completa de una contraparte
createEmpresaPOST /sii/empresasGuarda un cliente o proveedor nuevo en tu catálogo, para no volver a dictar sus datos. Exige empresas:write, un permiso propio (no el de emitir). El RUT es la identidad de la fila y no se puede editar después; si ya existe, la respuesta es 409 y lo que corresponde es editarla. El campo correos no viaja por este canal: decide a qué dirección le llega cada documento que le emitas a esa contraparte, así que mandarlo responde 422 empresa.correos_no_editable_por_mcp y no crea nada. Se edita en /app/empresas, o con una API key clásica
updateEmpresaPUT /sii/empresas/{id}Corrige los datos de una contraparte que ya está en tu catálogo. El cuerpo es completo, no un parche: lo que omitas queda vacío. El RUT no se toca. Mismo trato para correos que en createEmpresa, con una diferencia: por MCP omitirlo tampoco los borra, quedan como estaban
listCertificatesGET /certificatesTus certificados digitales vigentes (nunca la clave de firma)
getBillingPlanGET /billing/planPlan activo y cuota del mes

Son 31 operaciones. Para leer un DTE por id, primero lista con listDtes y toma el id de la fila: el mismo usage_hint que devuelve discover, que también trae la regla de corte de más abajo.

Para seguir un documento recién emitido, el camino es getDteEvents (o listDtes filtrando por estado), no refreshDteStatus: la emisión publica un seguimiento durable que lleva el documento a su estado final por su cuenta. refreshDteStatus existe para cuando ese seguimiento se murió, y si está vivo responde poll_in_progress sin consultarle nada al SII. Notta tiene además webhooks salientes (/docs/webhooks), pero sus cinco endpoints están fuera de este catálogo a propósito: registrar una URL de callback redirige el flujo de documentos de la empresa hacia un tercero, y esa es una decisión de infraestructura de la persona que integra, no del agente que consume. Un agente que necesita el estado lo tiene completo por pull. Corta cualquier bucle de espera por estado.terminal, NUNCA por sii_status === "EPR": un rechazo (RFR, RCT, RSC y RCH) también es final, y ese bucle no saldría nunca. stuck, sin_permiso_sii, emision_fallida y envio_repetido no son terminales (no hay un veredicto confirmado en Notta) pero tampoco avanzan solos: stuck y sin_permiso_sii los destraba POST /dtes/{id}/refresh-status si tienen Track ID; sin él, revisa sii_glosa y el documento en el SII, y contacta a soporte; emision_fallida y envio_repetido los resuelve soporte: no tienen Track ID, así que no hay nada que consultar.

Emitir por MCP: el techo, el umbral y la aprobación

Emitir es la escritura que más gobierno necesita del catálogo (es la que crea un documento con valor tributario), y ninguna empresa la tiene encendida sin decidirlo. Tienen que darse las tres cosas a la vez:

  1. El techo de tu empresa, arriba. Un owner o admin enciende «Escritura por MCP» en /app/mcp. Viene apagado; con el techo abajo la casilla ni siquiera aparece al autorizar, y bajarlo corta la escritura de todas las apps conectadas en la petición siguiente.
  2. El permiso, marcado al conectar. Quien autoriza la app marca la casilla de emisión en la pantalla de consentimiento. Sin marcarla, la conexión queda de solo lectura.
  3. El rol de quien autorizó. Un viewer no otorga emisión ni marcando la casilla, y degradar a esa persona corta la escritura de su app.

Con eso puesto, cada emisión pasa por el gate:

SituaciónQué pasa
Ambiente de certificaciónEmite directo: los documentos son de prueba
Producción, monto ≤ tu umbralEmite directo
Producción, monto > tu umbralQueda esperando aprobación humana
Tu empresa pidió revisar todoQueda esperando aprobación humana, siempre
Documento sin monto comparable (guía de traslado interno)Emite directo

El umbral se guarda en UF (no en pesos, para que no proteja cada año un poco menos sin que nadie lo decida) y se compara con el valor del día. Por defecto son 60 UF y un tope de 60 documentos por minuto, ambos configurables en /app/mcp.

Cuando un documento queda esperando, la respuesta trae status: "pending", el pending_id, un approve_url que apunta a /app/mcp/pendientes y el motivo en español. Ese documento no quema folio ni llega al SII: espera hasta 24 horas a que una persona con permiso para emitir lo apruebe o lo rechace desde el dashboard, y vence solo si nadie lo mira. Aprobar dos veces no duplica el documento. Tu agente consulta en qué terminó con getPendingAction: si lo rechazaron, ahí está el motivo que escribió la persona, para corregir y volver a pedirlo.

Lo que un agente todavía no hace por este canal

Por MCP no hay ruta para anular un documento, subir un certificado, pedir o subir folios, ni sincronizar el RCV: leerlos sí, con las operaciones de arriba. La boleta electrónica (39/41) y la boleta de honorarios no están en el catálogo mientras sigan pendientes de certificación ante el SII.

Próximos pasos

  • Agentes: patrones para que tu agente emita con confirmación humana y maneje la emisión async.
  • Emitir Factura 33: el shape completo del request de emisión y los estados SII.
  • Autenticación: API keys, scopes y ambientes cert/prod.
  • Referencia de la API: los endpoints que el catálogo del MCP refleja.

Última actualización

En esta página