Skip to main content
Glama
mcp-hacienda-cr

mcp-hacienda-cr

by jmnzcn

mcp-hacienda-cr

ci npm descargas License

Un servidor MCP que le da a Claude, Cursor y otros asistentes de IA acceso a los datos públicos del Ministerio de Hacienda de Costa Rica: el tipo de cambio, la situación tributaria de un contribuyente, los códigos CABYS con su tarifa de IVA y las exoneraciones. Además valida el XML de una factura electrónica 4.4 antes de enviarla: contra el esquema oficial, sus cuentas y los datos de Hacienda. Lo hice pensando en la facturación electrónica, donde cada línea de una factura necesita su código CABYS y el IVA correcto, y un error se descubre cuando Hacienda rechaza el comprobante.

Está publicado en npm y en el registro oficial de MCP como io.github.jmnzcn/mcp-hacienda-cr.

English summary

Demo: MCP Inspector llamando a tipo_de_cambio, buscar_cabys y consultar_contribuyente

Grabado con MCP Inspector contra la API real de Hacienda: el tipo de cambio del día, los códigos CABYS de "café tostado" con su IVA y la situación tributaria de la CNFL.

Qué le podés preguntar a tu asistente

"¿Qué código CABYS uso para vender café tostado y cuánto IVA lleva?"

Hay 71 códigos para café tostado. Por ejemplo, 2391102010100 (café tostado sin descafeinar, en grano) paga IVA del 1 %, pero 2391102020000 (café tostado descafeinado) paga 13 %.

"Antes de facturarle, ¿la empresa 3-101-000046 está al día con Hacienda?"

COMPAÑIA NACIONAL DE FUERZA Y LUZ S.A. · Cédula jurídica · Régimen general · Al día (no morosa ni omisa) · Actividad principal: 3510.0, generación, transmisión y distribución de energía eléctrica.

"Revisá esta factura antes de que la envíe" (con el XML adjunto)

❌ Factura electrónica tiene 1 error y 1 advertencia.

  • Esquema oficial 4.4: cumple (validado como borrador, sin firma)

  • ❌ Resumen › TotalComprobante: dice 26 980,00, pero venta neta + impuesto + otros cargos − IVA devuelto da 26 880,00 (diferencia 100,00).

  • ⚠️ Línea 2 › Impuesto › Tarifa: cobra IVA 13 %, pero el CABYS 0161001010000 (café cereza, orgánico) tiene 1 %.

También: "¿A cuánto está el dólar hoy?" o "¿La exoneración AL-00460853-20 sigue vigente?". Son respuestas reales del servidor contra la API de Hacienda.

Related MCP server: costa-rica-invoice-mcp

Herramientas

  • tipo_de_cambio: el tipo de cambio de referencia del día, dólar (compra y venta) y euro.

  • consultar_contribuyente: nombre, tipo de identificación, régimen, estado, si está moroso u omiso y sus actividades económicas. Ejemplo: 3-101-000046.

  • buscar_cabys: busca códigos CABYS por descripción, con su tarifa de IVA. Ejemplo: café tostado.

  • obtener_cabys: el detalle de un código CABYS, con su IVA y su categoría. Ejemplo: 0161001010000.

  • consultar_exoneracion: beneficiario, porcentaje, vigencia y códigos CABYS que cubre una exoneración. Ejemplo: AL-00460853-20.

  • validar_factura: revisa el XML de un comprobante 4.4, firmado o sin firmar, y explica cada problema en español. Ejemplo: examples/factura-con-errores.xml.

Todas son de solo lectura y usan las APIs públicas de Hacienda, así que no hace falta registrarse ni tener una API key.

Instalación

Requiere Node.js 18 o superior.

En Claude Desktop, agregalo a claude_desktop_config.json (Configuración → Desarrollador → Editar configuración):

{
  "mcpServers": {
    "hacienda-cr": {
      "command": "npx",
      "args": ["-y", "mcp-hacienda-cr"]
    }
  }
}

En Claude Code:

claude mcp add hacienda-cr -- npx -y mcp-hacienda-cr

En Cursor, VS Code y otros clientes MCP, usá el comando npx -y mcp-hacienda-cr con transporte stdio.

Qué revisa validar_factura

Sirve para los ocho tipos de comprobante 4.4: factura, tiquete, notas de crédito y de débito, factura de compra, factura de exportación, recibo electrónico de pago y mensaje receptor.

  1. El esquema oficial. Valida el XML contra los XSD de Hacienda en la revisión vigente desde el 1 de noviembre de 2026 (vienen incluidos; su origen está en schemas/v4.4/FUENTE.md). Si el comprobante no está firmado, lo valida como borrador y lo avisa. Si usa el espacio de nombres de la versión 4.3, lo dice.

  2. Las cuentas. Revisa cada línea y el resumen con las fórmulas que documentan los propios esquemas: cantidad × precio, descuentos, IVA según la tarifa, impuesto neto, total de la línea, gravado + exento + exonerado + no sujeto, venta neta, desglose por tarifa, total del comprobante y medios de pago. Compara al céntimo.

  3. La clave y el consecutivo. Comprueba que la clave de 50 posiciones tenga la fecha, la identificación del emisor y el consecutivo del documento, y que el consecutivo sea del tipo de comprobante correcto.

  4. Los datos de Hacienda. Comprueba que el emisor y el receptor estén registrados, que la actividad económica sea del emisor, que cada CABYS exista y cobre su IVA, que cada exoneración exista, esté vigente, sea del receptor y cubra el CABYS, y que el tipo de cambio en dólares se parezca al de referencia del día. Si Hacienda no responde, lo avisa sin invalidar el comprobante.

No verifica la firma criptográficamente ni reemplaza la aceptación de Hacienda: es una revisión previa para no enviar comprobantes que van a ser rechazados.

Cómo funciona

flowchart LR
    U["Usuario"] --> A["Asistente de IA<br/>(Claude, Cursor…)"]
    A -- "MCP (stdio)" --> S["mcp-hacienda-cr"]
    S -- "HTTPS" --> H["api.hacienda.go.cr"]

Está escrito en TypeScript con el SDK oficial de MCP, y cada herramienta valida su entrada con Zod antes de llamar a Hacienda: una cédula física tiene 9 dígitos, una jurídica o NITE 10, un DIMEX 11 o 12, y un código CABYS 13. Cada respuesta trae un texto legible para la conversación y los datos exactos en structuredContent para que el modelo trabaje con ellos. Si la cédula no es válida, el código no existe o la API de Hacienda está caída, el usuario recibe un mensaje claro en vez de un error. Las respuestas quedan en caché 10 minutos (tipo de cambio) o una hora (lo demás) para no saturar la API.

Pruebas

Hay 44 pruebas unitarias del cliente, el validador y el servidor completo, con un cliente MCP real en memoria y respuestas de Hacienda grabadas. Las del validador parten de una factura que cuadra y la rompen de a un error por vez. Además, el validador se probó con los siete comprobantes de ejemplo de DojoCodingLabs/hacienda-cr, generados por otro proyecto: todos pasan. Aparte, unas pruebas de contrato llaman a la API real para detectar si Hacienda cambia el formato de sus respuestas, y una prueba de humo levanta el servidor compilado por stdio, como lo haría Claude, y llama a las seis herramientas. El CI corre en Node 18, 20 y 22 en cada push, y las pruebas contra la API real también cada lunes, para enterarme antes que los usuarios si algo cambia.

npm install
npm test            # unitarias, sin red
npm run test:live   # contrato con la API real de Hacienda
npm run smoke       # servidor compilado por stdio, de punta a punta

Aviso

Los datos vienen de las APIs públicas del Ministerio de Hacienda y son de referencia. Este proyecto no está afiliado al Ministerio de Hacienda. Las decisiones fiscales confirmalas con un contador o directamente con Hacienda.

Licencia

PolyForm Noncommercial 1.0.0. Podés usarlo gratis para fines no comerciales: uso personal, investigación, educación o para evaluarlo. Cualquier uso comercial necesita una licencia: neyfred@gmail.com. Las versiones hasta el commit 438da02 (2026-10-26), incluida la 0.1.1 publicada en npm, se publicaron con licencia MIT.

English summary

mcp-hacienda-cr is a Model Context Protocol server that lets AI assistants such as Claude and Cursor query the public APIs of Costa Rica's Ministry of Finance: official exchange rates, taxpayer status (registered, delinquent or non-filer, economic activities), CABYS product and service codes with their VAT rate, and tax exemptions. It also validates a v4.4 e-invoice XML before it is sent: against the official schemas, its own arithmetic, and Hacienda's data (taxpayers, CABYS VAT rates, exemptions), explaining each problem in Spanish. It is aimed at e-invoicing, where every invoice line needs a CABYS code and the right VAT rate. No API key is needed. It is listed in the official MCP registry and installs with one command:

claude mcp add hacienda-cr -- npx -y mcp-hacienda-cr

Ney Fred Jiménez Campos · LinkedIn · GitHub

Available Tools

5 tools
buscar_cabysBuscar código CABYSA
Read-only

Busca en el catálogo CABYS (Catálogo de Bienes y Servicios) los códigos que corresponden a un producto o servicio, con su tarifa de IVA. Todo bien o servicio de una factura electrónica en Costa Rica necesita su código CABYS.

NameRequiredDescriptionDefault
limiteNoCantidad máxima de resultados (1–50).
descripcionYesProducto o servicio a buscar. Ej: "café tostado", "consultoría informática".

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description usefully notes that results include the IVA rate, but says nothing about result ordering, relevance matching, or what happens when no code matches — relevant for a catalog search with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: what it does first, domain justification second. Minimal waste, though the invoice sentence is more motivation than actionable guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only search with no output schema, the description covers purpose, the returned fields, and domain context adequately. Missing only the shape of a result item (code, description, IVA) and empty-result behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (descripcion, limite 1–50) are already documented. The description reinforces that descripcion is a product or service and that output carries the IVA rate, but adds no query-syntax or matching guidance beyond the schema examples.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (busca) and resource (catálogo CABYS) plus the payload returned (códigos con tarifa de IVA). It does not explicitly differentiate from the sibling obtener_cabys, which by name appears to be the code-lookup counterpart, so sibling disambiguation is left implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives domain context — every good or service on a Costa Rican electronic invoice needs a CABYS code — which implies when the tool is needed. However, it never states when to prefer this over obtener_cabys or consultar_exoneracion, and no exclusions or prerequisites are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

consultar_contribuyenteConsultar contribuyenteA
Read-only

Situación tributaria de una persona o empresa en Hacienda a partir de su cédula física, jurídica, DIMEX o NITE: nombre, régimen, estado, si está morosa u omisa y sus actividades económicas. Útil antes de emitir una factura electrónica.

NameRequiredDescriptionDefault
identificacionYesNúmero de identificación, con o sin guiones. Ej: "3-101-000046" o "112340567".

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description is consistent with that, reinforcing that the source is the external Hacienda registry. It adds useful disclosure beyond the annotations by listing exactly which fields come back (régimen, estado, morosa/omisa, actividades económicas). It doesn't cover latency, rate limits, or what happens when the identification isn't found.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both load-bearing: the first defines the resource and its return payload, the second gives the usage context. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a single required parameter, no output schema and lean annotations, the description carries the burden well by enumerating the returned fields and the accepted identifier types. Missing only edge-case behavior (invalid or not-found identification, response shape detail).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already explains the format with examples, so the baseline would be 3. The description adds genuine meaning by enumerating which identifier types are accepted (cédula física, jurídica, DIMEX, NITE), which the schema does not state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (consultar) and a precise resource: the tax situation of a person or company in Hacienda, with an explicit enumeration of the data returned (nombre, régimen, estado, morosidad, actividades económicas). This is clearly distinct from the sibling tools (tipo_de_cambio, buscar_cabys, obtener_cabys, consultar_exoneracion), which operate on exchange rates, CABYS codes and exemptions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Útil antes de emitir una factura electrónica" gives a concrete usage context, positioning it as a pre-invoicing verification step. However, it doesn't state when NOT to use it or point to alternatives (e.g., consultar_exoneracion for exemption status), so there are no explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

consultar_exoneracionConsultar exoneraciónA
Read-only

Datos de una exoneración de impuestos registrada en Hacienda a partir de su número de autorización: beneficiario, porcentaje, vigencia y códigos CABYS que cubre.

NameRequiredDescriptionDefault
autorizacionYesNúmero de documento de la exoneración. Ej: "AL-00020402-24".

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description usefully discloses that data comes from an external Hacienda registry and enumerates the returned fields. It says nothing about behavior when the authorization number is invalid or not found, which matters for an external lookup.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense sentence that front-loads the resource and key, then lists the returned fields. No filler or redundant restatement of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only lookup with annotations present and no output schema, the description covers source, key, and return fields, which is most of what an agent needs. The only gap is failure/not-found behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter already carries a format example ("AL-00020402-24"). The description restates that the input is the authorization number but adds no format, validation, or normalization detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific resource (exoneración de impuestos registered at Hacienda), the lookup key (número de autorización), and the fields returned (beneficiario, porcentaje, vigencia, CABYS). It is clearly distinguishable from siblings such as consultar_contribuyente or buscar_cabys. It stops short of a clean verb-led statement of operation, relying on the title for the 'consultar' action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it (when you have an authorization number and need exoneration details), and the 'a partir de su número de autorización' phrase anchors the input. It gives no explicit when-not-to-use guidance or pointers to alternatives like buscar_cabys when only CABYS coverage is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

