The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the MCP Reportia listing page.
Servidor MCP (Model Context Protocol) independiente que envuelve la API HTTP real de Reportia y la expone a través del transporte stdio con JSON-RPC newline-delimited. Pensado para ser consumido por clientes MCP (Claude Desktop, Cursor, Hermes Agent, otros) con un único npx, sin ejecutar código de servidor propio.
Esta capa no contiene lógica de negocio ni secretos propios: actúa como traductor entre el protocolo MCP y los endpoints REST de Reportia. Las credenciales se inyectan desde variables de entorno.
Este servidor MCP está publicado y discoverable en:
| Plataforma | URL | Formato |
|---|---|---|
| MCP Registry oficial (modelcontextprotocol.io) | io.github.javalenciacai/mcp-reportia | server.json |
| npm registry | @james.valencia/mcp-reportia | npm package |
| skills.sh (Agent Skills Directory) | javalenciacai/mcp-reportia | skills/reportia-mcp-usage/SKILL.md |
Instalación via skills.sh:
Este repo publica automáticamente a npm y al MCP Registry oficial cuando se pushea un tag v* a main. La indexación en skills.sh es automática (scrapeo de GitHub).
La configuración vive en la página del paquete (no en /settings/james.valencia/security — esa URL es para tokens tradicionales).
Abre https://www.npmjs.com/package/@james.valencia/mcp-reportia/settings (logueado como james.valencia en el navegador).
En la sección "Trusted Publisher", click en "Add a trusted publisher" (o "GitHub Actions" según el wording de tu versión de npmjs.com).
Completa el formulario con estos valores exactos (la doc oficial los lista así):
| Campo | Valor |
|---|---|
| Provider | GitHub Actions |
| Organization or user | javalenciacai |
| Repository | mcp-reportia |
| Workflow filename | publish.yml (solo el nombre, sin la ruta .github/workflows/) |
| Environment name | (vacío) — el workflow no usa GitHub Environments |
| Allowed actions | npm publish (al menos uno) |
Click "Add" o "Save". npm NO valida la configuración al guardar, pero el workflow fallará en runtime si los datos no coinciden exactamente.
Trusted Publishing requiere npm >= 11.5.1, que viene incluido en Node.js 24. El workflow actual usa Node 22 (npm 10.9) — fallará con ENEEDAUTH aunque el publisher esté bien configurado.
Lo que voy a hacer yo cuando confirmes el paso 1: actualizar el workflow a Node 24, hacer commit, re-crear el tag v0.1.2 apuntando al nuevo commit, re-disparar el publish.
Re-dispara manualmente el workflow y mira el log del job publish-npm:
Si dice OK: @james.valencia/mcp-reportia@0.1.2 publicado en el último step, está funcionando. Si vuelve a fallar, mandame el output del step "Publish" (sin el token).
| Plataforma | Requisito | Estado |
|---|---|---|
| npm Trusted Publishing | Configurar publisher en /package/@james.valencia/mcp-reportia/settings con javalenciacai/mcp-reportia + publish.yml | Tu turno |
| Workflow Node 24 | Subir a Node 24 (lo hago yo tras tu confirmación) | Pendiente |
| MCP Registry | Ninguno — usa github-oidc que firma el workflow automáticamente | Listo |
| skills.sh | Ninguno — scraping automático | Listo |
| GitHub Release | Permiso contents: write ya configurado en el workflow | Listo |
Voy a ejecutar en este orden (no requiere tu input):
node-version: '22' → '24' en ambos jobs del workflow publishnpm test && npm run build localPublish hasta publish-npm exitosoGitHub Actions se dispara automáticamente:
validate — typecheck + test + build + smoke. Verifica que package.json.version y server.json.version coincidan con el tag.publish-npm — publica a npm via OIDC (sin tokens de larga duración).publish-mcp-registry — publica server.json al MCP Registry oficial.release — crea un GitHub Release con notas auto-generadas.Si necesitas un release fuera del flujo normal, ve a GitHub → Actions → "Publish" → "Run workflow" y opcionalmente pasa un version override.
Si necesitas revertir una versión publicada a npm (dentro de 72h):
Después de 72h no es posible; debes publicar un patch. El MCP Registry no soporta rollback; hay que publicar una versión superior con la corrección.
Una vez publicado, el consumo típico es vía npx:
Los clientes MCP (Claude Desktop, Cursor, Hermes, etc.) lo invocan por ti como subproceso. No necesitas ejecutarlo a mano salvo para depurar.
| Variable | Obligatoria | Descripción |
|---|---|---|
REPORTIA_BASE_URL | Sí | URL raíz de la API de Reportia, sin barra final (p.ej. https://reportia.example.com). |
REPORTIA_TOKEN | Condicional* | Token Bearer. Alternativa al login por sesión. |
REPORTIA_COOKIE | Condicional* | Cookie de sesión Reportia pre-emitida (p.ej. connect.sid=s%3A...). Para callers que ya tienen la sesión del usuario resuelta y quieren que el child autentique como ese usuario sin re-login. |
REPORTIA_EMAIL | Condicional* | Email para login por sesión (cookie). |
REPORTIA_PASSWORD | Condicional* | Contraseña para login por sesión (cookie). |
REPORTIA_COMPANY_ID | No | companyId por defecto cuando la tool lo admita. Acepta entero positivo. |
REPORTIA_TIMEOUT_MS | No (def. 30000) | Timeout por petición HTTP en ms. |
REPORTIA_DOWNLOAD_DIR | No (def. ./downloads) | Carpeta donde se guardan los binarios descargados (Excel/PDF exportados). |
REPORTIA_USER_AGENT | No (def. mcp-reportia/0.1.0) | Cabecera User-Agent en cada request. |
* Exactamente una de las tres alternativas de auth debe estar presente:
REPORTIA_TOKEN Bearer, oREPORTIA_EMAIL + REPORTIA_PASSWORD sesión cookie (el package hace POST /api/auth/login y captura la cookie), oREPORTIA_COOKIE sesión cookie pre-emitida (el package la usa directo, sin re-login).Si pasás REPORTIA_TOKEN y REPORTIA_COOKIE a la vez, loadConfig lanza ConfigError con el mensaje REPORTIA_TOKEN y REPORTIA_COOKIE son mutuamente excluyentes — usa solo uno. para evitar que un token accidental sobreescriba una sesión per-user.
Precedencia cuando se establece una sola: cookie > bearer > session. cookie gana porque es la que matchea la identidad resuelta upstream; bearer es service-account; session es email+password login (el child se loguea a sí mismo).
Si no se establece ninguna, loadConfig lanza ConfigError al arrancar el servidor.
⚠️ No copies credenciales de
C:\james\Reportia\.enva este repositorio. Este proyecto no debe contener secretos. Configúralas en el entorno del cliente MCP que lo invoque.
Revisa .env.example para ver todas las variables.
%APPDATA%\Claude\claude_desktop_config.json)Añade una entrada dentro de mcpServers:
Sustituye
mcp-reportiapor la ruta localC:\\james\\mcp-reportiadurante desarrollo, conargs: ["-y", "--prefix", "C:\\james\\mcp-reportia", "mcp-reportia"]o ejecutandonpm run startcomo comando directo.
%USERPROFILE%\.cursor\mcp.json)~/.hermes/config.toml o UI)Añade un servidor MCP stdio de nombre reportia apuntando a npx mcp-reportia y exporta las variables en env.
Formato típico:
El nombre exacto del campo varía según la versión de Hermes. Consulta
hermes mcp --help.
Cuando el caller (p.ej. un servidor AI multi-tenant) ya resolvió la sesión de Reportia del usuario activo y quiere que el child autentique como ese mismo usuario — sin re-login y sin service-account — pasale la cookie pre-emitida:
El child NO va a llamar a
/api/auth/login(se salta ese paso), NO va a llamar a/api/auth/logoutal cerrar (la sesión es del caller, no del child), y va a hacer todas las requests Reportia con la identidad del usuario resuelto. Si el caller está corriendo detrás de un relay que captura la cookie del usuario en runtime (p.ej. la session-derived path del Cowork server), este es el modo de auth que se alinea con ese flujo.
El servidor expone 66 herramientas con el prefijo reportia_. Todas devuelven JSON (string con JSON.stringify pretty-print) y validan su input con Zod. Se agrupan por dominio funcional:
| Dominio | Módulo | Cantidad |
|---|---|---|
| Salud y autenticación | src/tools/auth-health.ts | 3 |
| Empresas | src/tools/companies.ts | 5 |
| Movimientos contables | src/tools/accounting-movements.ts | 4 |
| Mapeo de cuentas | src/tools/account-mappings.ts | 5 |
| Reportes de comisiones | src/tools/commission-reports.ts | 2 |
| Terceros | src/tools/third-parties.ts | 4 |
| Vendedor × factura | src/tools/salesperson-invoice.ts | 11 |
| Línea × centro de costo | src/tools/line-cost-center.ts | 22 |
| Operaciones (uploads, colas, SIIGO) | src/tools/operations.ts | 10 |
| Total | 66 |
src/tools/auth-health.ts)| Tool | Descripción |
|---|---|
reportia_health | Diagnóstico del cliente MCP + ping a GET /api/health. |
reportia_whoami | Perfil del usuario autenticado (GET /api/auth/me). |
reportia_logout | Cierra la sesión contra Reportia (POST /api/auth/logout). |
src/tools/companies.ts)| Tool | Tipo | Descripción |
|---|---|---|
reportia_companies_list | Listado | Lista empresas accesibles (GET /api/companies). |
reportia_company_get | Detalle | Detalle de una empresa (GET /api/companies/:id). |
reportia_company_settings_get | Configuración | Settings de empresa (GET /api/companies/:id/settings). |
reportia_company_settings_update | Mutación | Patch de settings (PATCH /api/companies/:id/settings). |
reportia_company_activate ⚠️ | Destructiva | Activa empresa (POST /api/companies/:id/activate). Requiere confirm:true. |
src/tools/accounting-movements.ts)| Tool | Tipo | Descripción |
|---|---|---|
reportia_movements_list | Listado | Lista movimientos con filtros y paginación. |
reportia_movements_export_excel | Descarga binaria | Exporta movimientos a Excel y devuelve ruta local. |
reportia_movements_export_pdf | Descarga binaria | Exporta movimientos a PDF y devuelve ruta local. |
reportia_movements_delete_all ⚠️ | Destructiva | Elimina todos los movimientos de la empresa. Requiere confirm:true. |
src/tools/account-mappings.ts)| Tool | Tipo | Descripción |
|---|---|---|
reportia_account_mappings_list | Listado | Lista mapeos contables (GET /api/companies/:companyId/account-mappings). |
reportia_account_mapping_create | Mutación | Crea un mapeo (POST /api/account-mappings). |
reportia_account_mapping_update | Mutación | Actualiza un mapeo (PATCH /api/account-mappings/:mappingId). |
reportia_account_mapping_delete ⚠️ | Destructiva | Elimina un mapeo (DELETE /api/account-mappings/:mappingId). Requiere confirm:true. |
reportia_account_codes_search | Búsqueda | Busca códigos contables para autocompletar (GET /api/companies/:companyId/account-codes/search). |
src/tools/commission-reports.ts)| Tool | Tipo | Descripción |
|---|---|---|
reportia_commission_list | Listado | Lista cálculos de comisión (GET /api/commission-reports). |
reportia_commission_export_excel | Descarga binaria | Exporta reporte de comisiones a Excel. |
src/tools/third-parties.ts)| Tool | Tipo | Descripción |
|---|---|---|
reportia_third_parties_list | Listado | Lista terceros (clientes/proveedores). |
reportia_third_parties_search | Búsqueda | Búsqueda avanzada de terceros. |
reportia_third_parties_get_by_nit | Detalle | Obtiene un tercero por NIT. |
reportia_third_parties_portfolio_balance | Resumen | Balance de cartera por tercero. |
src/tools/salesperson-invoice.ts)Mapeos vendedor → factura, opciones de vendedor, listados de facturas, settings de factura y envío de facturas (email individual y masivo).
| Tool | Tipo | Descripción |
|---|---|---|
reportia_salesperson_mappings_list | Listado | Lista mapeos vendedor × factura de una empresa. |
reportia_salesperson_mapping_create | Mutación | Crea un mapeo vendedor × factura. |
reportia_salesperson_mapping_update | Mutación | Actualiza un mapeo vendedor × factura. |
reportia_salesperson_mapping_delete ⚠️ | Destructiva | Elimina un mapeo vendedor × factura. Requiere confirm:true. |
reportia_salesperson_options_list | Listado | Lista opciones de vendedor para selección / autocompletar. |
reportia_invoices_list | Listado | Lista facturas con filtros. |
reportia_invoice_settings_get | Configuración | Lee la configuración de factura de una empresa. |
reportia_invoice_settings_create | Mutación | Crea la configuración de factura. |
reportia_invoice_settings_update | Mutación | Actualiza la configuración de factura. |
reportia_invoice_email_send | Notificación | Envía una factura por email (servidor Reportia dispara el envío). |
reportia_invoices_send_multiple | Notificación | Envía varias facturas por email en una sola llamada. |
src/tools/line-cost-center.ts)Dominio más extenso: gestiona mapeos línea-grupo, mapeos centro de costo, centros de costo disponibles, y todo el ciclo de vida de los reportes de centro de costo (CRUD + ejecutar + duplicar + exportes).
| Tool | Tipo | Descripción |
|---|---|---|
reportia_line_group_mappings_list | Listado | Lista mapeos línea-grupo. |
reportia_line_group_mapping_create | Mutación | Crea un mapeo línea-grupo. |
reportia_line_group_mapping_update | Mutación | Actualiza un mapeo línea-grupo. |
reportia_line_group_mapping_delete ⚠️ | Destructiva | Elimina un mapeo línea-grupo. Requiere confirm:true. |
reportia_line_group_suggestions_lines_groups | Sugerencias | Sugerencias de líneas-grupo para autocompletar. |
reportia_line_group_suggestions_by_type | Sugerencias | Sugerencias de líneas-grupo filtradas por tipo. |
reportia_line_group_description | Detalle | Descripción legible de un mapeo línea-grupo. |
reportia_cost_center_mappings_list | Listado | Lista mapeos centro de costo. |
reportia_cost_center_mapping_create | Mutación | Crea un mapeo centro de costo. |
reportia_cost_center_mapping_update | Mutación | Actualiza un mapeo centro de costo. |
reportia_cost_center_mapping_delete ⚠️ | Destructiva | Elimina un mapeo centro de costo. Requiere confirm:true. |
reportia_cost_center_mappings_suggestions | Sugerencias | Sugerencias de mapeos centro de costo. |
reportia_cost_centers_available | Listado | Centros de costo disponibles para una empresa. |
reportia_cost_center_reports_list | Listado | Lista reportes de centro de costo. |
reportia_cost_center_report_get | Detalle | Detalle de un reporte de centro de costo. |
reportia_cost_center_report_create | Mutación | Crea un reporte de centro de costo. |
reportia_cost_center_report_update | Mutación | Actualiza un reporte de centro de costo. |
reportia_cost_center_report_delete ⚠️ | Destructiva | Elimina un reporte de centro de costo. Requiere confirm:true. |
reportia_cost_center_report_execute | Ejecución | Ejecuta un reporte de centro de costo. |
reportia_cost_center_report_duplicate | Mutación | Duplica un reporte de centro de costo (alias: copia). |
reportia_cost_center_report_export_excel | Descarga binaria | Exporta el resultado del reporte a Excel. |
reportia_cost_center_report_export_pdf | Descarga binaria | Exporta el resultado del reporte a PDF. |
src/tools/operations.ts) — uploads, colas y SIIGOTodas las tools de este módulo son read-only: historial/estado de uploads, salud del sistema de colas y de los workers, y herramientas de consulta sobre SIIGO (settings, clientes, corridas, trazas, schedules, historial). No hay tools de mutación, de subida multipart/form-data, ni de control de colas en esta versión.
| Tool | Tipo | Descripción |
|---|---|---|
reportia_uploads_history_list | Listado | Historial de uploads de una empresa (GET /api/companies/:companyId/upload-history). |
reportia_upload_status_get | Detalle | Estado de un upload específico (GET /api/upload/:uploadId/status). |
reportia_health_queue_system | Diagnóstico | Salud del sistema de colas (GET /api/health/queue-system). |
reportia_health_workers | Diagnóstico | Salud de los workers y lag de la cola (GET /api/queue/workers/health). |
reportia_siigo_settings_get | Configuración | Settings SIIGO Pyme de una empresa (GET /api/companies/:companyId/siigo-settings). |
reportia_siigo_clients_list | Listado | Clientes remotos SIIGO disponibles para una empresa (GET /api/companies/:companyId/siigo/clients). |
reportia_siigo_sync_runs_list | Listado | Corridas de sincronización SIIGO (GET /api/companies/:companyId/siigo/sync/runs). |
reportia_siigo_run_trace_get | Detalle | Trazabilidad de una corrida SIIGO (GET /api/companies/:companyId/siigo/sync/runs/:runId/trace). |
reportia_siigo_schedules_list | Listado | Schedules de sincronización SIIGO (GET /api/companies/:companyId/siigo/schedules). |
reportia_siigo_history_get | Historial | Historial de comandos SIIGO (GET /api/companies/:companyId/siigo/history). |
⚠️ Las tools marcadas como Destructiva requieren el parámetro
{ "confirm": true }en su input. Si no se envía, el handler valida conassertConfirmed(input, '<tool-name>')(definido ensrc/tool-base.ts) y devuelve un error concode: "GUARD_REJECTED"antes de cualquier llamada HTTP. El LLM debe pedir confirmación explícita al usuario antes de invocarlas.
companyId puede omitirse si configuraste REPORTIA_COMPANY_ID; en caso contrario, es obligatorio en todas las tools que tocan datos por empresa.
stdio. Clientes que solo soporten HTTP no pueden consumirlo directamente.ReportiaClient por proceso: el login es lazy y global; no se admite multi-cuenta simultánea.multipart/form-data): el cliente HTTP está preparado (FormData desde undici) pero las tools actuales no exponen endpoints de upload (no hay POST/PUT con multipart/form-data). Sí se exponen dos tools read-only sobre el histórico y estado de uploads existentes: reportia_uploads_history_list (GET /api/companies/:companyId/upload-history) y reportia_upload_status_get (GET /api/upload/:uploadId/status). Si Reportia añade en el futuro endpoints de carga, basta con añadir un ToolDefinition que use ctx.client.call(..., { formData }).tools/list cuando lo necesite.AUTH_ERROR, NOT_FOUND, VALIDATION_ERROR, ROW_LIMIT_EXCEEDED, NETWORK_ERROR, TIMEOUT). El cliente nunca expone secretos en el mensaje.npm run test:smoke arranca el servidor con REPORTIA_BASE_URL=http://127.0.0.1:9 (puerto cerrado). No hace llamadas reales; solo valida el handshake MCP. Para pruebas integradas reales, usa npm run test:integration apuntando a un servidor Reportia accesible.El servidor está diseñado para minimizar superficie de ataque cuando es invocado por un LLM:
confirm: true literal: se declaran con destructive: true y verifican con assertConfirmed(...) antes de cualquier llamada HTTP. Si falta confirm, devuelven GUARD_REJECTED sin tocar la API. El LLM debe pedirle al usuario confirmación explícita antes de invocarlas.z.number().int().positive() antes de la interpolación. Los strings de path (NIT, invoiceId, mappingId de líneas/centros) usan encodeURIComponent y/o se restringen a un alfabeto seguro ([A-Za-z0-9-]+ para NITs).User-Agent configurable vía REPORTIA_USER_AGENT se sanitiza contra CRLF (header injection) en src/client.ts:sanitizeUserAgent.connect.sid se mantiene en memoria del cliente y nunca aparece en respuestas JSON.connect.sid recibida de /api/auth/login y la rota solo si Reportia la renueva; nunca se escribe a disco.tests/security.test.ts): 16 tests que verifican que ninguna tool destructiva omite confirm, que ningún esquema acepta inputs peligrosos, y que el orden de guards (resolveCompanyId → assertConfirmed) prefiere errores informativos sobre GUARD_REJECTED cuando el problema es de configuración.tools/)| Endpoint | Tool |
|---|---|
GET /api/health | reportia_health |
GET /api/auth/me | reportia_whoami |
POST /api/auth/logout | reportia_logout |
GET /api/companies | reportia_companies_list |
GET /api/companies/:id | reportia_company_get |
GET /api/companies/:id/settings | reportia_company_settings_get |
PATCH /api/companies/:id/settings | reportia_company_settings_update |
POST /api/companies/:id/activate | reportia_company_activate |
GET /api/accounting-movements (con filtros) | reportia_movements_list |
GET /api/accounting-movements/export/excel | reportia_movements_export_excel |
GET /api/accounting-movements/export/pdf | reportia_movements_export_pdf |
DELETE /api/accounting-movements | reportia_movements_delete_all |
GET/POST/PATCH/DELETE /api/account-mappings/... | reportia_account_mapping_* |
GET /api/account-codes/search | reportia_account_codes_search |
GET /api/commission-reports | reportia_commission_list |
GET /api/commission-reports/export/excel | reportia_commission_export_excel |
GET /api/third-parties | reportia_third_parties_list |
GET /api/third-parties/search | reportia_third_parties_search |
GET /api/third-parties/by-nit/:nit | reportia_third_parties_get_by_nit |
GET /api/third-parties/portfolio-balance | reportia_third_parties_portfolio_balance |
ReportiaClient).multipart/form-data) — la superficie se limita a GET /api/companies/:companyId/upload-history y GET /api/upload/:uploadId/status (read-only)./api/v0/*).⚠️ Esta tabla refleja la superficie actual de
src/tools/*.ts. Antes de añadir rutas nuevas, editasrc/tools/<modulo>.ts, re-exporta ensrc/tools/index.tsy correnpm run typecheck && npm test.
Requisitos:
Los tests no requieren Reportia levantada ni credenciales; usan entorno sintético.
El smoke test (scripts/jsonrpc-smoke.mjs) lanza dist/server.js como subproceso, le envía initialize + tools/list por JSON-RPC newline-delimited y verifica que la respuesta contenga al menos una herramienta. No realiza llamadas HTTP contra Reportia (apunta a 127.0.0.1:9).
El test de integración (scripts/integration-smoke.mjs) sí habla con un servidor Reportia real: hace initialize, tools/list, llama a reportia_health (que hace ping a /api/health) y a reportia_whoami (que debe devolver AUTH_ERROR con un token inválido para validar el manejo de errores). Útil para verificar que la versión desplegada sigue siendo compatible con el backend real.
Si solo quieres validar que la build no está rota:
Esto ejecuta npx @modelcontextprotocol/inspector node dist/server.js, que abre una UI web para enviar manualmente los métodos del protocolo (initialize, tools/list, tools/call, etc.).
Convenciones:
z.object({...})) para validar su input.ctx.client.call(...) en try/catch y usar ok(...)/fail(...) de tool-base.ts.destructive: true y verificar confirm: true con assertConfirmed(...) o equivalente en su handler.