¿Puedo hacer que un agente de IA emita facturas en Chile? Cómo hacerlo con MCP o tool calling
Sí: un agente de IA puede emitir facturas electrónicas válidas ante el SII si se conecta a un facturador con API o servidor MCP. Te explicamos los dos caminos, con código, y las reglas para que nunca emita algo que no aprobaste.
· Antonio Gil
Sí, puedes hacer que un agente de IA emita facturas electrónicas en Chile, y la factura es tan válida como cualquier otra ante el SII. El agente no timbra nada por su cuenta: lo que hace es llamar herramientas de un facturador que ya emite al SII, ya sea un facturador de mercado o uno integrado al facturador gratuito del SII. Hay dos formas de conectarlo: un servidor MCP (para asistentes como Claude, ChatGPT o Cursor) o tool calling sobre una API REST (para un agente que vive dentro de tu producto). En los dos casos la regla de oro es la misma: el agente prepara un borrador y una persona confirma antes de emitir, porque un DTE emitido no se borra; solo se corrige con una nota de crédito.
En esta guía vemos los dos caminos con código real, usando Tupana como ejemplo, y las reglas de seguridad que aplican a cualquier proveedor.
Qué significa que "un agente emita una factura"
Conviene separar tres capas, porque cada una tiene un responsable distinto:
- El modelo de lenguaje (Claude, GPT, Gemini, Grok u otro) entiende el pedido ("factúrale a este RUT tres horas de asesoría") y decide qué herramienta llamar con qué datos.
- Las herramientas son funciones que un sistema expone: buscar un contribuyente por RUT, crear un borrador, generar la vista previa, emitir.
- El facturador arma el DTE en el formato del SII, lo firma, le asigna folio y lo envía. Es el que responde ante el SII por la parte técnica.
La responsabilidad tributaria sigue siendo de la empresa emisora, igual que si la factura la hubiera hecho una persona desde el portal del SII. Por eso el diseño importa: un agente bien construido nunca debería poder emitir sin que alguien con autoridad lo apruebe.
Los dos caminos: MCP o tool calling
| Servidor MCP | Tool calling sobre la API REST | |
|---|---|---|
| Para qué sirve | Un asistente que opera en nombre de una persona (Claude, ChatGPT, Cursor, Claude Code, VS Code) | Un agente propio dentro de tu SaaS, ERP o backend |
| Quién define las herramientas | El proveedor del servidor MCP | Tú, a partir de la referencia de la API |
| Autenticación | OAuth con la cuenta del usuario, sin copiar API keys | API key guardada en tu backend |
| Confirmación antes de emitir | Viene incluida en el servidor | La programas tú |
| Tiempo para tener algo andando | Minutos | Uno o pocos días, según tu producto |
| Cuándo elegirlo | Tu equipo quiere facturar conversando con su asistente | Tus usuarios facturan desde tu producto y quieres un copiloto ahí |
No son excluyentes. Muchos equipos parten con MCP para validar los casos de uso y después construyen el agente propio con tool calling cuando saben exactamente qué necesita su producto.
Camino 1: conectar un asistente por MCP
MCP (Model Context Protocol) es un estándar abierto para que un asistente de IA descubra y llame herramientas de un servicio externo. El servidor MCP de Tupana es remoto, está publicado en el registro oficial de servidores MCP como io.github.tupana-ai/tupana y su código de configuración está en github.com/tupana-ai/tupana-mcp.
- URL:
https://mcp.tupana.ai/mcp - Transporte: Streamable HTTP.
- Autenticación: OAuth 2.1 con PKCE y registro dinámico de clientes. El asistente te abre el navegador, inicias sesión en Tupana y autorizas. No copias ninguna API key.
- Alcance: cada usuario ve solo las empresas a las que tiene acceso en Tupana.
Paso 1: agregar el servidor
En Claude (claude.ai o Claude Desktop): Settings → Connectors → Add custom connector, con nombre Tupana y la URL de arriba.
En Claude Code:
claude mcp add --transport http tupana https://mcp.tupana.ai/mcp
En Cursor (~/.cursor/mcp.json) o en VS Code (.vscode/mcp.json, con "type": "http"):
{
"mcpServers": {
"tupana": { "url": "https://mcp.tupana.ai/mcp" }
}
}
En ChatGPT, se agrega como conector en modo desarrollador (Settings → Apps & Connectors), con la misma URL y autenticación OAuth, según lo que permita tu plan.
Paso 2: pedir la factura en lenguaje natural
Hazle una factura a 76.123.456-7 por 3 horas de asesoría a $45.000 + IVA, con referencia a la OC 4500123. Muéstrame el borrador antes de emitir.
Paso 3: qué hace el agente por debajo
El servidor de Tupana está diseñado con borrador primero: ninguna herramienta que crea documentos emite al SII. La secuencia típica es:
| Paso | Herramienta | Qué pasa |
|---|---|---|
| 1 | enrich_client_from_rut |
Trae razón social, giro y direcciones del receptor desde el SII. El modelo no los inventa. |
| 2 | create_sale_invoice |
Crea un borrador de factura afecta (33) o exenta (34), con sus referencias. No usa folio ni envía nada al SII. |
| 3 | get_document_preview |
Genera la vista previa en PDF para que la revises. |
| 4 | emit_document |
Emite al SII el borrador ya revisado. Rechaza borradores a los que no se les generó vista previa. |
Si en el paso 3 ves un error (un monto, una referencia), se lo dices al asistente y corrige el borrador. Recién cuando dices que sí, llama a emit_document. El reenvío por correo (send_document_email) también pide confirmación explícita.
El mismo servidor sirve para el resto del ciclo: get_pending_invoices para ver quién te debe, create_credit_note para anular con nota de crédito, get_reconciliation_suggestions y reconcile_movement para conciliar el banco, y get_f29_summary para revisar el IVA del mes. Para la lista vigente, pídele al asistente que llame a list_capabilities.
Más detalle por cliente en la página del servidor MCP y en la guía de conexión de docs.tupana.ai.
Camino 2: tu propio agente con tool calling
Si el agente vive dentro de tu producto, el modelo no habla directo con Tupana: tu backend define las herramientas, el modelo decide cuál usar y tu código ejecuta la llamada real a la API. Así la API key nunca entra al prompt y la regla de confirmación vive en código, no en una instrucción que el modelo podría ignorar.
Paso 1: define las herramientas
Este formato (JSON Schema) lo aceptan los principales proveedores de modelos y frameworks de agentes. Fíjate en que preparar y emitir son herramientas separadas:
[
{
"name": "buscar_contribuyente",
"description": "Busca una empresa chilena por RUT y devuelve razón social, actividades y direcciones. Úsala antes de facturar a un receptor nuevo; nunca inventes estos datos.",
"input_schema": {
"type": "object",
"properties": { "rut": { "type": "string", "description": "RUT con guion, ej. 76123456-7" } },
"required": ["rut"]
}
},
{
"name": "preparar_factura",
"description": "Arma el borrador de una factura y devuelve un resumen para que el usuario lo revise. NO emite nada.",
"input_schema": {
"type": "object",
"properties": {
"dte_type": { "type": "string", "enum": ["33", "34", "39", "41", "61"] },
"issuer_rut": { "type": "string" },
"receiver_rut": { "type": "string" },
"receiver_name": { "type": "string" },
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"item_name": { "type": "string" },
"quantity": { "type": "number" },
"unit_price": { "type": "number", "description": "Precio unitario neto en pesos" }
},
"required": ["item_name", "quantity", "unit_price"]
}
},
"external_id": { "type": "string", "description": "Id de tu pedido; se usa como clave de idempotencia" }
},
"required": ["dte_type", "issuer_rut", "receiver_rut", "items", "external_id"]
}
},
{
"name": "emitir_factura",
"description": "Emite al SII un borrador ya confirmado por el usuario en este turno.",
"input_schema": {
"type": "object",
"properties": {
"draft_id": { "type": "string" },
"user_confirmed": { "type": "boolean" }
},
"required": ["draft_id", "user_confirmed"]
}
}
]
Paso 2: ejecuta las herramientas en tu backend
Ejemplo en Python con requests. La emisión usa POST https://api.tupana.ai/v2/documents/batch/, que acepta hasta 500 documentos por llamada y responde de forma asíncrona:
import os
import requests
TUPANA = "https://api.tupana.ai/v2"
HEADERS = {"Authorization": f"Api-Key {os.environ['TUPANA_API_KEY']}"}
def run_tool(name: str, args: dict, ctx) -> dict:
if name == "buscar_contribuyente":
res = requests.get(f"{TUPANA}/master-entities/", params={"rut": args["rut"]}, headers=HEADERS)
return res.json()
if name == "preparar_factura":
draft = ctx.drafts.save(args) # tu base de datos
net = sum(i["quantity"] * i["unit_price"] for i in args["items"])
return {"draft_id": draft.id, "neto": net, "aviso": "Pide confirmación antes de emitir."}
if name == "emitir_factura":
# La regla vive en el código: sin confirmación registrada, no se emite.
if not args["user_confirmed"] or not ctx.user_confirmed(args["draft_id"]):
return {"error": "Falta la confirmación del usuario."}
d = ctx.drafts.get(args["draft_id"])
res = requests.post(
f"{TUPANA}/documents/batch/",
headers={**HEADERS, "Idempotency-Key": d.external_id, "X-Use-Defaults": "true"},
json={"documents": [{
"dte_type": {"code": d.dte_type},
"document_issuer": {"rut": d.issuer_rut},
"document_receiver": {"rut": d.receiver_rut, "business_name": d.receiver_name},
"details": d.items,
"json_param": {"external_order_id": d.external_id},
}]},
)
return {"status": res.status_code, "body": res.json()}
return {"error": f"Herramienta desconocida: {name}"}
ctx.user_confirmed() es tu propia verificación: por ejemplo, que el usuario haya apretado un botón "Emitir" en tu interfaz para ese borrador, no solo que el modelo diga que confirmó.
Paso 3: escucha el resultado por webhook
La emisión es asíncrona: la API acepta el lote al tiro y el resultado del SII llega después. En vez de que el agente consulte en un ciclo, registra un webhook con los eventos document.issued, document.rejected y document.issue_failed, verifica la firma HMAC-SHA256 del header X-Pana-Signature y retoma la conversación con ese evento ("Tu factura 1234 fue aceptada por el SII"). La guía completa está en docs.tupana.ai/guias/webhooks.
Paso 4: prueba todo en sandbox
Las API keys nuevas de Tupana nacen en modo sandbox: la emisión se simula, el folio tiene la forma SANDBOX-{n} y nada se envía al SII. Es el lugar para correr las evaluaciones de tu agente (cientos de conversaciones de prueba) antes de tocar producción. Puedes crear una key gratis en developers.tupana.ai y seguir el quickstart.
Si prefieres no escribir las llamadas HTTP a mano, los SDKs oficiales de Tupana hacen lo mismo con reintentos e Idempotency-Key incluidos: npm install tupana para Node.js (npm) y pip install tupana para Python (PyPI). Con el SDK de Python, la llamada HTTP de emitir_factura queda en tupana.documents.create_batch([invoice], use_defaults=True, idempotency_key=d.external_id). En tupana-examples hay un agente de ejemplo que factura pidiendo confirmación.
Las 7 reglas para que un agente facture sin sustos
- Separa preparar de emitir. Dos herramientas distintas, siempre. El borrador es gratis y reversible; la emisión no.
- La confirmación vive en código. Una instrucción en el prompt ("no emitas sin preguntar") ayuda, pero no basta. Tu backend debe rechazar la emisión si no hay una aprobación registrada.
- Idempotencia en cada emisión. Los modelos reintentan. Manda
Idempotency-Keyderivada de algo estable (tu id de pedido), no un valor aleatorio por intento. Si la llamada se repite, recibes el mismo lote sin emitir dos veces. - Datos del contribuyente desde el RUT, no desde el modelo. Razón social, giro y dirección se consultan; un modelo que "completa" una dirección inventa.
- Montos netos y cálculo en el facturador. Pásale precios netos y deja que el facturador calcule IVA y totales. Los modelos no son calculadoras confiables.
- Permisos mínimos. Un agente que solo responde preguntas no necesita poder emitir. Usa API keys con el alcance justo y una key por agente o entorno.
- Registro de todo. Guarda quién pidió qué, qué borrador se generó y quién lo aprobó. Si algo sale mal, necesitas reconstruirlo.
Qué puede salir mal y cómo evitarlo
| Riesgo | Qué lo evita |
|---|---|
| El agente emite dos veces la misma factura | Idempotency-Key estable por operación |
| Factura a un RUT equivocado | Búsqueda por RUT + vista previa con razón social antes de confirmar |
| Monto mal calculado | Precios netos, IVA calculado por el facturador, total visible en la vista previa |
| Prompt injection (un PDF o correo con instrucciones ocultas) | La emisión exige confirmación humana registrada en tu sistema, no en el texto |
| El agente "se queda esperando" al SII | Webhooks en vez de consultas en ciclo |
| Pruebas que terminan en el SII | Sandbox para evaluaciones; producción solo con keys separadas |
Si a pesar de todo se emite algo incorrecto, se corrige igual que siempre: con una nota de crédito que referencia la factura original.
¿Y con otros proveedores?
El patrón de tool calling funciona con cualquier facturador que tenga API REST: defines las herramientas, tu backend llama al proveedor y aplicas las mismas siete reglas. La diferencia está en cuánto trabajo te ahorra el proveedor: si tiene sandbox real, idempotencia, webhooks firmados y un servidor MCP con borrador primero, la integración es mucho más corta. Para comparar opciones con esos criterios, revisa nuestra comparativa de APIs de facturación electrónica en Chile.
Cuánto cuesta
Probar no cuesta nada: el sandbox de Tupana es gratis e incluye APIs, MCP y webhooks de prueba. En producción, la API de facturación para developers cuesta 0,5 UF al mes por empresa que enroles (hasta 100 documentos o 1.000 boletas al mes por empresa), con el facturador de mercado de Tupana o con el facturador gratuito del SII, al mismo precio. El detalle está en docs.tupana.ai/precios. Si en cambio tu empresa factura desde la plataforma web, los planes están en la sección de precios.
Preguntas frecuentes
¿Es legal que una IA emita facturas en Chile?
Sí. El SII no exige que una persona apriete el botón: exige que el documento sea un DTE válido, emitido por un contribuyente autorizado. El agente es una herramienta más, como un ERP o una planilla. La responsabilidad tributaria sigue siendo de la empresa emisora, por eso conviene que una persona apruebe cada emisión.
¿El agente necesita mi clave del SII o mi certificado digital?
No en el prompt. Las credenciales quedan en el facturador: con el facturador gratuito del SII, la empresa conecta su clave tributaria una vez; con un facturador de mercado, el facturador gestiona la firma y los folios. El agente solo recibe acceso a las herramientas, con OAuth (MCP) o con una API key guardada en tu backend (tool calling).
¿Qué asistentes funcionan con el servidor MCP de Tupana?
Cualquiera con soporte de MCP remoto (Streamable HTTP y OAuth 2.1): Claude (claude.ai, Claude Desktop y Claude Code), ChatGPT en modo desarrollador, Cursor y VS Code con GitHub Copilot, entre otros. Si tu cliente solo soporta stdio, se puede usar un puente como mcp-remote.
¿Puede el agente emitir sin que yo confirme?
Con el servidor MCP de Tupana, no: las herramientas que crean documentos solo crean borradores, y emit_document exige que antes se haya generado la vista previa. Con tool calling, depende de cómo lo programes; por eso la confirmación debe verificarse en tu backend y no solo en el prompt.
¿Qué pasa si el agente se equivoca en una factura ya emitida?
Se corrige igual que cualquier factura: con una nota de crédito (tipo 61) que referencia el documento original, ya sea para anularlo o para corregir montos. El mismo agente puede prepararla con create_credit_note, y también debería pasar por tu confirmación.
¿Puedo probar sin emitir documentos reales?
Sí. Las API keys nuevas de Tupana nacen en sandbox: la emisión se simula, el folio es SANDBOX-{n} y nada llega al SII. El sandbox es gratis e incluye el servidor MCP y webhooks de prueba.
¿Sirve para boletas y notas de crédito, o solo facturas?
La API emite facturas afectas y exentas, boletas, notas de crédito y débito, guías de despacho, facturas de compra y documentos de exportación, entre otros. Por MCP están disponibles hoy los borradores de factura afecta y exenta, factura de compra, factura de exportación y nota de crédito.
¿Qué modelo de IA conviene usar?
Cualquier modelo actual con buen soporte de tool calling funciona; la calidad depende más del diseño de las herramientas que del modelo. Lo que sí importa es que la emisión no dependa del criterio del modelo: borrador primero, confirmación en código e idempotencia.
Empieza hoy
Si quieres probarlo en cinco minutos, conecta https://mcp.tupana.ai/mcp a tu asistente y pídele un borrador. Si vas a construir tu propio agente, crea una key de sandbox en developers.tupana.ai y sigue la guía de agentes de IA en docs.tupana.ai. Y si te trabas, el soporte de Tupana es un grupo de WhatsApp con tu equipo, respondido por personas.