Siigo MCP
README.md
# 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 contra `api.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.md`](./TOOLS.md) para 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
```bash
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
1. 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_key
```
2. Levanta el Worker localmente:
```bash
npm run dev
```
3. El 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 con `curl` directamente:
```bash
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):
```bash
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
```bash
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:
```bash
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`](./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_ventas` con `fecha_inicio_comparacion`/`fecha_fin_comparacion`.
- *"¿Qué productos tienen menos de 3 unidades disponibles?"* → usa `siigo_consultar_inventario` con `umbral_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ícitamente `document_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
1. En Claude (Claude.ai, Claude Desktop o Claude Code), agrega un servidor MCP remoto apuntando a:
```
https://<tu-worker>.workers.dev/mcp
```
2. 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.
3. Claude descubrirá las 28 tools automáticamente vía `tools/list`.
## Conexión con ChatGPT
1. En la configuración de conectores/MCP de ChatGPT, agrega un conector remoto con la misma URL:
```
https://<tu-worker>.workers.dev/mcp
```
2. El servidor usa Streamable HTTP estándar (sin sesión obligatoria, `legacy: "stateless"` por defecto en `agents/mcp/server`), compatible con la forma en que ChatGPT invoca servidores MCP remotos.
3. 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.vars` local (ambos en `.gitignore`); nunca se hardcodean ni se commitean.
- Ninguna tool devuelve `access_key`, `access_token`, `username` ni headers de autenticación. El `access_token` se cachea en memoria del Worker (por isolate, no persistente) y se renueva automáticamente antes de expirar; nunca sale de `src/siigo/auth.ts`.
- Los errores de Siigo se traducen con `src/utils/errors.ts` a 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_factura` nunca timbra ante la DIAN ni envía correo salvo que se indique `enviar_a_dian`/`enviar_por_email` como `true` explícitamente. `siigo_crear_comprobante_contable` valida 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 que `SIIGO_USERNAME`/`SIIGO_ACCESS_KEY` esté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...` en `siigo_obtener_*`**: el ID (UUID) no existe o pertenece a otro tipo de documento. Usa primero la tool `siigo_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_service` no disponible); reintenta la operación. Para `siigo_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 (ver `TOOLS.md`).
- **El cliente MCP no ve las tools**: confirma que el endpoint termina en `/mcp` y que el cliente hace `initialize` antes de `tools/list` (algunos clientes lo hacen automáticamente).
- **Cambié `wrangler.jsonc` y los tipos no reflejan el cambio**: corre `npm 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 en `TOOLS.md` y en los comentarios de `src/siigo/*.ts`.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues