MCP - Model Context Protocol
Introducción
El servidor MCP de Bitnovo Pay permite a los agentes de IA interactuar con la API de Bitnovo Pay para crear y gestionar pagos con criptomonedas de forma autónoma. Esta integración facilita la automatización de pagos cripto en aplicaciones que utilizan modelos de lenguaje como ChatGPT, Claude, o Gemini.
Versión actual: v1.1.0 | Última actualización: 30 de septiembre de 2025
¿Qué es MCP?
Model Context Protocol (MCP) es un protocolo estándar abierto que permite a los modelos de IA acceder a herramientas y servicios externos de forma estructurada y segura.
Conceptos clave de MCP
MCP Server
Proceso que expone capacidades (herramientas, recursos) a través del protocolo MCP vía stdio
MCP Tools
Funciones que el modelo de IA puede invocar (ej: create_payment_link)
MCP Resources
Datos que el servidor puede proveer al modelo (ej: catálogo de criptomonedas)
stdio Transport
Comunicación entre cliente y servidor MCP usando entrada/salida estándar
El servidor MCP de Bitnovo Pay implementa este protocolo para exponer 8 herramientas MCP que permiten gestión completa de pagos cripto desde cualquier cliente MCP compatible.
Inicio Rápido (5 minutos)
Paso 1: Obtén tus credenciales
Crea cuenta en Bitnovo Pay
Obtén tu Device ID desde el panel de Bitnovo
(Opcional) Genera Device Secret para webhooks
Paso 2: Configura tu cliente MCP
Agrega esta configuración a tu cliente MCP (ejemplo para Claude Desktop):
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["-y", "@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com"
}
}
}
}Ubicación del archivo de configuración:
Claude Desktop (macOS):
~/Library/Application Support/Claude/claude_desktop_config.jsonClaude Desktop (Windows):
%APPDATA%\Claude\claude_desktop_config.jsonOpenAI ChatGPT:
~/.config/openai/mcp-config.jsonGoogle Gemini:
~/.config/gemini/mcp-config.json
Paso 3: Reinicia tu cliente MCP
Reinicia Claude Desktop, ChatGPT, o tu cliente MCP para cargar el servidor.
Paso 4: ¡Prueba!
Pregunta a tu asistente IA:
"Crea un pago de 10 euros"
✅ Deberías recibir una URL de pago lista para compartir.
Características principales
8 herramientas MCP para gestión completa de pagos:
create_payment_onchain- Genera direcciones de criptomonedas para pagos directoscreate_payment_link- Crea URLs de pago web con gestión de redireccionesget_payment_status- Consulta el estado de un pago con información detalladalist_currencies_catalog- Obtiene las criptomonedas soportadas con filtradogenerate_payment_qr- Genera códigos QR personalizados desde pagos existentesget_webhook_events- Consulta eventos de webhook recibidos en tiempo realget_webhook_url- Obtiene la URL pública del webhook con instrucciones de configuraciónget_tunnel_status- Diagnostica el estado de la conexión del túnel
Sistema de webhooks automático con 3 proveedores de túnel:
🔗 ngrok: URL persistente gratuita (1 dominio estático por cuenta)
🌐 zrok: Open-source 100% gratuito con URLs persistentes
🏢 manual: Para servidores con IP pública (N8N, Opal, VPS)
Compatible con múltiples LLMs:
🤖 OpenAI ChatGPT (GPT-5, GPT-4o, Responses API, Agents SDK)
🧠 Google Gemini (Gemini 2.5 Flash/Pro Sept 2025, CLI, FastMCP)
🔮 Claude (Claude Desktop, Claude Code)
Códigos QR de alta calidad (v1.1.0+):
📱 Resolución por defecto de 512px (mejorada desde 300px) para pantallas modernas
🖨️ Soporte hasta 2000px para impresión profesional
✨ Bordes nítidos con algoritmos de interpolación optimizados
🎨 Branding personalizado de Bitnovo Pay con escalado suave de logo
Seguridad y privacidad:
Comunicación HTTPS obligatoria
Validación de firmas HMAC para webhooks
Prevención de ataques de replay con caché de nonces
Datos sensibles enmascarados en logs
Sin almacenamiento local (operación stateless)
Requisitos previos
✅ Node.js 18+
Runtime de JavaScript
Ejecutar servidor MCP
✅ Device ID
Identificador de dispositivo del panel
Todas las operaciones
⚠️ Device Secret
Secret HMAC (opcional)
Webhooks con validación
✅ Cliente MCP
Claude, ChatGPT, o Gemini
Interactuar con servidor
⚠️ ngrok/zrok (opcional)
Túnel para webhooks
Desarrollo local con webhooks
Inicio rápido: Solo necesitas Node.js 18+ y credenciales de Bitnovo para comenzar. Los webhooks son opcionales.
Instalación
Hay dos formas de instalar el servidor MCP de Bitnovo Pay:
Opción 1: Usar npx (Recomendado)
Recomendado para la mayoría de usuarios - Forma más sencilla y siempre actualizada
No requiere instalación previa, solo necesitas configurar tu cliente MCP (ver sección "Configuración por plataforma" más abajo) usando:
npx -y @bitnovopay/mcp-bitnovo-pay✅ Ventajas:
Siempre obtienes la última versión publicada
No requiere clonar el repositorio
No requiere compilar el código
Actualización automática en cada ejecución
Perfecto para usuarios finales
Opción 2: Clonar el repositorio (Para desarrollo)
Solo para desarrolladores - Requiere conocimientos de TypeScript y Node.js
Si necesitas modificar el código o contribuir al proyecto:
# Clonar el repositorio
git clone https://github.com/bitnovo/mcp-bitnovo-pay.git
cd mcp-bitnovo-pay
# Instalar dependencias
npm install
# Compilar el proyecto
npm run build
# Ejecutar en modo desarrollo
npm run dev✅ Ventajas:
Control total del código fuente
Permite modificaciones y desarrollo local
Ideal para contribuir al proyecto
Configuración de credenciales
Obtén tus credenciales desde el panel de Bitnovo Pay:
Device ID: Identificador único de tu comercio
Device Secret: (Requerido para webhooks) Para validación de firmas HMAC
Base URL: URL del entorno (desarrollo o producción)
Configuración por plataforma
OpenAI ChatGPT
Para integrar con ChatGPT (GPT-4o, GPT-5), crea o edita tu archivo de configuración:
Ubicación: ~/.config/openai/mcp-config.json
Opción A: Usando npx (Recomendado)
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com.com",
"BITNOVO_DEVICE_SECRET": "tu_device_secret_hex"
}
}
}
}Soportado desde: Marzo 2025 (GPT-5 desde Agosto 2025)
Google Gemini
Para integrar con Gemini 2.5, configura el archivo de FastMCP:
Ubicación: ~/.config/gemini/mcp-config.json
Opción A: Usando npx (Recomendado)
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com.com",
"BITNOVO_DEVICE_SECRET": "tu_device_secret_hex"
}
}
}
}Soportado desde: Abril 2025 (Modelos Sept 2025)
Claude (Anthropic)
Para integrar con Claude Desktop o Claude Code:
Ubicación macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Ubicación Windows: %APPDATA%\Claude\claude_desktop_config.json
Configuración básica (sin webhooks)
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com.com",
"BITNOVO_DEVICE_SECRET": "tu_device_secret_hex"
}
}
}
}Configuración con webhooks (desarrollo local con ngrok)
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com.com",
"BITNOVO_DEVICE_SECRET": "tu_device_secret_hex",
"WEBHOOK_ENABLED": "true",
"TUNNEL_ENABLED": "true",
"TUNNEL_PROVIDER": "ngrok",
"NGROK_AUTHTOKEN": "tu_token_ngrok",
"NGROK_DOMAIN": "bitnovo-dev.ngrok-free.app"
}
}
}
}Configuración para N8N/Opal/Servidor
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "tu_device_id_aqui",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com.com",
"BITNOVO_DEVICE_SECRET": "tu_device_secret_hex",
"WEBHOOK_ENABLED": "true",
"TUNNEL_ENABLED": "false",
"WEBHOOK_PUBLIC_URL": "https://n8n.empresa.com"
}
}
}
}Soportado desde: 2025
Referencia de herramientas MCP
Herramientas de Pago (5)
1. create_payment_onchain
Crea un pago con dirección de criptomoneda específica para transacciones directas en blockchain.
Usar cuando: El usuario especifica una criptomoneda concreta (Bitcoin, ETH, USDC, etc.)
Parámetros:
{
"amount_eur": 50.0,
"input_currency": "BTC",
"fiat": "EUR",
"notes": "Pago por café",
"include_qr": true
}Respuesta:
{
"identifier": "abc-123-def",
"payment_uri": "bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.001",
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"qr_address": "data:image/png;base64,...",
"qr_payment_uri": "data:image/png;base64,...",
"expected_output_amount": "0.001",
"currency_id": "BTC",
"fiat_amount": "50.00",
"status": "PE"
}Ejemplos de uso:
"Crear un pago en Bitcoin por 50 euros"
"Generar dirección ETH para 100 euros"
"Necesito un QR de USDC para 25 euros"
2. create_payment_link
Crea una URL de pago web donde el cliente puede elegir su criptomoneda preferida.
Usar cuando: Solicitud de pago genérica sin criptomoneda específica mencionada (OPCIÓN POR DEFECTO)
Parámetros:
{
"amount_eur": 50.0,
"fiat": "EUR",
"url_ok": "https://mitienda.com/exito",
"url_ko": "https://mitienda.com/cancelado",
"notes": "Pedido #1234",
"include_qr": true
}Respuesta:
{
"identifier": "abc-123-def",
"web_url": "https://payments.bitnovo.com/pay/abc-123-def",
"qr_web_url": "data:image/png;base64,...",
"fiat_amount": "50.00",
"fiat_currency": "EUR",
"status": "PE"
}Ejemplos de uso:
"Crear un pago de 50 euros"
"Generar QR para cobrar 100 euros"
"Dame el link de pago para 25 euros"
3. get_payment_status
Consulta el estado actual de un pago con información detallada.
Parámetros:
{
"identifier": "abc-123-def"
}Respuesta:
{
"identifier": "abc-123-def",
"status": "CO",
"status_description": "Completed",
"fiat_amount": "50.00",
"crypto_amount": "0.001",
"currency_id": "BTC",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:35:00Z"
}Estados posibles:
NR(Not Ready): Pre-pago creado, sin cripto asignadaPE(Pending): Esperando pago del clienteAC(Awaiting Completion): Cripto detectada en mempoolCO(Completed): Pago confirmado en blockchainEX(Expired): Tiempo límite de pago excedidoCA(Cancelled): Pago canceladoFA(Failed): Transacción falló al confirmar
Ejemplos de uso:
"¿Cuál es el estado del pago abc-123-def?"
"¿Se completó el pago?"
"Verificar estado de pago"
4. list_currencies_catalog
Obtiene el catálogo de criptomonedas disponibles con filtrado opcional por importe.
Parámetros:
{
"filter_by_amount": 25.0
}Respuesta:
{
"currencies": [
{
"symbol": "BTC",
"name": "Bitcoin",
"blockchain": "Bitcoin",
"min_amount": "0.0001",
"max_amount": "10.0",
"decimals": 8
},
{
"symbol": "ETH",
"name": "Ethereum",
"blockchain": "Ethereum",
"min_amount": "0.001",
"max_amount": "100.0",
"decimals": 18
}
]
}Ejemplos de uso:
"¿Qué criptomonedas están disponibles?"
"¿Qué monedas aceptan pagos de 50 euros?"
"Mostrar catálogo de criptos"
5. generate_payment_qr
Genera códigos QR personalizados desde pagos existentes.
Parámetros:
{
"identifier": "abc-123-def",
"qr_type": "both",
"size": 512,
"style": "branded",
"branding": true
}Opciones de qr_type:
address: Solo dirección cripto (cliente ingresa importe manualmente)payment_uri: Dirección + importe incluido (recomendado)both: Genera ambos tipos (recomendado)gateway_url: QR de la URL del gateway de pago
Respuesta:
{
"qr_address": "data:image/png;base64,...",
"qr_payment_uri": "data:image/png;base64,...",
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"payment_uri": "bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.001"
}Ejemplos de uso:
"Generar QR más grande para el pago"
"Crear QR sin branding"
"Necesito un QR de 500px"
Herramientas de Webhook (3)
6. get_webhook_events
Consulta eventos de webhook recibidos en tiempo real desde Bitnovo Pay API.
Disponible cuando: WEBHOOK_ENABLED=true
Parámetros:
{
"identifier": "abc-123-def",
"limit": 50,
"validated_only": true
}Respuesta:
{
"events": [
{
"event_id": "abc-123:1234567890",
"identifier": "abc-123-def",
"status": "CO",
"received_at": "2025-09-30T10:30:00.000Z",
"validated": true,
"payload": {
"identifier": "abc-123-def",
"status": "CO",
"confirmed_amount": 0.0012,
"crypto_amount": 0.0012
}
}
],
"total_count": 1
}Ejemplos de uso:
"¿Ha llegado algún webhook del pago abc-123?"
"Mostrar todos los eventos de webhook"
"¿Se recibió confirmación de pago?"
7. get_webhook_url
Obtiene la URL pública del webhook con instrucciones de configuración para el panel de Bitnovo.
Disponible cuando: WEBHOOK_ENABLED=true
Parámetros:
{
"validate": true
}Respuesta:
{
"webhook_url": "https://bitnovo-dev.ngrok-free.app/webhook/bitnovo",
"provider": "ngrok",
"validated": true,
"instructions": "✅ ngrok tunnel activo con URL persistente.\n\nPasos de configuración:\n1. Copiar esta URL: https://bitnovo-dev.ngrok-free.app/webhook/bitnovo\n2. Entrar en https://pay.bitnovo.com\n3. Ir a: Configuración → Comercio → Dispositivos\n4. Seleccionar dispositivo\n5. Configurar 'notification_url' con la URL\n\nNota: Esta URL es persistente y no cambiará entre reinicios."
}Ejemplos de uso:
"¿Cuál es mi URL de webhook?"
"Dame la URL para configurar en Bitnovo"
"¿Cómo configuro los webhooks?"
8. get_tunnel_status
Diagnostica el estado de la conexión del túnel (ngrok, zrok o manual).
Disponible cuando: WEBHOOK_ENABLED=true
Parámetros: Ninguno
Respuesta:
{
"enabled": true,
"provider": "ngrok",
"status": "connected",
"public_url": "https://bitnovo-dev.ngrok-free.app",
"connected_at": "2025-09-30T10:30:00.000Z",
"last_error": null,
"reconnect_attempts": 0,
"health_check_enabled": true,
"context_detected": {
"execution_context": "local",
"confidence": 0.7,
"suggested_provider": "ngrok",
"indicators": ["Local development environment detected"]
}
}Estados de conexión:
disconnected: Túnel no iniciadoconnecting: Túnel inicializandoconnected: Túnel activo y saludablereconnecting: Conexión perdida, intentando reconectarerror: Falló después de máximo de reintentos
Ejemplos de uso:
"¿Está funcionando el túnel de webhooks?"
"¿Cuál es el estado de la conexión?"
"Diagnosticar problemas de túnel"
Sistema de Webhooks y Túneles
Arquitectura Dual-Server
El servidor MCP puede ejecutar dos servidores simultáneamente:
┌─────────────────────────────────────────────────────────┐
│ MCP Bitnovo Pay Server │
│ │
│ ┌──────────────┐ ┌──────────────────┐ ┌────────────┐│
│ │ MCP Server │ │ Webhook Server │ │ Tunnel ││
│ │ (stdio) │ │ (HTTP :3000) │ │ Manager ││
│ └──────┬───────┘ └────────┬─────────┘ └──────┬─────┘│
│ │ │ │ │
│ │ Event Store │ Public URL │ │
│ │ (in-memory) │ (ngrok/zrok) │ │
│ └──────────┬────────┴──────────┬────────┘ │
└────────────────────┼───────────────────┼───────────────┘
│ │
┌────────┴────────┐ ┌───────┴────────┐
│ │ │ │
Claude Desktop Bitnovo API Tunnel Provider
(MCP Tools) (Webhooks) (ngrok/zrok/manual)Proveedores de Túnel
Comparación de Proveedores
ngrok
Gratis (1 dominio estático)
✅ Sí
Desarrollo local
~99% uptime
zrok
100% Gratis
✅ Sí (reserved shares)
Preferencia open-source
Media-alta
manual
Depende del hosting
✅ Sí
Servidores con IP pública
Dependiente del servidor
1. ngrok (Recomendado para Desarrollo Local)
Características:
✅ Dominio estático gratuito (1 por cuenta desde 2023)
✅ URL persistente (no cambia en reinicios)
✅ Alta confiabilidad (~99% uptime)
✅ Timeout de 24 horas (auto-reconexión maneja esto)
Configuración:
TUNNEL_ENABLED=true
TUNNEL_PROVIDER=ngrok
NGROK_AUTHTOKEN=tu_token_ngrok
NGROK_DOMAIN=bitnovo-dev.ngrok-free.app # Tu dominio estático gratuitoSetup:
Crear cuenta en ngrok.com
Obtener authtoken del dashboard
Reclamar dominio estático gratuito en domains
2. zrok (Alternativa Open-Source)
Características:
✅ 100% Gratuito (sin límites en reserved shares)
✅ URL persistente con unique-name
✅ Open-source (construido sobre OpenZiti)
✅ Estabilidad media-alta (mejorando con cada release)
Configuración:
TUNNEL_ENABLED=true
TUNNEL_PROVIDER=zrok
ZROK_TOKEN=tu_token_zrok
ZROK_UNIQUE_NAME=bitnovo-webhooks # Tu nombre de share reservado
# Resulta en URL persistente:
# https://bitnovo-webhooks.share.zrok.io/webhook/bitnovoSetup:
Crear cuenta en myzrok.io
Instalar zrok CLI:
brew install openziti/zrok/zrokHabilitar cuenta:
zrok enable TU_TOKENReservar share:
zrok reserve public --unique-name bitnovo-webhooks 3000
3. manual (Servidores con IP Pública)
Mejor Para:
Instancias de N8N
Despliegues de Opal
Servidores VPS/cloud
Docker con ingress
Kubernetes con LoadBalancer
Auto-detección de Entornos:
El sistema detecta automáticamente estos entornos:
N8N
Variables N8N_HOST o N8N_PROTOCOL
Opal
Variables OPAL_WEBHOOK_URL o OPAL_HOST
Kubernetes
Variable KUBERNETES_SERVICE_HOST
Docker
Archivo /.dockerenv o DOCKER_HOST
VPS/Server
Múltiples indicadores (systemd, PM2, etc.)
Configuración:
WEBHOOK_ENABLED=true
TUNNEL_ENABLED=false # o TUNNEL_PROVIDER=manual
WEBHOOK_PUBLIC_URL=https://n8n.empresa.com # URL pública del servidorSeguridad de Webhooks
Validación HMAC-SHA256
Todos los webhooks se validan usando:
signature = hex(hmac_sha256(device_secret, nonce + raw_body))Proceso de validación:
Extraer nonce y signature de headers
X-NONCEyX-SIGNATURECalcular signature esperada usando device_secret
Comparar usando comparación timing-safe
Rechazar si las signatures no coinciden (401 Unauthorized)
Prevención de Ataques de Replay
Caché de nonces: Almacena nonces usados por 5 minutos
Detección de duplicados: Rechaza webhooks con nonces ya utilizados
Deduplicación de eventos: Mismo evento recibido múltiples veces se almacena una vez
¿Por qué las URLs Públicas son Seguras?
Pregunta: "¿No enviarán actores maliciosos webhooks falsos a mi URL pública?"
Respuesta: No, porque:
Validación HMAC asegura que solo Bitnovo (con tu device_secret) puede crear signatures válidas
Sin el device_secret, atacantes no pueden generar signatures válidas
Todas las requests sin signatures válidas son rechazadas (401 Unauthorized)
Prevención de replay de nonces detiene reutilización de requests válidas capturadas
Modelo de Seguridad:
Atacante envía webhook falso → Signature faltante/inválida → 401 Rechazado ✅
Atacante replica webhook capturado → Nonce ya usado → 401 Rechazado ✅
Bitnovo envía webhook → Signature válida + nonce fresco → 200 Aceptado ✅Árbol de decisión para selección de herramienta
REGLA CRÍTICA: ¿El usuario menciona explícitamente una criptomoneda?
Usuario menciona cripto específica (Bitcoin, BTC, Ethereum, ETH, USDC, etc.)
→ Usar create_payment_onchain con ese input_currency específico
Usuario NO menciona cripto específica
→ Usar create_payment_link (OPCIÓN POR DEFECTO)
Tabla comparativa de métodos de pago
Retorna
Dirección cripto + QR
URL web
Cliente elige cripto?
No (fijo)
Sí (en gateway)
Mejor para
Pagos cripto específicos
Pagos genéricos (DEFECTO)
Método de compartir
Mostrar QR/dirección
Enviar link
Redirecciones
N/A
Sí (url_ok/url_ko)
Usar cuando
Usuario especifica cripto
NO se menciona cripto
Ejemplos
"Pago en Bitcoin", "Dirección ETH"
"Pago de 24 euros", "Generar QR"
Ejemplos de uso
Ejemplo 1: Pago genérico (sin cripto específica)
Solicitud del usuario:
"Necesito crear un pago de 50 euros"
Herramienta a usar: create_payment_link
Comando:
{
"amount_eur": 50.0,
"notes": "Pago genérico"
}Resultado: URL web donde el cliente puede elegir cualquier criptomoneda disponible.
Ejemplo 2: Pago con Bitcoin específicamente
Solicitud del usuario:
"Crear un pago en Bitcoin por 100 euros"
Herramienta a usar: create_payment_onchain
Comando:
{
"amount_eur": 100.0,
"input_currency": "BTC",
"notes": "Pago en Bitcoin"
}Resultado: Dirección Bitcoin específica + QR con el importe incluido.
Ejemplo 3: Verificar pago con webhooks
Solicitud del usuario:
"¿Se completó el pago abc-123-def?"
Herramienta 1: get_webhook_events
Comando:
{
"identifier": "abc-123-def",
"validated_only": true
}Resultado: Lista de eventos webhook recibidos mostrando estado actualizado en tiempo real.
Alternativa - Herramienta 2: get_payment_status
Comando:
{
"identifier": "abc-123-def"
}Resultado: Estado actual del pago consultado a la API.
Ejemplo 5: Casos de uso por industria
🛒 E-commerce: Pago en checkout
Escenario: Cliente completa compra de €150, necesita flexibilidad de criptomoneda
Herramienta: create_payment_link
{
"amount_eur": 150.0,
"url_ok": "https://tienda.com/pedido/12345/confirmado",
"url_ko": "https://tienda.com/pedido/12345/cancelado",
"notes": "Pedido #12345 - Auriculares Bluetooth"
}Flujo:
Cliente confirma pedido → AI genera payment link
Cliente elige criptomoneda preferida en gateway
Realiza pago con wallet
Gateway redirige a
url_oktras confirmaciónSistema procesa pedido automáticamente
☕ Café/Restaurante: Propinas en Bitcoin
Escenario: Cliente quiere dejar €5 de propina en Bitcoin
Herramienta: create_payment_onchain
{
"amount_eur": 5.0,
"input_currency": "BTC",
"notes": "Propina - Mesa 7"
}Flujo:
Mesero solicita QR de propina → AI genera dirección BTC
Cliente escanea QR con wallet Bitcoin
Pago se confirma en minutos
Sistema notifica via webhook al mesero
💼 Freelance: Factura internacional en stablecoins
Escenario: Freelancer cobra $500 USD por proyecto, prefiere USDC
Herramienta: create_payment_onchain
{
"amount_eur": 500.0,
"input_currency": "USDC_ERC20",
"fiat": "USD",
"notes": "Factura #2025-001 - Desarrollo web"
}Flujo:
Cliente internacional recibe dirección USDC
Transfiere desde exchange o wallet
Confirmación en blockchain
Freelancer recibe fondos sin intermediarios
🎮 Gaming: Compras in-game
Escenario: Jugador compra skin de €25, elige criptomoneda
Herramienta: create_payment_link
{
"amount_eur": 25.0,
"notes": "Compra in-game - Dragon Skin Legendary",
"include_qr": true
}Flujo:
Jugador selecciona skin → AI genera QR + link
Paga con su crypto preferida (BTC, ETH, etc.)
Sistema detecta pago via webhook
Unlock automático de item en cuenta
🏨 Hotel: Reserva con depósito
Escenario: Reserva de habitación con depósito de €200
Herramienta: create_payment_link
{
"amount_eur": 200.0,
"url_ok": "https://hotel.com/reservas/confirm/789",
"url_ko": "https://hotel.com/reservas/cancel/789",
"notes": "Depósito reserva - Suite Presidencial 15-20 Octubre"
}Flujo:
Cliente reserva → AI genera payment link
Cliente paga depósito en criptomoneda preferida
Confirmación automática de reserva
Check-in sin fricción
Ejemplo 6: Monitoreo de pagos en tiempo real
Escenario: Sistema de punto de venta monitoring payments
Flujo completo:
// 1. Crear pago
create_payment_link({
amount_eur: 50.0,
notes: "POS Sale #4567"
})
// → Identifier: "abc-123-def"
// 2. Monitorear con webhooks (recomendado)
get_webhook_events({
identifier: "abc-123-def",
validated_only: true
})
// → Recibe eventos en tiempo real
// 3. Verificar estado manualmente (alternativa)
get_payment_status({
identifier: "abc-123-def"
})
// → Status: "CO" (Completed)
// 4. Confirmar pago completado
// → Sistema actualiza inventario, imprime reciboEjemplo 4: Configurar webhooks
Solicitud del usuario:
"¿Cómo configuro los webhooks en Bitnovo?"
Herramienta: get_webhook_url
Comando:
{
"validate": true
}Resultado: URL del webhook + instrucciones paso a paso para configurar en panel de Bitnovo.
Arquitectura técnica
Capas del sistema
┌─────────────────┐
│ MCP Tools │ ← 8 herramientas: 5 de pago + 3 de webhook
│ (src/tools/) │
├─────────────────┤
│ Services │ ← Lógica de negocio: PaymentService, CurrencyService
│ (src/services/) │
├─────────────────┤
│ API Client │ ← Integración con API de Bitnovo con retry logic
│ (src/api/) │
├─────────────────┤
│ Webhook Server │ ← Servidor HTTP Express + Event Store + Tunnel Manager
│ (src/webhook-*) │
├─────────────────┤
│ Utilities │ ← Logging, validación, manejo de errores, crypto
│ (src/utils/) │
└─────────────────┘Flujo de datos
Pagos:
Solicitud de herramienta → Validación → Capa de servicio → Cliente API → API de Bitnovo
Respuesta → Manejo de errores → Transformación de datos → Respuesta JSON
Logging: Todas las operaciones registradas con enmascaramiento de datos sensibles
Webhooks:
Bitnovo envía webhook → Túnel (ngrok/zrok) → Webhook Server (HTTP :3000)
Validación HMAC → Verificación de nonce → Almacenamiento en Event Store
Consulta via MCP → get_webhook_events → Datos del Event Store
Variables de entorno
Variables Requeridas
BITNOVO_DEVICE_ID=tu_device_id_aqui # Requerido
BITNOVO_BASE_URL=https://pos.bitnovo.com.com # RequeridoVariables de Webhook (Opcionales)
# Habilitar webhooks
WEBHOOK_ENABLED=true
WEBHOOK_PORT=3000
WEBHOOK_HOST=0.0.0.0
WEBHOOK_PATH=/webhook/bitnovo
# Seguridad
BITNOVO_DEVICE_SECRET=tu_device_secret_hex # Requerido para webhooks
# Event store
WEBHOOK_MAX_EVENTS=1000
WEBHOOK_EVENT_TTL_MS=3600000 # 1 horaVariables de Túnel (Opcionales)
# Configuración de túnel
TUNNEL_ENABLED=true
TUNNEL_PROVIDER=ngrok # Opciones: ngrok, zrok, manual
# ngrok específico
NGROK_AUTHTOKEN=tu_token_ngrok
NGROK_DOMAIN=bitnovo-dev.ngrok-free.app # Opcional: dominio estático gratuito
# zrok específico
ZROK_TOKEN=tu_token_zrok
ZROK_UNIQUE_NAME=bitnovo-webhooks # Tu nombre de share reservado
# manual provider
WEBHOOK_PUBLIC_URL=https://n8n.empresa.com # Para provider manual
# Monitoreo de salud y reconexión
TUNNEL_HEALTH_CHECK_INTERVAL=60000 # 60 segundos (default)
TUNNEL_RECONNECT_MAX_RETRIES=10 # Máximo intentos de reintento
TUNNEL_RECONNECT_BACKOFF_MS=5000 # Delay inicial de backoff🔒 Seguridad
La seguridad es una prioridad fundamental del servidor MCP de Bitnovo Pay. Implementamos múltiples capas de protección para garantizar transacciones seguras.
IMPORTANTE: Nunca expongas tus credenciales en repositorios públicos, logs o configuraciones compartidas.
🛡️ Principios de Seguridad Implementados
1. Comunicación Segura
✅ HTTPS obligatorio: Todas las llamadas a la API usan HTTPS exclusivamente
✅ No HTTP: Requests HTTP son rechazadas automáticamente
✅ TLS 1.2+: Comunicación cifrada con protocolos modernos
2. Validación de Webhooks HMAC-SHA256
Los webhooks están protegidos con firmas criptográficas HMAC:
signature = hex(hmac_sha256(device_secret, nonce + raw_body))Proceso de validación:
Bitnovo envía webhook con headers
X-NONCEyX-SIGNATUREServidor calcula signature esperada usando
BITNOVO_DEVICE_SECRETComparación timing-safe entre signatures
Rechazo inmediato si no coinciden (401 Unauthorized)
3. Prevención de Ataques de Replay
✅ Caché de nonces: Almacena nonces usados por 5 minutos
✅ Detección de duplicados: Rechaza webhooks con nonces ya utilizados
✅ Deduplicación de eventos: Mismo evento recibido múltiples veces se almacena una vez
Ejemplo de ataque rechazado:
Atacante replica webhook válido → Nonce ya usado → 401 Rechazado ✅4. Privacidad de Datos
✅ Logs enmascarados: Device IDs, secrets, y direcciones cripto parcialmente ocultas
✅ Sin exchange rates: No se exponen tasas de cambio para prevenir inexactitudes
✅ Diseño stateless: Sin persistencia local, consultas en tiempo real a la API
✅ Datos mínimos: Solo se solicitan datos necesarios para operación
Ejemplo de log enmascarado:
[INFO] Payment created for device: 12345678-****-****-****-********90ab
[INFO] Webhook validated with signature: a3f2c1...******5. Resiliencia y Disponibilidad
✅ Timeouts: 5 segundos máximo por operación API
✅ Reintentos inteligentes: Máximo 2 reintentos con backoff exponencial
✅ Auto-reconexión de túneles: Backoff exponencial hasta 10 reintentos
✅ Health monitoring: Verificación cada 60 segundos de conexión de túnel
🔐 Configuración Segura de Credenciales
Buenas prácticas de seguridad:
✅ Usa variables de entorno, nunca hardcodees secrets
✅ Rota
BITNOVO_DEVICE_SECRETregularmente✅ Usa URLs de producción (
https://pos.bitnovo.com) en entornos productivos✅ Limita acceso al archivo de configuración MCP (permisos 600)
❌ NUNCA compartas
BITNOVO_DEVICE_SECRETen logs, repos, o mensajes
Permisos recomendados para archivo de configuración:
# Claude Desktop config (macOS)
chmod 600 ~/Library/Application\ Support/Claude/claude_desktop_config.json
# OpenAI ChatGPT config
chmod 600 ~/.config/openai/mcp-config.json🌐 Seguridad de Túneles Públicos
Pregunta frecuente: "¿No es inseguro exponer una URL pública para webhooks?"
Respuesta: No, gracias a la validación HMAC:
Atacante envía webhook falso
❌ Signature inválida → 401 Rechazado
Atacante replica webhook capturado
❌ Nonce ya usado → 401 Rechazado
Bitnovo envía webhook legítimo
✅ Signature válida + nonce fresco → 200 Aceptado
Conclusión: Solo Bitnovo (con tu BITNOVO_DEVICE_SECRET) puede generar webhooks válidos.
📋 Checklist de Seguridad
Antes de usar en producción, verifica:
🔧 Solución de Problemas
Problemas Comunes y Soluciones
❌ Error: "MCP server not found" o "Server failed to start"
Causa: El servidor MCP no puede inicializarse.
Soluciones:
Verifica que Node.js 18+ esté instalado:
node --versionPrueba ejecutar manualmente:
npx -y @bitnovopay/mcp-bitnovo-payRevisa que las variables de entorno estén correctamente configuradas
Busca errores en logs de tu cliente MCP (Claude Desktop:
~/Library/Logs/Claude/)
Ejemplo de configuración correcta:
{
"mcpServers": {
"bitnovo-pay": {
"command": "npx",
"args": ["-y", "@bitnovopay/mcp-bitnovo-pay"],
"env": {
"BITNOVO_DEVICE_ID": "12345678-abcd-...",
"BITNOVO_BASE_URL": "https://pos.bitnovo.com"
}
}
}
}❌ Error: INVALID_DEVICE_ID
Causa: Device ID incorrecto o no válido.
Soluciones:
Copia el Device ID desde el panel de Bitnovo Pay
Verifica que sea un UUID válido (formato:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)Asegúrate de no incluir espacios antes/después del ID
Confirma que estás usando el dispositivo correcto para el entorno (dev/prod)
❌ Error: CURRENCY_NOT_SUPPORTED
Causa: Criptomoneda solicitada no disponible.
Soluciones:
Usa
list_currencies_catalogpara ver opciones disponiblesVerifica el símbolo exacto (ej:
BTC, noBitcoinobtc)Confirma que la moneda esté activa en tu cuenta de Bitnovo
Ejemplo:
// ❌ Incorrecto
{ "input_currency": "Bitcoin" }
// ✅ Correcto
{ "input_currency": "BTC" }❌ Error: AMOUNT_TOO_LOW / AMOUNT_TOO_HIGH
Causa: Importe fuera de los límites de la criptomoneda.
Soluciones:
Consulta límites con
list_currencies_catalogAjusta el importe dentro del rango permitido
Para pagos grandes, considera dividir en múltiples transacciones
Ejemplo de consulta de límites:
// Request
{ "filter_by_amount": 50.0 }
// Response muestra min_amount y max_amount
[
{
"symbol": "BTC",
"min_amount": 0.01,
"max_amount": null // Sin límite superior
}
]❌ Error: PAYMENT_EXPIRED
Causa: El pago superó el tiempo límite de expiración.
Soluciones:
Crea un nuevo pago con
create_payment_onchainocreate_payment_linkAvisa a tu cliente sobre el tiempo límite antes de que expire
Usa
get_payment_statuspara monitorear el campoexpires_at
Importante: Los pagos onchain con criptomoneda específica inician su timer inmediatamente al crearse. Comunica esto al usuario.
❌ Error: WEBHOOK_NOT_ENABLED
Causa: Intentas usar herramientas de webhook sin habilitarlos.
Soluciones:
Agrega
"WEBHOOK_ENABLED": "true"a la configuración(Opcional) Configura túnel con
TUNNEL_ENABLEDy proveedorReinicia el servidor MCP
Configuración mínima de webhooks:
{
"env": {
"BITNOVO_DEVICE_ID": "...",
"BITNOVO_BASE_URL": "...",
"BITNOVO_DEVICE_SECRET": "...",
"WEBHOOK_ENABLED": "true"
}
}❌ Error: TUNNEL_CONNECTION_FAILED
Causa: Fallo al conectar con ngrok o zrok.
Soluciones ngrok:
Verifica tu authtoken:
ngrok config checkConfirma que tu dominio estático esté reclamado en ngrok dashboard
Prueba manualmente:
ngrok http --domain=tu-dominio.ngrok-free.app 3000
Soluciones zrok:
Verifica que zrok esté habilitado:
zrok statusConfirma que el share reservado exista:
zrok share reservedPrueba conexión:
zrok share reserved tu-share-name
❌ Error: INVALID_SIGNATURE (webhooks)
Causa: Firma HMAC del webhook no coincide.
Soluciones:
Verifica que
BITNOVO_DEVICE_SECRETsea correcto (64 caracteres hex)Confirma que sea el mismo secret configurado en el panel de Bitnovo
No modifiques el body del webhook antes de validar
Asegúrate de usar el secret del dispositivo correcto (dev/prod)
Códigos de Error Completos
INVALID_DEVICE_ID
Device ID no válido
Verificar credenciales en panel de Bitnovo
INVALID_DEVICE_SECRET
Device Secret incorrecto
Verificar formato hex de 64 caracteres
CURRENCY_NOT_SUPPORTED
Criptomoneda no soportada
Usar list_currencies_catalog
AMOUNT_TOO_LOW
Importe por debajo del mínimo
Aumentar el importe del pago
AMOUNT_TOO_HIGH
Importe por encima del máximo
Reducir el importe o dividir pago
PAYMENT_NOT_FOUND
Pago no encontrado
Verificar el identifier
PAYMENT_EXPIRED
Pago expiró
Crear un nuevo pago
WEBHOOK_NOT_ENABLED
Webhooks no habilitados
Configurar WEBHOOK_ENABLED=true
TUNNEL_CONNECTION_FAILED
Fallo de conexión de túnel
Verificar credenciales de ngrok/zrok
INVALID_SIGNATURE
Firma HMAC inválida
Verificar BITNOVO_DEVICE_SECRET
Formato de Respuesta de Error
Todos los errores siguen el siguiente formato estándar:
{
"error": {
"code": "CURRENCY_NOT_SUPPORTED",
"message": "The specified currency is not supported",
"details": {
"input_currency": "INVALID_COIN",
"supported_currencies": ["BTC", "ETH", "USDC", "..."]
}
}
}Desarrollo
Comandos disponibles
npm run build # Compilar TypeScript a JavaScript
npm run dev # Servidor de desarrollo con hot reload
npm start # Iniciar servidor de producciónRendimiento
Event Store
Almacenamiento: In-memory (rápido, sin persistencia)
Capacidad: 1000 eventos (configurable)
TTL: 1 hora (configurable)
Limpieza: Automática cada 5 minutos
Indexación: Búsqueda rápida por payment identifier
Túneles
ngrok: ~99% uptime, ~10-50ms latencia añadida
zrok: Uptime medio-alto, ~20-100ms latencia añadida
manual: Dependiente del servidor, sin overhead de túnel
Uso de Memoria
Event Store:
Memoria estimada por evento: ~2KB
1000 eventos ≈ 2MB
10000 eventos ≈ 20MB
Tunnel Manager:
ngrok: ~5-10MB overhead
zrok: ~10-20MB overhead (incluye OpenZiti)
manual: ~0MB (sin proceso de túnel)
Soporte y recursos
Repositorio GitHub: github.com/bitnovo/mcp-bitnovo-pay
Soporte Bitnovo: bitnovo.com
Protocolo MCP: modelcontextprotocol.io
Limitaciones conocidas
Operación single-tenant: Un Device ID por instancia del servidor
Sin persistencia local: Todas las consultas son en tiempo real a la API
Sin tasas de cambio: Por privacidad y exactitud, no se exponen exchange rates
Timeouts: 5 segundos máximo por operación API
Reintentos: Máximo 2 reintentos con backoff exponencial
Event Store: In-memory (se pierde en reinicio)
Túneles gratuitos: Limitaciones de cada proveedor aplican
Changelog
v1.1.0 (2025-09-30) - Sistema de Túneles
✅ Gestión automática de túneles con 3 proveedores (ngrok, zrok, manual)
✅ Auto-detección de contexto (N8N, Opal, Docker, Kubernetes, VPS, local)
✅ URLs persistentes con dominios estáticos gratuitos de ngrok y reserved shares de zrok
✅ Auto-reconexión con backoff exponencial (hasta 10 reintentos)
✅ Monitoreo de salud cada 60 segundos con recuperación automática
✅ Nuevas herramientas MCP:
get_webhook_url,get_tunnel_status✅ Configuración cero para escenarios de despliegue comunes
v1.0.0 (2025-09-28) - Implementación Inicial de Webhooks
✅ Implementación inicial de webhooks
✅ Event store (in-memory)
✅ Validación de signatures HMAC
✅ Prevención de ataques de replay
✅ Modo dual-server (stdio + HTTP)
✅ Nueva herramienta MCP:
get_webhook_events✅ Endpoints de health check y stats
Licencia
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
Última actualización: 30 de septiembre de 2025 Versión del servidor: v1.1.0
Última actualización