Siigo MCP
Servidor MCP (Model Context Protocol) remoto que conecta la API pública de Siigo Colombia con cualquier cliente MCP estándar — Claude, ChatGPT, u otros. Corre como un Cloudflare Worker sin estado, expone 28 herramientas (lectura, escritura y analítica de negocio) y nunca expone las credenciales de Siigo al modelo ni al cliente.
No hay lógica específica de Claude ni de ChatGPT: es un servidor MCP estándar sobre Streamable HTTP, servido en /mcp.
Qué es este MCP
- Traduce llamadas MCP (
tools/call) a llamadas REST autenticadas contraapi.siigo.com. - Cubre clientes, productos, facturas de venta, compras, cotizaciones, recibos de caja, comprobantes contables y un set de tools de inteligencia de negocio (resúmenes de ventas/compras/cartera/inventario/financiero).
- Las credenciales de Siigo (
SIIGO_USERNAME,SIIGO_ACCESS_KEY) viven únicamente como Cloudflare Secrets; ninguna tool las devuelve, registra ni expone. - Ver
TOOLS.mdpara la tabla completa de herramientas.
Arquitectura
Cliente MCP (Claude / ChatGPT / otro)
│ Streamable HTTP
▼
https://<tu-worker>.workers.dev/mcp
│
▼
src/index.ts → src/server.ts → src/tools/*.ts → src/siigo/*.ts → src/siigo/client.ts
│
▼
Cloudflare Secrets
(SIIGO_USERNAME, SIIGO_ACCESS_KEY)
│
▼
api.siigo.com
src/
├── index.ts # Worker entrypoint: solo wiring (createMcpHandler)
├── server.ts # construye el McpServer y registra todos los grupos de tools
├── siigo/
│ ├── auth.ts # POST /auth + cache en memoria del access_token, renovación automática
│ ├── client.ts # cliente HTTP centralizado: headers, query, JSON, errores
│ ├── types.ts # tipos de dominio (Customer, Product, Invoice, Purchase, Quotation, Voucher, Journal)
│ ├── customers.ts # GET/POST /v1/customers
│ ├── products.ts # GET/POST /v1/products
│ ├── invoices.ts # GET/POST /v1/invoices
│ ├── purchases.ts # GET /v1/purchases
│ ├── quotations.ts # GET/POST /v1/quotations
│ ├── receipts.ts # GET/POST /v1/vouchers (recibos de caja)
│ └── accounting.ts # GET/POST /v1/journals (comprobantes contables)
├── tools/
│ ├── customers.ts, products.ts, invoices.ts, purchases.ts,
│ ├── quotations.ts, receipts.ts, accounting.ts # registro de tools MCP (Zod + descripciones)
│ └── analytics.ts # tools de inteligencia de negocio (resúmenes)
└── utils/
├── pagination.ts # schema de paginación + recorrido multi-página con tope
└── errors.ts # SiigoApiError + formateo seguro de errores para el LLM
Cada siigo/*.ts es una función pura contra la API (no sabe nada de MCP). Cada tools/*.ts traduce input MCP (validado con Zod) → llamada a siigo/*.ts → texto + structuredContent. server.ts es el único punto que ensambla todo.
Instalación
git clone <este repo>
cd siigo-mcp
npm install
Requiere Node.js reciente (usado con Node 24) y una cuenta de Cloudflare con Wrangler autenticado (npx wrangler login).
Desarrollo local
Crea un archivo
.env(o.dev.vars, ambos están en.gitignore) con las credenciales de Siigo solo para tu entorno local:SIIGO_USERNAME=tu_usuario_de_siigo SIIGO_ACCESS_KEY=tu_access_keyLevanta el Worker localmente:
npm run devEl MCP queda disponible en
http://localhost:8787/mcp(o el puerto que Wrangler asigne). Puedes probarlo con cualquier cliente MCP compatible con Streamable HTTP, o concurldirectamente:curl -s -X POST http://localhost:8787/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
Nunca subas .env/.dev.vars al repositorio (ya están en .gitignore) ni pegues su contenido en chats, tickets o documentación compartida fuera de la cuenta corporativa aprobada de BBLABS.
Variables y Secrets
| Nombre | Tipo | Dónde vive | Descripción |
|---|---|---|---|
SIIGO_USERNAME |
Secret | Cloudflare Secret / .env local |
Usuario de la API de Siigo. Nunca se loguea ni se devuelve. |
SIIGO_ACCESS_KEY |
Secret | Cloudflare Secret / .env local |
Access key de la API de Siigo. Nunca se loguea ni se devuelve. |
SIIGO_PARTNER_ID |
Variable pública | wrangler.jsonc (vars) |
Identificador de la integración (mcpclaude). No es sensible, se envía en cada request a Siigo. |
Para configurar los secrets en producción (una sola vez, o cuando roten):
npx wrangler secret put SIIGO_USERNAME
npx wrangler secret put SIIGO_ACCESS_KEY
SIIGO_PARTNER_ID ya está declarado en wrangler.jsonc bajo vars y no requiere wrangler secret put.
Despliegue
npm run typecheck # tsc --noEmit
npm test # vitest run
npm run deploy # wrangler deploy
Tras el primer despliegue (o si cambias bindings/vars en wrangler.jsonc), regenera los tipos de Workers:
npm run cf-typegen # wrangler types
El Worker queda publicado en https://<nombre-del-worker>.<tu-subdominio>.workers.dev/mcp (Streamable HTTP, endpoint /mcp).
Herramientas disponibles
Ver la tabla completa en TOOLS.md. Resumen por dominio:
- Clientes: listar, buscar, obtener, crear.
- Productos: listar, buscar, obtener, crear.
- Facturas de venta: listar, obtener, crear.
- Compras: listar, obtener.
- Cotizaciones: listar, obtener, crear.
- Recibos de caja: listar, obtener, crear (ver nota de confiabilidad en
TOOLS.md). - Comprobantes contables: listar, obtener, crear.
- Analítica: resumen de ventas, resumen de compras, resumen de cartera, consulta de inventario, resumen financiero.
- Diagnóstico:
siigo_auth_test.
Ejemplos de uso
Una vez conectado el MCP a un cliente compatible, puedes pedirle en lenguaje natural, por ejemplo:
- "Busca el cliente con NIT 900123456 en Siigo." → usa
siigo_buscar_cliente. - "Dame el resumen de ventas de enero 2026 comparado con diciembre 2025." → usa
siigo_resumen_ventasconfecha_inicio_comparacion/fecha_fin_comparacion. - "¿Qué productos tienen menos de 3 unidades disponibles?" → usa
siigo_consultar_inventarioconumbral_stock_bajo: 3. - "Crea una cotización para el cliente 900123456 con 2 unidades del producto SKU-1 a 50000 cada una." → usa
siigo_crear_cotizacion. El modelo debe reunir explícitamentedocument_id(tipo de documento), fecha, identificación del cliente e items antes de ejecutar la tool.
Las tools de escritura (siigo_crear_*) están descritas para que el modelo nunca las ejecute con información ambigua o incompleta — Zod rechaza la llamada si falta un campo obligatorio de Siigo.
Conexión con Claude
- En Claude (Claude.ai, Claude Desktop o Claude Code), agrega un servidor MCP remoto apuntando a:
https://<tu-worker>.workers.dev/mcp - No se requiere configuración de autenticación adicional del lado del cliente: las credenciales de Siigo están únicamente en el Worker (Cloudflare Secrets), nunca en el cliente MCP.
- Claude descubrirá las 28 tools automáticamente vía
tools/list.
Conexión con ChatGPT
- En la configuración de conectores/MCP de ChatGPT, agrega un conector remoto con la misma URL:
https://<tu-worker>.workers.dev/mcp - El servidor usa Streamable HTTP estándar (sin sesión obligatoria,
legacy: "stateless"por defecto enagents/mcp/server), compatible con la forma en que ChatGPT invoca servidores MCP remotos. - Igual que con Claude, no hay credenciales que configurar del lado de ChatGPT.
Seguridad
- Las credenciales de Siigo (
SIIGO_USERNAME,SIIGO_ACCESS_KEY) solo existen como Cloudflare Secrets (producción) o en.env/.dev.varslocal (ambos en.gitignore); nunca se hardcodean ni se commitean. - Ninguna tool devuelve
access_key,access_token,usernameni headers de autenticación. Elaccess_tokense cachea en memoria del Worker (por isolate, no persistente) y se renueva automáticamente antes de expirar; nunca sale desrc/siigo/auth.ts. - Los errores de Siigo se traducen con
src/utils/errors.tsa mensajes tipo"Siigo rechazó la solicitud. Código: <status>. Detalle: <detalle>", sin incluir secretos ni headers. - Las tools de escritura son explícitas: exigen todos los campos obligatorios de Siigo (sin adivinar valores) y sus descripciones advierten que crean documentos reales e irreversibles.
siigo_crear_facturanunca timbra ante la DIAN ni envía correo salvo que se indiqueenviar_a_dian/enviar_por_emailcomotrueexplícitamente.siigo_crear_comprobante_contablevalida que la partida cuadre (débito = crédito) antes de enviarla a Siigo. - Al trabajar con datos reales de clientes (nombres, identificaciones, correos, teléfonos) obtenidos vía este MCP, sigue las políticas de BBLABS: usa solo la cuenta corporativa aprobada, minimiza los datos que compartes fuera del MCP, y anonimiza/resumes antes de pegar resultados en canales o documentos que no sean estrictamente necesarios.
Troubleshooting
Siigo rechazó la solicitud. Código: 401...: revisa queSIIGO_USERNAME/SIIGO_ACCESS_KEYestén correctamente configurados como secrets (npx wrangler secret put ...) y que el usuario de Siigo tenga permisos de API habilitados.Siigo rechazó la solicitud. Código: 404...ensiigo_obtener_*: el ID (UUID) no existe o pertenece a otro tipo de documento. Usa primero la toolsiigo_listar_*/siigo_buscar_*correspondiente.Siigo rechazó la solicitud. Código: 500/503/504...: en pruebas, Siigo devolvió ocasionalmente errores transitorios de servidor (p. ej.document_query_serviceno disponible); reintenta la operación. Parasiigo_listar_recibos_caja/siigo_obtener_recibo_caja, un 500 puede indicar que ese endpoint de lectura simplemente no está soportado de forma confiable por la API pública (verTOOLS.md).- El cliente MCP no ve las tools: confirma que el endpoint termina en
/mcpy que el cliente haceinitializeantes detools/list(algunos clientes lo hacen automáticamente). - Cambié
wrangler.jsoncy los tipos no reflejan el cambio: correnpm run cf-typegen. - Necesito confirmar un endpoint/parámetro de Siigo que no está en este README: consulta la documentación oficial en
https://developers.siigo.com/docs/siigoapi/antes de asumir el shape de un payload; varios recursos de esta integración (compras, recibos de caja) tienen partes no documentadas públicamente y están anotadas como tales enTOOLS.mdy en los comentarios desrc/siigo/*.ts.