mcp-hacienda-cr
Read-only MCP server for querying Costa Rica’s Ministry of Finance public data for e-invoicing and tax checks.
Get today’s reference exchange rates for USD (buy/sell) and EUR.
Check a taxpayer’s status by physical/juridical ID, DIMEX, or NITE: name, regime, status, delinquent/non-filer flags, and economic activities.
Search CABYS product/service codes by description and see their VAT rate, with an optional result limit.
Get details for a specific 13-digit CABYS code: description, VAT rate, and category hierarchy.
Look up a tax exemption by authorization number: beneficiary, percentage, validity, and covered CABYS codes.
Use public Hacienda APIs with no registration, token, or API key; all tools are read-only.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-hacienda-crBusca el código CABYS para café tostado y dime cuánto IVA lleva"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🇨🇷 mcp-hacienda-cr
Servidor MCP que conecta a Claude, Cursor y otros asistentes de IA con los datos públicos del Ministerio de Hacienda de Costa Rica: tipo de cambio, situación tributaria de contribuyentes, códigos CABYS con su IVA y exoneraciones. Pensado para la facturación electrónica.
English summary · Herramientas · Instalación · Cómo funciona

Grabado con MCP Inspector contra la API real de Hacienda: tipo de cambio de hoy, códigos CABYS de "café tostado" con su IVA y la situación tributaria de la CNFL.
💬 Qué puedes preguntarle 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 1%, pero2391102020000(café tostado descafeinado) paga IVA 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 · Inscrita en el 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.
"¿A cuánto está el dólar hoy?" · "¿La exoneración AL-00020402-24 sigue vigente?"
Son respuestas reales del servidor contra la API de Hacienda.
Related MCP server: costa-rica-invoice-mcp
🧰 Herramientas
Herramienta | Qué hace | Ejemplo de entrada |
| Tipo de cambio de referencia de hoy: dólar (compra/venta) y euro | — |
| Nombre, tipo de identificación, régimen, estado, si está moroso u omiso y actividades económicas |
|
| Busca códigos CABYS por descripción, con su tarifa de IVA |
|
| Detalle de un código CABYS: IVA y jerarquía de categorías |
|
| Beneficiario, porcentaje, vigencia y CABYS cubiertos de una exoneración |
|
Todas son de solo lectura (readOnlyHint) y usan APIs públicas de Hacienda: no necesitan registro, token ni API key.
📦 Instalación
Requiere Node.js 18 o superior.
Claude Desktop
En claude_desktop_config.json (Configuración → Desarrollador → Editar configuración):
{
"mcpServers": {
"hacienda-cr": {
"command": "npx",
"args": ["-y", "mcp-hacienda-cr"]
}
}
}Claude Code
claude mcp add hacienda-cr -- npx -y mcp-hacienda-crCursor, VS Code y otros clientes MCP
Usa el comando npx -y mcp-hacienda-cr con transporte stdio.
⚙️ Cómo funciona
flowchart LR
U["Tú"] --> A["Asistente de IA<br/>(Claude, Cursor…)"]
A -- "MCP (stdio)" --> S["mcp-hacienda-cr"]
S -- "HTTPS" --> H["api.hacienda.go.cr"]TypeScript con el SDK oficial de MCP; cada herramienta valida su entrada con Zod.
Respuestas dobles: texto legible para la conversación y
structuredContentpara que el modelo trabaje con datos exactos.Errores pensados para el usuario: una cédula con formato inválido, un código inexistente o la API de Hacienda caída se responden con un mensaje claro, no con una excepción.
Caché en memoria: 10 minutos para el tipo de cambio y 1 hora para el resto, para no saturar la API de Hacienda.
Validación local antes de llamar a la API: cédula física (9 dígitos), jurídica o NITE (10) y DIMEX (11–12); código CABYS de 13 dígitos.
Calidad
25 tests unitarios | Cliente de la API y servidor MCP completo (con un cliente MCP real en memoria), usando respuestas reales de Hacienda grabadas |
Tests de contrato en vivo | Contra |
Prueba de humo por stdio | Levanta el servidor compilado como lo haría Claude y llama a las 5 herramientas |
CI | Node 18, 20 y 22 en cada push; contrato en vivo también cada lunes, para enterarse antes que los usuarios si la API cambia |
npm install
npm test # unitarios (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 provienen de las APIs públicas del Ministerio de Hacienda y son de referencia. Este proyecto no está afiliado al Ministerio de Hacienda. Confirma las decisiones fiscales con un contador o directamente con Hacienda.
📜 Licencia
PolyForm Noncommercial 1.0.0. Puedes usarlo gratis para fines no comerciales: uso personal, investigación, educación o evaluarlo. Cualquier uso comercial requiere una licencia comercial: neyfred@gmail.com.
Las versiones hasta el commit 438da02 (2026-10-26), incluida la publicada en npm hasta ese momento, se publicaron con licencia MIT.
🇺🇸 English summary
mcp-hacienda-cr is a Model Context Protocol server that lets AI assistants (Claude, Cursor, …) query Costa Rica's Ministry of Finance public APIs: official exchange rates, taxpayer status (registered, delinquent or non-filer, economic activities), CABYS product/service codes with their VAT rate, and tax exemptions. It targets e-invoicing, where every invoice line needs a CABYS code and the right VAT rate.
No API keys needed. TypeScript + the official MCP SDK, Zod-validated inputs, text plus structured output, friendly errors, in-memory caching, 25 unit tests, live contract tests, a stdio smoke test, and CI on Node 18/20/22 with a weekly live run.
claude mcp add hacienda-cr -- npx -y mcp-hacienda-crNey Fred Jiménez Campos · LinkedIn · GitHub · PolyForm Noncommercial · commercial licenses on request
Available Tools
5 toolsbuscar_cabysBuscar código CABYSARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| limite | No | Cantidad máxima de resultados (1–50). | |
| descripcion | Yes | Producto o servicio a buscar. Ej: "café tostado", "consultoría informática". |
TDQS
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.
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.
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.
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.
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.
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 contribuyenteARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| identificacion | Yes | Número de identificación, con o sin guiones. Ej: "3-101-000046" o "112340567". |
TDQS
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.
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.
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.
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.
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.
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ónARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| autorizacion | Yes | Número de documento de la exoneración. Ej: "AL-00020402-24". |
TDQS
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.
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.
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.
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.
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.
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 CABYSARead-only
Descripción, tarifa de IVA y categorías de un código CABYS de 13 dígitos.
| Name | Required | Description | Default |
|---|---|---|---|
| codigo | Yes | Código CABYS de 13 dígitos. Ej: "0161001010000". |
TDQS
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.
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.
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.
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.
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.
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íaARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.1.0- First observed
buscar_cabys - First observed
consultar_contribuyente - First observed
consultar_exoneracion - First observed
obtener_cabys - First observed
tipo_de_cambio
TDQS
Scored across 5 tools
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.
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.
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.
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
Related MCP Connectors
Costa Rica Hacienda v4.4: AI agents submit and query electronic invoices, stateless BYO.
Ecuador factura electronica for AI agents - issue and query SRI e-invoices via Datil. Stateless BYO.
Chile DTE for AI agents - boleta/factura electronica via OpenFactura or LibreDTE. Stateless BYO.
Live & historical FX rates and currency conversion for AI agents. No API keys.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to accept payments in Costa Rica through ONVO Pay, providing tools to create payment links and query payment status.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to submit already-signed Costa Rica electronic invoices (v4.4) to the Ministerio de Hacienda e-invoicing gateway, handling authentication and submission while keeping signing on the user's side.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to issue and query Paraguay SIFEN e-Kuatia electronic invoices through FacturaSend, handling IVA math and stateless forwarding.MIT

Tlaloc MCP Serverofficial
AlicenseNot gradedqualityCmaintenanceProvides 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