Librería profesional de Node.js y servidor MCP para consultar indicadores económicos oficiales de Venezuela (BCV), Colombia (TRM) y Brasil (PTAX). Extrae los datos directamente del Banco Central de Venezuela, del portal de datos abiertos del Gobierno de Colombia y del Banco Central do Brasil, con tipado estricto, reintentos con backoff, caché en memoria activa por defecto, jerarquía de errores tipada y logger basado en interfaz, sin dependencias forzadas.
- Multi-indicador. Tasas oficiales del BCV (
USD,EUR,CNY,TRY,RUB), TRM de Colombia (COP) y dólar PTAX de Brasil (BRL). - Servidor MCP integrado.
npx bcv-exchange-rateexpone las tres fuentes en cuatro tools del Model Context Protocol para Claude, Cursor y cualquier cliente MCP. - CLI incluida. Consulta cualquier fuente desde la terminal (
npx bcv-exchange-rateo el alias globalxrate) con salida JSON apta para scripts. - Historial bancario paginado. Tasas de compra y venta por institución financiera venezolana.
- Reintentos automáticos con backoff exponencial configurable.
- Caché en memoria con TTL por llamada y stale-while-error opcional.
- Jerarquía de errores tipada (
NetworkError,TrmApiError,BrlApiError,ValidationError). - Logger basado en interfaz. Compatible con winston, pino, bunyan o
console, sin dependencias forzadas. - TLS seguro por defecto (
strictSSL: true), con desactivación explícita cuando sea necesario. Los fallos de certificado lanzanTlsErrorsin reintentos, con la recomendación del flag en el mensaje, y toda respuesta ecoastrictSSLpara saber si la data se obtuvo sin validación. - Dual CJS/ESM con declaraciones
.d.ts. - Estado por sección (
status.current,status.history) para detectar fallos parciales. - Cobertura del 100 % forzada en CI.
npm install bcv-exchange-rateRequiere Node.js 20 LTS o superior. Si usas winston como logger (opcional):
npm install winstonimport { getBcvRates, getTrmRates, getBrlRates } from 'bcv-exchange-rate';
const bcv = await getBcvRates({ currencies: 'USD', includeHistory: false });
console.log(`USD/VES: ${bcv.current.USD} (vigencia ${bcv.effectiveDate})`);
const trm = await getTrmRates({ limit: 1 });
console.log(`TRM: ${trm?.current.value} COP`);
const brl = await getBrlRates({ days: 7 });
console.log(`PTAX venta: ${brl?.current.sell} BRL por USD (${brl?.current.dateTime})`);Versión CommonJS:
const { getBcvRates } = require('bcv-exchange-rate');const bcv = await getBcvRates({
currencies: ['USD', 'EUR'],
retries: 3,
retryDelayMs: 500,
cacheTtlMs: 60_000,
cacheStaleTtlMs: 10 * 60_000,
});
if (bcv.status.current === 'failed') {
console.warn('Tasa actual no disponible; se usa el historial como alternativa');
}Consulta cualquier fuente directamente desde la terminal con npx (o con xrate si lo instalas global):
npx bcv-exchange-rate # tasas BCV (comando por defecto) + histórico
npx bcv-exchange-rate bcv --currencies USD,EUR --days 3 --no-history
npx bcv-exchange-rate history --days 3 # solo histórico bancario BCV
npx bcv-exchange-rate trm --limit 5 # TRM de Colombia
npx bcv-exchange-rate brl --days 30 --limit 5 --offset 5 # dólar PTAX de Brasil, paginado
npx bcv-exchange-rate --help # todos los comandos y flagsLa salida es JSON formateado por stdout (exit 0); los errores van por stderr (exit 1), apto para pipes y scripts.
Instalación global con alias corto:
npm install -g bcv-exchange-rate
xrate # equivale a "xrate bcv"
xrate trm --limit 1Flags globales de todos los comandos: --timeout MS (default 25000), --retries N (default 2). Los comandos del BCV aceptan --strict-ssl para activar la validación TLS (desactivada por defecto en la CLI: el portal del BCV sirve una cadena de certificados incompleta).
El mismo binario es un servidor Model Context Protocol por stdio: cuando lo lanza un cliente MCP (stdin por pipe, sin argumentos) sirve el protocolo automáticamente; cuando lo ejecuta una persona en una terminal interactiva actúa como CLI.
Claude Code:
claude mcp add bcv-exchange-rate -- npx bcv-exchange-rateClaude Desktop / Cursor / cualquier cliente con mcpServers (claude_desktop_config.json, .mcp.json, etc.):
{
"mcpServers": {
"bcv-exchange-rate": {
"command": "npx",
"args": ["bcv-exchange-rate"]
}
}
}Tasas de cambio oficiales del Banco Central de Venezuela (VES por unidad de divisa) y, opcionalmente, el histórico informativo del sistema bancario.
| Atributo | Tipo | Default | Descripción |
|---|---|---|---|
currencies |
("USD" | "EUR" | "CNY" | "TRY" | "RUB")[] |
todas | Códigos de moneda a incluir. |
includeCurrent |
boolean |
true |
Incluir las tasas actuales de la portada del BCV. |
includeHistory |
boolean |
true |
Incluir el histórico bancario. |
days |
integer ≥ 1 |
7 |
Ventana de días del histórico. |
page |
integer ≥ 0 |
0 |
Página del histórico. |
strictSSL |
boolean |
false |
Validación TLS. El portal del BCV sirve una cadena de certificados incompleta, por lo que el servidor MCP la desactiva por defecto (la librería mantiene true). |
timeout |
integer ≥ 1 |
25000 |
Timeout de la petición en ms. |
retries |
integer ≥ 0 |
2 |
Reintentos ante fallos transitorios. |
cacheTtlMs |
integer ≥ 0 |
60000 |
TTL de caché fresca en ms; 0 desactiva la caché. |
Solo las tasas informativas históricas del sistema bancario venezolano (compra/venta por banco y fecha).
| Atributo | Tipo | Default | Descripción |
|---|---|---|---|
days |
integer ≥ 1 |
7 |
Ventana de días hacia atrás. |
page |
integer ≥ 0 |
0 |
Página del listado. |
strictSSL |
boolean |
false |
Validación TLS (ver nota en get_bcv_rates). |
timeout |
integer ≥ 1 |
25000 |
Timeout de la petición en ms. |
retries |
integer ≥ 0 |
2 |
Reintentos ante fallos transitorios. |
cacheTtlMs |
integer ≥ 0 |
60000 |
TTL de caché fresca en ms; 0 desactiva la caché. |
Tasa Representativa del Mercado (COP por USD) desde el portal de datos abiertos del Gobierno de Colombia (datos.gov.co).
| Atributo | Tipo | Default | Descripción |
|---|---|---|---|
limit |
integer 1-1000 |
10 |
Máximo de registros a devolver. |
offset |
integer ≥ 0 |
0 |
Desplazamiento de paginación. |
days |
integer ≥ 1 |
sin filtro | Ventana de días hacia atrás (vigenciahasta >=). |
timeout |
integer ≥ 1 |
25000 |
Timeout de la petición en ms. |
retries |
integer ≥ 0 |
2 |
Reintentos ante fallos transitorios. |
cacheTtlMs |
integer ≥ 0 |
60000 |
TTL de caché fresca en ms; 0 desactiva la caché. |
Cotización oficial USD/BRL (dólar PTAX, compra y venta) desde la API de datos abiertos del Banco Central do Brasil. Devuelve null cuando la ventana no contiene cotizaciones (fines de semana o feriados).
| Atributo | Tipo | Default | Descripción |
|---|---|---|---|
days |
integer ≥ 1 |
7 |
Ventana de días hacia atrás. |
limit |
integer 1-1000 |
toda la ventana | Máximo de registros a devolver (OData $top). |
offset |
integer ≥ 0 |
0 |
Registros a saltar para paginar (OData $skip). |
timeout |
integer ≥ 1 |
25000 |
Timeout de la petición en ms. |
retries |
integer ≥ 0 |
2 |
Reintentos ante fallos transitorios. |
cacheTtlMs |
integer ≥ 0 |
60000 |
TTL de caché fresca en ms; 0 desactiva la caché. |
Todas las tools devuelven el payload por partida doble: como JSON en el contenido de texto y como structuredContent.data validado contra el outputSchema que cada tool declara en tools/list — el servidor es autodescriptivo y cualquier cliente o agente puede integrarse desde esa respuesta sin documentación externa. Los errores de la librería (red, TLS, validación, parseo) se reportan como respuestas MCP con isError: true sin tumbar el servidor.
Especificación completa a nivel de protocolo (handshake, esquemas de salida, intercambios reales y recetas para agentes): docs/mcp.md.
Las tres fuentes comparten el mismo esqueleto de salida. Los campos que no aplican al paradigma de una fuente son null (nunca se omiten), de modo que el shape es idéntico:
{
current: ..., // varía por fuente: multi-moneda (BCV), valor (TRM), compra/venta (BRL)
history: [...], // ítems propios de cada fuente
pagination: {
limit: number | null, // null: no solicitado, o la fuente pagina por página (BCV)
offset: number | null, // null: la fuente pagina por página (BCV)
page: number | null, // null: la fuente pagina por limit/offset (TRM, BRL)
count: number, // registros devueltos
hasMore: boolean | null // null: la fuente no puede saberlo (TRM, BRL)
},
range: { startDate, endDate } | null, // ventana de días aplicada (ISO 8601)
strictSSL: boolean // false = la data se obtuvo SIN validación TLS
}| Campo | BCV | TRM | BRL |
|---|---|---|---|
pagination.limit / offset |
null (usa page) |
reales | reales (limit: null si no se pidió) |
pagination.page |
real | null |
null |
pagination.hasMore |
real (pager del portal) | null |
null |
range |
ventana de days |
ventana de days o null sin filtro |
ventana de days |
BcvResponse añade además effectiveDate y status (fallos parciales por sección).
- Un certificado expirado, autofirmado o con cadena incompleta lanza
TlsErrorde inmediato (sin gastar reintentos: el fallo es determinista). El mensaje incluye la recomendación: reintentar constrictSSL: false(librería/tools MCP) o sin--strict-ssl(CLI) si aceptas el riesgo. - En
getBcvRatescon ambas secciones, un fallo TLS en una sección no tumba la otra: se marcastatus.<sección>: 'failed'y el resto se entrega. - El campo
strictSSLde la respuesta indica siempre cómo se obtuvo la data:falsesignifica que la validación TLS estuvo desactivada en esa llamada.
La documentación extendida vive en docs/:
- Logging y observabilidad
- Manejo de errores
- Caché y resiliencia
- Reintentos y resiliencia
- Seguridad y TLS
- Uso con TypeScript
npm install
npm test # Jest con cobertura del 100 % forzada.
npm run lint # ESLint.
npm run format # Prettier.
npm run build # Dual CJS/ESM, declaraciones, CLI y servidor MCP.Más detalles en CONTRIBUTING.md.
Reporta vulnerabilidades según lo descrito en SECURITY.md. No abras incidencias públicas para problemas de seguridad.
José Carrillo — Senior Fullstack Developer y Tech Lead con más de diez años de experiencia construyendo software escalable, eficiente y seguro.
Stack habitual: NestJS, Go, React, React Native, Kotlin, Swift y Python sobre PostgreSQL y MongoDB.
Proyectos adicionales: carrillo.app/proyectos. Publicaciones técnicas: github.com/carrilloapps/papers. CV: carrillo.app/cv.pdf.
Si esta librería te resulta útil, puedes invitarme un café o patrocinar el desarrollo continuo:
Distribuida bajo la licencia MIT. © José Carrillo.