obtener_cabysDetalle de un código CABYSA
Read-only

Descripción, tarifa de IVA y categorías de un código CABYS de 13 dígitos.

NameRequiredDescriptionDefault
codigoYesCódigo CABYS de 13 dígitos. Ej: "0161001010000".

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds useful return-field information (description, IVA rate, categories) that matters because there is no output schema, but it omits invalid-code behavior and any rate/auth context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single efficient sentence that front-loads the returned fields and ends with the key input constraint. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter lookup with readOnly annotations and no output schema, the description names the key return fields so the agent knows what to expect. Only explicit sibling routing and invalid-code behavior are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage, the schema already documents the single codigo parameter with its 13-digit format and example. The description merely repeats the 13-digit constraint without adding format or validation meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource (a 13-digit CABYS code) and states the fields returned: description, IVA rate, and categories. It does not explicitly distinguish itself from the sibling buscar_cabys, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 13-digit exact-code phrasing implies this is a lookup tool for when the code is already known, but it never says so explicitly or names buscar_cabys as the alternative. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tipo_de_cambioTipo de cambio del díaA
Read-only

Tipo de cambio de referencia de hoy según Hacienda: dólar (compra y venta en colones) y euro (en colones y en dólares).

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the agent knows this is a safe external read. The description adds only the source (Hacienda) and the data composition, and says nothing about failure behavior when no rate has been published yet (weekends/holidays), timezone/date boundary of 'hoy', or caching/freshness of the fetch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the source and temporal scope front-loaded and the currency breakdown following. Every clause carries information; there is no boilerplate or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly shoulders the burden of describing return content by listing the three rate pairs (USD buy/sell, EUR/CRC, EUR/USD). It stops short of stating the return shape or naming the currency codes, which leaves some ambiguity about how to parse the result, but the substantive coverage is solid for a no-argument lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly makes no parameter claims and instead spends its words on output content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource ('Tipo de cambio de referencia de hoy') and its authoritative source ('según Hacienda'), then enumerates exactly which rates are included: USD buy/sell in colones and EUR in colones and dollars. An agent can tell immediately that this is a single-purpose FX lookup, and the sibling tools (taxpayer lookup, CABYS codes, exoneration) are clearly unrelated, so no differentiation is needed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'de hoy' establishes the temporal scope and implicitly tells the agent this tool only answers today's reference rate, not historical series. There are no sibling alternatives to route between and no prerequisites to state, but the description never explicitly says 'use this when you need a current exchange rate for a calculation' or excludes anything.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedbuscar_cabys
    • First observedconsultar_contribuyente
    • First observedconsultar_exoneracion
    • First observedobtener_cabys
    • First observedtipo_de_cambio

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a clearly distinct resource: exchange rates, taxpayer status, CABYS search, CABYS lookup by code, and tax exoneration details. buscar_cabys and obtener_cabys are adjacent but clearly differentiated as search versus direct code lookup.

Naming Consistency4/5

Four tools follow a consistent Spanish verb_noun pattern: consultar_contribuyente, buscar_cabys, obtener_cabys, consultar_exoneracion. The outlier tipo_de_cambio is a noun phrase rather than an action, but it is still clear and readable.

Tool Count5/5

Five tools is well-scoped for a focused Hacienda CR lookup server. Each tool supports a distinct e-invoicing or tax-reference need without unnecessary surface area.

Completeness4/5

The set covers the core reference lookups implied by the domain: exchange rates, taxpayer status, CABYS catalog search/detail, and exonerations. Minor gaps may exist around broader Hacienda services or historical/currency variants, but agents can work around them for typical e-invoicing preparation.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides AI assistants with live, authenticated access to official Mexican data sources including CURP, RFC, postal codes, phone numbers, SPEI payments, CFDI status, DOF semantic search, and geocoding via INEGI/INE.
    MIT