ohneben's Wafeq MCP
ohneben's Wafeq MCP: gestiona tus libros de Wafeq desde Claude, Cursor o cualquier cliente MCP: los 251 endpoints de la API como herramientas MCP categorizadas por seguridad, a través de stdio o Streamable HTTP, en Docker.
Documentación
MCP de Wafeq de ohneben
Licencia y comprobaciones
Registros MCP
Gestiona tus libros de Wafeq en lenguaje natural desde asistentes de IA como Claude, Cursor y cualquier otro cliente MCP.
Este servidor de Protocolo de Contexto de Modelo expone la API pública de Wafeq — los 251 endpoints completos, generados directamente desde la especificación OpenAPI como herramientas MCP, más dos escritas a mano. Cada herramienta lleva una categoría de seguridad (🟢 solo lectura / 🟡 escritura / 🟠 cambio de estado / 🔴 irreversible o destructiva) para que tu asistente sepa qué hace una acción antes de llamarla — incluyendo la diferencia entre guardar una factura y presentarla ante una autoridad fiscal, algo que ningún envoltorio tipo CRUD puede decirte. Funciona sobre stdio (Claude Desktop y otros lanzadores locales) o HTTP Streamable (alojado en Docker), e incluye reintentos, limitación de velocidad en el cliente, tiempos de espera de solicitud, claves de idempotencia, carga multiparte y manejo de PDF binarios para que resista un libro real.
Por qué lo querrás
Algunos servidores MCP solo reenvían una API. Este está construido para ser seguro de entregar a un LLM y fácil de ejecutar contra datos contables reales:
| Lo que obtienes | Por qué importa |
|---|---|
| Los 251 endpoints, impulsados por especificación | Cobertura completa de facturas, recibos, cotizaciones, notas de crédito y débito, pagos, banca, diarios, nómina, proyectos, inventario e informes — nada seleccionado a mano ni omitido. |
| Nueve categorías de seguridad, no cuatro 🟢 / 🟡 / 🟠 / 🔴 | Una docena de los POST de Wafeq no son creaciones. Las vistas previas no escriben nada; finalizar una amortización anticipadamente publica en el libro mayor sin deshacer; reportar una factura a una autoridad fiscal deja tu organización permanentemente. Cada una tiene su propio aviso en lugar de agruparse con "crear". |
| Instrucciones del servidor enviadas al conectar | Al cliente se le indica cómo leer los avisos de seguridad y las pocas convenciones de Wafeq — formato de fecha, separador decimal, rangos de informes de período completo — de antemano, en lugar de descubrirlas cometiendo un error primero. |
Anotaciones MCP legibles por máquina (readOnlyHint, destructiveHint) | Los hosts que respetan anotaciones (incluido Claude) pueden confiar automáticamente en las 98 herramientas de solo lectura y exigir confirmación antes de cualquiera de las 44 que eliminan o no se pueden deshacer. |
| Parámetros de informe correctos, por informe | Cada uno de los cuatro informes tiene su propio esquema: el balance general toma date + period_count; pérdidas y ganancias y flujo de caja toman date_after + date_before; la balanza de comprobación toma from_date + to_date. Wafeq ignora silenciosamente los parámetros de consulta mal escritos, por lo que un nombre incorrecto parece una llamada que funciona. |
| Validación de período completo antes de enviar | Pérdidas y ganancias y flujo de caja rechazan rangos que no se alinean con meses o años completos. El servidor verifica localmente y responde con el rango válido más cercano en lugar de gastar un viaje de ida y vuelta en un HTTP 400. |
| Claves de idempotencia automáticas | Cada uno de los 146 endpoints de escritura que admiten X-Wafeq-Idempotency-Key recibe un UUID v4 automáticamente, reutilizado entre reintentos — para que un contratiempo de red nunca duplique una factura. Proporciona la tuya propia para que una re-ejecución deliberada también sea segura. |
| Cargas de archivos que realmente funcionan | POST /files/ es solo multiparte y POST /files/raw/ necesita un encabezado Content-Disposition. Ambos se manejan; pasas contenido base64 y un nombre de archivo. |
| PDF binarios manejados como bytes | Los nueve endpoints de PDF se codifican en base64 dentro de un pequeño envoltorio con tamaño y tipo de contenido, en lugar de leerse como texto y corromperse. |
| Reintentos automáticos con retroceso | Las respuestas transitorias 429 / 5xx se reintentan con retroceso exponencial con jitter, respetando Retry-After — con la misma clave de idempotencia, exactamente como exige la guía de integración de Wafeq. |
| Limitación de velocidad integrada | Se auto-limita para que una ráfaga de llamadas de herramientas no dispare un 429. Wafeq no publica un límite numérico, por lo que el predeterminado es deliberadamente conservador y configurable. |
| Inquilino verificado al inicio | Una clave de API de Wafeq está limitada a la organización. El servidor llama a GET /organization/ antes de servir y publica el resultado en /health, para que una clave mal configurada aparezca como un nombre que puedes verificar en lugar de escrituras contra los libros de la empresa equivocada. |
| Dos transportes: stdio y HTTP Streamable | Úsalo localmente en Claude Desktop, o ejecuta un servidor siempre activo al que cualquier número de clientes MCP llegue por HTTP. |
| Docker + docker-compose, verificación de salud, reinicio automático | docker compose up y permanece activo, vinculado solo a localhost. |
| Autenticación opcional con token portador en el endpoint HTTP | Pon el servidor detrás de un secreto compartido en cuanto sea accesible más allá de localhost. |
| Tus secretos nunca llegan al modelo | Las credenciales viven en el entorno del servidor y se inyectan en cada solicitud. La herramienta de paso directo no puede anular Authorization ni apuntar la credencial a otro host. |
| Actualizaciones de especificación sin fricción | ¿Wafeq publica una especificación más nueva? Reemplaza un archivo y reconstruye — los nuevos endpoints se convierten automáticamente en nuevas herramientas, sin cambios de código. |
Cómo se compara
| Capacidad | Este proyecto | Envoltorio genérico OpenAPI→MCP* |
|---|---|---|
| Los 251 endpoints de Wafeq como herramientas | ✅ | ✅ |
| Categoría de seguridad + aviso por herramienta | ✅ | ❌ |
| Presentación ante autoridad fiscal marcada como irreversible, no "crear" | ✅ | ❌ |
Anotaciones MCP readOnlyHint / destructiveHint | ✅ | ➖ |
| Campos de solo lectura eliminados de los cuerpos de crear/actualizar | ✅ | ❌ |
| Prosa de enumeraciones duplicada compactada fuera de los esquemas | ✅ | ❌ |
| Parámetros de fecha correctos, por informe | ✅ | ✅ |
| Rango de período completo validado antes de enviar | ✅ | ❌ |
X-Wafeq-Idempotency-Key automático, estable entre reintentos | ✅ | ❌ |
| Carga de archivos multiparte + binario crudo | ✅ | ➖ |
| Respuestas PDF binarias codificadas en base64, no dañadas | ✅ | ➖ |
| Fechas de transacción recuperadas para partidas de diario | ✅ | ❌ |
Reintentos automáticos en 429 / 5xx (respeta Retry-After) | ✅ | ❌ |
| Limitación de velocidad en el cliente | ✅ | ❌ |
| Identidad de la organización verificada al inicio | ✅ | ❌ |
Transporte stdio | ✅ | ✅ |
| Transporte HTTP Streamable | ✅ | ➖ |
| Docker + docker-compose, verificación de salud, reinicio automático | ✅ | ❌ |
| Autenticación opcional con token portador en el endpoint | ✅ | ❌ |
| Licencia | MIT | varía |
*Los envoltorios genéricos OpenAPI→MCP convierten cualquier especificación en herramientas MCP. Pueden alcanzar los mismos endpoints, pero tratan cada operación de manera idéntica — y contra la especificación de Wafeq específicamente heredan el problema de campos obligatorios de solo lectura descrito en MIGRATION.md. "➖" = varía según la herramienta / no garantizado.
Lo que puedes hacer
Una vez conectado, pregúntale a tu asistente cosas como:
- "¿Cuál fue nuestra pérdida y ganancia para la primera mitad de este año?"
- "Muéstrame todas las facturas impagas de más de 30 días, con el nombre del cliente."
- "Crea un borrador de factura para Acme Ltd por 3 días de consultoría a €800/día."
- "Descarga la factura INV-2026-014 como PDF."
- "¿En qué cuenta se registró la transferencia de €7,000 de enero?"
- "Adjunta este recibo al gasto EXP-118."
- "Concilia las líneas del extracto bancario de marzo contra el libro mayor."
- "Convierte la cotización QUO-31 en una factura y registra el pago."
Cómo funciona
Claude / Cursor / any MCP client ──MCP──► this server ──HTTPS──► Wafeq API (your organization)
Al inicio, el servidor analiza la especificación OpenAPI incluida en herramientas MCP — resolviendo
$refs, protegiéndose contra esquemas recursivos y eliminando campos asignados por el servidor
(readOnly) de los cuerpos de solicitud — etiqueta cada herramienta con su categoría de seguridad,
verifica a qué organización de Wafeq pertenecen las credenciales y luego inyecta tu
credencial en cada solicitud saliente. Tu clave permanece en el entorno del servidor; el
modelo nunca la ve ni la maneja.
Requisitos
- Una organización de Wafeq con acceso a API — ya sea una clave de API privada (Wafeq → Configuración → Desarrollador → Claves de API) o un token de acceso OAuth2. Consulta Obtén tus credenciales de API.
- Docker (Docker Desktop en macOS/Windows) para el inicio rápido a continuación — o Node.js ≥ 20 para ejecutar desde el código fuente.
Inicio rápido (Docker)
1. Agrega tus credenciales. Copia la configuración de ejemplo y complétala:
cp .env.example .env
Luego edita .env y establece WAFEQ_API_KEY. Si el servidor será accesible más allá de
localhost, establece también MCP_SHARED_TOKEN con una cadena aleatoria larga.
2. Inicia el servidor:
docker compose up -d --build
docker-compose.yml se vincula solo a 127.0.0.1:8765, por lo que el servidor es accesible desde tu
máquina pero no desde la red.
3. Confirma que está funcionando — y que apunta a los libros correctos:
curl -s http://localhost:8765/health
{
"status": "ok",
"server": "wafeq-mcp",
"version": "2.0.0",
"tools": 253,
"organization": {
"status": "ok",
"id": "org_...",
"name": "Your Company FZCO",
"base_currency": "EUR",
"country": "AE"
},
"auth_required": false
}
Revisa el campo name. Esa es la organización a la que tu clave escribe. Si no es la
empresa que esperabas, detente y corrige la clave antes de hacer cualquier otra cosa. /health
responde 503 y "status": "degraded" cuando las credenciales no se pueden verificar.
4. Apunta tu cliente MCP hacia él: http://localhost:8765/mcp (HTTP Streamable).
Los endpoints remotos se agregan a Claude como un conector personalizado (Configuración →
Conectores), o se puentean localmente con
mcp-remote. Para el puente, agrega esto
bajo mcpServers en la configuración de tu cliente y reinicia la aplicación por completo:
{
"mcpServers": {
"wafeq": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8765/mcp",
"--header", "Authorization: Bearer YOUR_MCP_SHARED_TOKEN"
]
}
}
}
(Elimina la línea --header si dejaste MCP_SHARED_TOKEN vacío.)
¿Prefieres una imagen lista?
Cada versión publica una imagen lista para ejecutar en el Registro de Contenedores de GitHub, por lo que puedes omitir la compilación local por completo:
docker run -d --name wafeq-mcp -p 127.0.0.1:8765:8765 --env-file .env \
ghcr.io/ohneben/wafeq-mcp:latest
Fija una versión (:2.0.0) en lugar de latest si quieres que las versiones sean algo
a lo que te adhieres deliberadamente.
Instalar desde el Registro MCP
El servidor está publicado en el Registro MCP
como io.github.ohneben/wafeq-mcp, por lo que los clientes que reconocen el registro pueden instalarlo por nombre.
La entrada del registro lanza la imagen sobre stdio — consulta
Ejecutar el contenedor sobre stdio para la configuración
escrita a mano equivalente.
curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/io.github.ohneben%2Fwafeq-mcp/versions/latest"
Obtén tus credenciales de API
Clave de API privada (la mayoría de las personas): en Wafeq, ve a Configuración → Desarrollador → Claves
de API y crea una clave. Está limitada a una organización. Ponla en .env como
WAFEQ_API_KEY; el servidor la envía como Authorization: Api-Key <key>.
Aplicación OAuth2: si tienes un token de acceso de una aplicación OAuth2 de Wafeq, ponlo en
.env como WAFEQ_ACCESS_TOKEN en su lugar. El servidor cambia a
Authorization: Bearer <token> automáticamente. Establece WAFEQ_AUTH_SCHEME solo si
necesitas forzar un esquema mientras ambas variables están presentes.
Configuración
Toda la configuración es mediante variables de entorno. Todo excepto la credencial tiene un valor predeterminado funcional.
| Variable | Default | What it does |
|---|---|---|
WAFEQ_API_KEY | — | Clave API privada de la organización. Se envía como Api-Key <key>. Se requiere una credencial. |
WAFEQ_ACCESS_TOKEN | — | Token de acceso OAuth2. Se envía como Bearer <token>. Tiene prioridad sobre WAFEQ_API_KEY. |
WAFEQ_AUTH_SCHEME | auto | Forzar api-key o bearer. Normalmente déjalo sin configurar. |
WAFEQ_API_BASE_URL | https://api.wafeq.com/v1 | URL base de la API de Wafeq. |
WAFEQ_OPENAPI_PATH | spec incluida | Usar un documento OpenAPI diferente (JSON o YAML). |
MCP_TRANSPORT | stdio | stdio o http. Docker establece http. |
PORT | 8765 | Puerto de escucha HTTP. |
HOST | 0.0.0.0 | Dirección de enlace HTTP. |
MCP_HTTP_PATH | /mcp | Ruta donde se sirve el endpoint de MCP. |
MCP_SHARED_TOKEN | — | Token Bearer requerido en /mcp. Vacío = sin autenticación. Configúralo si el puerto es accesible más allá de localhost. |
WAFEQ_TOOL_GROUPS | — | Grupos de recursos separados por comas para exponer, p. ej. invoices,bills,reports. Vacío = los 251. Ejecuta npm run list-tools para la lista. |
WAFEQ_MAX_REQUESTS | 20 | Límite de tasa del lado del cliente: solicitudes por ventana. 0 desactiva la limitación. |
WAFEQ_RATE_WINDOW_MS | 10000 | Ventana del límite de tasa en milisegundos. |
WAFEQ_MAX_RETRIES | 3 | Reintentos en 429 / 5xx / errores de red. |
WAFEQ_TIMEOUT_MS | 30000 | Tiempo de espera de solicitud por intento. |
WAFEQ_ALLOW_LOCAL_FILE_UPLOAD | false | Permitir que las herramientas de carga lean el sistema de archivos de esta máquina mediante file_path. Consulta Seguridad. |
WAFEQ_MAX_UPLOAD_BYTES | 26214400 | Tamaño máximo de carga decodificada (25 MiB). |
¿Demasiadas herramientas?
251 herramientas es mucho. El catálogo completo tiene aproximadamente 0.5 MB de JSON (~133k tokens) en
tools/list, y algunos hosts se vuelven más lentos o menos precisos con tantas. Dos cosas
ayudan.
Los esquemas ya están compactados. La especificación de Wafeq renderiza los valores de cada enum en
su descripción además de en enum — la lista de monedas sola tiene ~4 KB, insertada
en 203 lugares. El generador colapsa esos envoltorios de allOf de un solo miembro y elimina
las listas con viñetas duplicadas, lo que reduce ~29% la carga útil sin eliminar un
solo valor permitido.
Reduce el catálogo si aún lo quieres más pequeño — sin cambios de código:
WAFEQ_TOOL_GROUPS=invoices,bills,contacts,payments,reports,accounts,items,tax-rates
Las dos herramientas escritas a mano están siempre disponibles, así que nada queda inalcanzable —
cualquier cosa que filtres aún se puede llamar mediante wafeq_request.
Categorías de seguridad de herramientas
La descripción de cada herramienta comienza con un banner, y cada herramienta lleva las anotaciones MCP correspondientes. Los conteos son para la especificación incluida (251 generadas + 2 escritas a mano = 253).
| Banner | Herramientas | readOnlyHint | destructiveHint | Qué cubre |
|---|---|---|---|---|
🟢 READ-ONLY | 85 | ✅ | ❌ | Cada GET, más la herramienta de conveniencia del libro mayor de cuentas. |
🟢 READ-ONLY · returns a PDF | 9 | ✅ | ❌ | Las descargas PDF: factura, factura simplificada, nota de crédito, nota de débito, factura de compra, cotización, orden de compra, pago, recibo de nómina. Devueltas codificadas en base64. |
🟢 READ-ONLY · preview / simulation | 4 | ✅ | ❌ | Vistas previas de amortización y reconocimiento de ingresos. POST, pero documentadas como que no escriben nada. |
🟡 WRITE · creates data | 39 | ❌ | ❌ | Creaciones de colecciones, ambas cargas de archivos y las dos conversiones (cotización→factura, orden de compra→factura de compra). No idempotentes por naturaleza — de ahí la clave de idempotencia automática. |
🟡 WRITE · updates data | 70 | ❌ | ❌ | Cada PUT y PATCH. |
🟠 STATE CHANGE · moves a document in or out of the ledger | 2 | ❌ | ❌ | Marcar gasto como publicado / borrador. Reversible — cada uno deshace al otro. |
🔴 IRREVERSIBLE · files the document with an external tax authority | 3 | ❌ | ✅ | Reportar factura / nota de crédito / factura simplificada a la autoridad fiscal. Deja tu organización y no se puede recuperar. |
🔴 IRREVERSIBLE · posts the remaining balance to the ledger | 2 | ❌ | ✅ | Terminar amortización / reconocimiento de ingresos antes de tiempo. Sin deshacer por API — ejecuta la vista previa correspondiente primero. |
🔴 DESTRUCTIVE · deletes | 39 | ❌ | ✅ | Cada DELETE, más el paso directo de wafeq_request (su efecto no se puede conocer de antemano). |
| 253 | 98 | 44 |
Los tres grupos 🔴 todos establecen destructiveHint: true, así que un host que respeta las anotaciones
se detiene y pregunta antes de cualquiera de ellos — no solo antes de eliminaciones. Presentar una factura ante
una autoridad fiscal es al menos tan importante como eliminar una, y a diferencia de una eliminación,
alcanza fuera de tu organización.
Imprime el catálogo en vivo en cualquier momento, sin credenciales:
npm run list-tools
🟢 SOLO LECTURA (85)
| Herramienta | Endpoint |
|---|---|
wafeq_account_ledger | escrita a mano |
wafeq_accounts_list | GET /accounts/ |
wafeq_accounts_retrieve | GET /accounts/{id}/ |
wafeq_amortizations_list | GET /amortizations/ |
wafeq_amortizations_retrieve | GET /amortizations/{id}/ |
wafeq_bank_accounts_ledger_transactions_list | GET /bank-accounts/{bank_account_id}/ledger-transactions/ |
wafeq_bank_accounts_ledger_transactions_retrieve | GET /bank-accounts/{bank_account_id}/ledger-transactions/{id}/ |
wafeq_bank_accounts_list | GET /bank-accounts/ |
wafeq_bank_accounts_retrieve | GET /bank-accounts/{id}/ |
wafeq_bank_accounts_statement_transactions_list | GET /bank-accounts/{bank_account_id}/statement-transactions/ |
wafeq_bank_accounts_statement_transactions_retrieve | GET /bank-accounts/{bank_account_id}/statement-transactions/{id}/ |
wafeq_beneficiaries_list | GET /beneficiaries/ |
wafeq_beneficiaries_retrieve | GET /beneficiaries/{id}/ |
wafeq_bills_line_items_list | GET /bills/{bill_id}/line-items/ |
wafeq_bills_line_items_retrieve | GET /bills/{bill_id}/line-items/{id}/ |
wafeq_bills_list | GET /bills/ |
wafeq_bills_retrieve | GET /bills/{id}/ |
wafeq_branches_list | GET /branches/ |
wafeq_branches_retrieve | GET /branches/{id}/ |
wafeq_contacts_list | GET /contacts/ |
wafeq_contacts_retrieve | GET /contacts/{id}/ |
wafeq_cost_centers_list | GET /cost-centers/ |
wafeq_cost_centers_retrieve | GET /cost-centers/{id}/ |
wafeq_credit_notes_line_items_list | GET /credit-notes/{credit_note_id}/line-items/ |
wafeq_credit_notes_line_items_retrieve | GET /credit-notes/{credit_note_id}/line-items/{id}/ |
wafeq_credit_notes_list | GET /credit-notes/ |
wafeq_credit_notes_retrieve | GET /credit-notes/{id}/ |
wafeq_custom_fields_list | GET /custom-fields/ |
wafeq_custom_fields_retrieve | GET /custom-fields/{id}/ |
wafeq_debit_notes_line_items_list | GET /debit-notes/{debit_note_id}/line-items/ |
wafeq_debit_notes_line_items_retrieve | GET /debit-notes/{debit_note_id}/line-items/{id}/ |
wafeq_debit_notes_list | GET /debit-notes/ |
wafeq_debit_notes_retrieve | GET /debit-notes/{id}/ |
wafeq_employees_list | GET /employees/ |
wafeq_employees_retrieve | GET /employees/{id}/ |
wafeq_expenses_list | GET /expenses/ |
wafeq_expenses_retrieve | GET /expenses/{id}/ |
wafeq_files_list | GET /files/ |
wafeq_files_retrieve | GET /files/{id}/ |
wafeq_invoices_line_items_list | GET /invoices/{invoice_id}/line-items/ |
wafeq_invoices_line_items_retrieve | GET /invoices/{invoice_id}/line-items/{id}/ |
wafeq_invoices_list | GET /invoices/ |
wafeq_invoices_retrieve | GET /invoices/{id}/ |
wafeq_item_units_of_measure_list | GET /item-units-of-measure/ |
wafeq_item_units_of_measure_retrieve | GET /item-units-of-measure/{id}/ |
wafeq_items_list | GET /items/ |
wafeq_items_retrieve | GET /items/{id}/ |
wafeq_journal_line_items_list | GET /journal-line-items/ |
wafeq_journal_line_items_retrieve | GET /journal-line-items/{id}/ |
wafeq_manual_journals_list | GET /manual-journals/ |
wafeq_manual_journals_retrieve | GET /manual-journals/{id}/ |
wafeq_organization_retrieve | GET /organization/ |
wafeq_payment_requests_list | GET /payment_requests/ |
wafeq_payment_requests_retrieve | GET /payment_requests/{id}/ |
wafeq_payments_list | GET /payments/ |
wafeq_payments_retrieve | GET /payments/{id}/ |
wafeq_payslips_list | GET /payslips/ |
wafeq_payslips_pay_items_list | GET /payslips/{payslip_id}/pay-items/ |
wafeq_payslips_pay_items_retrieve | GET /payslips/{payslip_id}/pay-items/{id}/ |
wafeq_payslips_retrieve | GET /payslips/{id}/ |
wafeq_projects_list | GET /projects/ |
wafeq_projects_retrieve | GET /projects/{id}/ |
wafeq_purchase_orders_line_items_list | GET /purchase-orders/{purchase_order_id}/line-items/ |
wafeq_purchase_orders_line_items_retrieve | GET /purchase-orders/{purchase_order_id}/line-items/{id}/ |
wafeq_purchase_orders_list | GET /purchase-orders/ |
wafeq_purchase_orders_retrieve | GET /purchase-orders/{id}/ |
wafeq_quotes_line_items_list | GET /quotes/{quote_id}/line-items/ |
wafeq_quotes_line_items_retrieve | GET /quotes/{quote_id}/line-items/{id}/ |
wafeq_quotes_list | GET /quotes/ |
wafeq_quotes_retrieve | GET /quotes/{id}/ |
wafeq_reports_balance_sheet_list | GET /reports/balance-sheet/ |
wafeq_reports_cash_flow_list | GET /reports/cash-flow/ |
wafeq_reports_profit_and_loss_list | GET /reports/profit-and-loss/ |
wafeq_reports_trial_balance_list | GET /reports/trial-balance/ |
wafeq_revenue_recognitions_list | GET /revenue-recognitions/ |
wafeq_revenue_recognitions_retrieve | GET /revenue-recognitions/{id}/ |
wafeq_simplified_invoices_line_items_list | GET /simplified-invoices/{invoice_id}/line-items/ |
wafeq_simplified_invoices_line_items_retrieve | GET /simplified-invoices/{invoice_id}/line-items/{id}/ |
wafeq_simplified_invoices_list | GET /simplified-invoices/ |
wafeq_simplified_invoices_retrieve | GET /simplified-invoices/{id}/ |
wafeq_tax_rates_list | GET /tax-rates/ |
wafeq_units_of_measure_list | GET /units-of-measure/ |
wafeq_units_of_measure_retrieve | GET /units-of-measure/{id}/ |
wafeq_warehouses_list | GET /warehouses/ |
wafeq_warehouses_retrieve | GET /warehouses/{id}/ |
🟢 SOLO LECTURA (PDF) (9)
| Herramienta | Endpoint |
|---|---|
wafeq_bills_download_retrieve | GET /bills/{id}/download/ |
wafeq_credit_notes_download_retrieve | GET /credit-notes/{id}/download/ |
wafeq_debit_notes_download_retrieve | GET /debit-notes/{id}/download/ |
wafeq_invoices_download_retrieve | GET /invoices/{id}/download/ |
wafeq_payments_download_retrieve | GET /payments/{id}/download/ |
wafeq_payslips_download_retrieve | GET /payslips/{id}/download/ |
wafeq_purchase_orders_download_retrieve | GET /purchase-orders/{id}/download/ |
wafeq_quotes_download_retrieve | GET /quotes/{id}/download/ |
wafeq_simplified_invoices_download_retrieve | GET /simplified-invoices/{id}/download/ |
🟢 SOLO LECTURA (VISTA PREVIA) (4)
| Herramienta | Endpoint |
|---|---|
wafeq_amortizations_preview_create | POST /amortizations/preview/ |
wafeq_amortizations_preview_end_early_create | POST /amortizations/{id}/preview-end-early/ |
wafeq_revenue_recognitions_preview_create | POST /revenue-recognitions/preview/ |
wafeq_revenue_recognitions_preview_end_early_create | POST /revenue-recognitions/{id}/preview-end-early/ |
🟡 ESCRITURA · CREACIONES (39)
| Herramienta | Endpoint |
|---|---|
wafeq_accounts_create | POST /accounts/ |
wafeq_bank_accounts_create | POST /bank-accounts/ |
wafeq_bank_accounts_ledger_transactions_create | POST /bank-accounts/{bank_account_id}/ledger-transactions/ |
wafeq_bank_accounts_statement_transactions_create | POST /bank-accounts/{bank_account_id}/statement-transactions/ |
wafeq_beneficiaries_create | POST /beneficiaries/ |
wafeq_bills_create | POST /bills/ |
wafeq_bills_line_items_create | POST /bills/{bill_id}/line-items/ |
wafeq_branches_create | POST /branches/ |
wafeq_contacts_create | POST /contacts/ |
wafeq_cost_centers_create | POST /cost-centers/ |
wafeq_credit_notes_create | POST /credit-notes/ |
wafeq_credit_notes_line_items_create | POST /credit-notes/{credit_note_id}/line-items/ |
wafeq_custom_fields_create | POST /custom-fields/ |
wafeq_debit_notes_create | POST /debit-notes/ |
wafeq_debit_notes_line_items_create | POST /debit-notes/{debit_note_id}/line-items/ |
wafeq_employees_create | POST /employees/ |
wafeq_expenses_create | POST /expenses/ |
wafeq_invoices_create | POST /invoices/ |
wafeq_invoices_line_items_create | POST /invoices/{invoice_id}/line-items/ |
wafeq_item_units_of_measure_create | POST /item-units-of-measure/ |
wafeq_items_create | POST /items/ |
wafeq_manual_journals_create | POST /manual-journals/ |
wafeq_payment_requests_create | POST /payment_requests/ |
wafeq_payments_create | POST /payments/ |
wafeq_payslips_create | POST /payslips/ |
wafeq_payslips_pay_items_create | POST /payslips/{payslip_id}/pay-items/ |
wafeq_projects_create | POST /projects/ |
wafeq_purchase_orders_bill_create | POST /purchase-orders/{id}/bill/ |
wafeq_purchase_orders_create | POST /purchase-orders/ |
wafeq_purchase_orders_line_items_create | POST /purchase-orders/{purchase_order_id}/line-items/ |
wafeq_quotes_create | POST /quotes/ |
wafeq_quotes_invoice_create | POST /quotes/{id}/invoice/ |
wafeq_quotes_line_items_create | POST /quotes/{quote_id}/line-items/ |
wafeq_simplified_invoices_create | POST /simplified-invoices/ |
wafeq_simplified_invoices_line_items_create | POST /simplified-invoices/{invoice_id}/line-items/ |
wafeq_units_of_measure_create | POST /units-of-measure/ |
wafeq_upload_file | POST /files/ |
wafeq_upload_file_raw | POST /files/raw/ |
wafeq_warehouses_create | POST /warehouses/ |
🟡 ESCRITURA · ACTUALIZACIONES (70)
| Herramienta | Endpoint | |---|---| | `wafeq_accounts_partial_update` | `PATCH /accounts/{id}/` | | `wafeq_accounts_update` | `PUT /accounts/{id}/` | | `wafeq_bank_accounts_ledger_transactions_partial_update` | `PATCH /bank-accounts/{bank_account_id}/ledger-transactions/{id}/` | | `wafeq_bank_accounts_ledger_transactions_update` | `PUT /bank-accounts/{bank_account_id}/ledger-transactions/{id}/` | | `wafeq_bank_accounts_partial_update` | `PATCH /bank-accounts/{id}/` | | `wafeq_bank_accounts_statement_transactions_partial_update` | `PATCH /bank-accounts/{bank_account_id}/statement-transactions/{id}/` | | `wafeq_bank_accounts_statement_transactions_update` | `PUT /bank-accounts/{bank_account_id}/statement-transactions/{id}/` | | `wafeq_bank_accounts_update` | `PUT /bank-accounts/{id}/` | | `wafeq_beneficiaries_partial_update` | `PATCH /beneficiaries/{id}/` | | `wafeq_beneficiaries_update` | `PUT /beneficiaries/{id}/` | | `wafeq_bills_line_items_partial_update` | `PATCH /bills/{bill_id}/line-items/{id}/` | | `wafeq_bills_line_items_update` | `PUT /bills/{bill_id}/line-items/{id}/` | | `wafeq_bills_partial_update` | `PATCH /bills/{id}/` | | `wafeq_bills_update` | `PUT /bills/{id}/` | | `wafeq_branches_partial_update` | `PATCH /branches/{id}/` | | `wafeq_branches_update` | `PUT /branches/{id}/` | | `wafeq_contacts_partial_update` | `PATCH /contacts/{id}/` | | `wafeq_contacts_update` | `PUT /contacts/{id}/` | | `wafeq_cost_centers_partial_update` | `PATCH /cost-centers/{id}/` | | `wafeq_cost_centers_update` | `PUT /cost-centers/{id}/` | | `wafeq_credit_notes_line_items_partial_update` | `PATCH /credit-notes/{credit_note_id}/line-items/{id}/` | | `wafeq_credit_notes_line_items_update` | `PUT /credit-notes/{credit_note_id}/line-items/{id}/` | | `wafeq_credit_notes_partial_update` | `PATCH /credit-notes/{id}/` | | `wafeq_credit_notes_update` | `PUT /credit-notes/{id}/` | | `wafeq_custom_fields_partial_update` | `PATCH /custom-fields/{id}/` | | `wafeq_custom_fields_update` | `PUT /custom-fields/{id}/` | | `wafeq_debit_notes_line_items_partial_update` | `PATCH /debit-notes/{debit_note_id}/line-items/{id}/` | | `wafeq_debit_notes_line_items_update` | `PUT /debit-notes/{debit_note_id}/line-items/{id}/` | | `wafeq_debit_notes_partial_update` | `PATCH /debit-notes/{id}/` | | `wafeq_debit_notes_update` | `PUT /debit-notes/{id}/` | | `wafeq_employees_partial_update` | `PATCH /employees/{id}/` | | `wafeq_employees_update` | `PUT /employees/{id}/` | | `wafeq_expenses_partial_update` | `PATCH /expenses/{id}/` | | `wafeq_expenses_update` | `PUT /expenses/{id}/` | | `wafeq_invoices_line_items_partial_update` | `PATCH /invoices/{invoice_id}/line-items/{id}/` | | `wafeq_invoices_line_items_update` | `PUT /invoices/{invoice_id}/line-items/{id}/` | | `wafeq_invoices_partial_update` | `PATCH /invoices/{id}/` | | `wafeq_invoices_update` | `PUT /invoices/{id}/` | | `wafeq_item_units_of_measure_partial_update` | `PATCH /item-units-of-measure/{id}/` | | `wafeq_item_units_of_measure_update` | `PUT /item-units-of-measure/{id}/` | | `wafeq_items_partial_update` | `PATCH /items/{id}/` | | `wafeq_items_update` | `PUT /items/{id}/` | | `wafeq_manual_journals_partial_update` | `PATCH /manual-journals/{id}/` | | `wafeq_manual_journals_update` | `PUT /manual-journals/{id}/` | | `wafeq_payment_requests_partial_update` | `PATCH /payment_requests/{id}/` | | `wafeq_payment_requests_update` | `PUT /payment_requests/{id}/` | | `wafeq_payments_partial_update` | `PATCH /payments/{id}/` | | `wafeq_payments_update` | `PUT /payments/{id}/` | | `wafeq_payslips_partial_update` | `PATCH /payslips/{id}/` | | `wafeq_payslips_pay_items_partial_update` | `PATCH /payslips/{payslip_id}/pay-items/{id}/` | | `wafeq_payslips_pay_items_update` | `PUT /payslips/{payslip_id}/pay-items/{id}/` | | `wafeq_payslips_update` | `PUT /payslips/{id}/` | | `wafeq_projects_partial_update` | `PATCH /projects/{id}/` | | `wafeq_projects_update` | `PUT /projects/{id}/` | | `wafeq_purchase_orders_line_items_partial_update` | `PATCH /purchase-orders/{purchase_order_id}/line-items/{id}/` | | `wafeq_purchase_orders_line_items_update` | `PUT /purchase-orders/{purchase_order_id}/line-items/{id}/` | | `wafeq_purchase_orders_partial_update` | `PATCH /purchase-orders/{id}/` | | `wafeq_purchase_orders_update` | `PUT /purchase-orders/{id}/` | | `wafeq_quotes_line_items_partial_update` | `PATCH /quotes/{quote_id}/line-items/{id}/` | | `wafeq_quotes_line_items_update` | `PUT /quotes/{quote_id}/line-items/{id}/` | | `wafeq_quotes_partial_update` | `PATCH /quotes/{id}/` | | `wafeq_quotes_update` | `PUT /quotes/{id}/` | | `wafeq_simplified_invoices_line_items_partial_update` | `PATCH /simplified-invoices/{invoice_id}/line-items/{id}/` | | `wafeq_simplified_invoices_line_items_update` | `PUT /simplified-invoices/{invoice_id}/line-items/{id}/` | | `wafeq_simplified_invoices_partial_update` | `PATCH /simplified-invoices/{id}/` | | `wafeq_simplified_invoices_update` | `PUT /simplified-invoices/{id}/` | | `wafeq_units_of_measure_partial_update` | `PATCH /units-of-measure/{id}/` | | `wafeq_units_of_measure_update` | `PUT /units-of-measure/{id}/` | | `wafeq_warehouses_partial_update` | `PATCH /warehouses/{id}/` | | `wafeq_warehouses_update` | `PUT /warehouses/{id}/` |🟠 CAMBIO DE ESTADO (2)
| Herramienta | Endpoint |
|---|---|
wafeq_expenses_mark_as_draft_create | POST /expenses/{id}/mark-as-draft/ |
wafeq_expenses_mark_as_posted_create | POST /expenses/{id}/mark-as-posted/ |
🔴 IRREVERSIBLE · PRESENTACIÓN EXTERNA (3)
| Herramienta | Endpoint |
|---|---|
wafeq_credit_notes_tax_authority_report_create | POST /credit-notes/{id}/tax-authority/report/ |
wafeq_invoices_tax_authority_report_create | POST /invoices/{id}/tax-authority/report/ |
wafeq_simplified_invoices_tax_authority_report_create | POST /simplified-invoices/{id}/tax-authority/report/ |
🔴 IRREVERSIBLE · LIBRO MAYOR (2)
| Herramienta | Endpoint |
|---|---|
wafeq_amortizations_end_early_create | POST /amortizations/{id}/end-early/ |
wafeq_revenue_recognitions_end_early_create | POST /revenue-recognitions/{id}/end-early/ |
🔴 DESTRUCTIVO · ELIMINA (39)
| Herramienta | Endpoint |
|---|---|
wafeq_accounts_destroy | DELETE /accounts/{id}/ |
wafeq_amortizations_destroy | DELETE /amortizations/{id}/ |
wafeq_bank_accounts_destroy | DELETE /bank-accounts/{id}/ |
wafeq_bank_accounts_ledger_transactions_destroy | DELETE /bank-accounts/{bank_account_id}/ledger-transactions/{id}/ |
wafeq_bank_accounts_statement_transactions_destroy | DELETE /bank-accounts/{bank_account_id}/statement-transactions/{id}/ |
wafeq_beneficiaries_destroy | DELETE /beneficiaries/{id}/ |
wafeq_bills_destroy | DELETE /bills/{id}/ |
wafeq_bills_line_items_destroy | DELETE /bills/{bill_id}/line-items/{id}/ |
wafeq_branches_destroy | DELETE /branches/{id}/ |
wafeq_contacts_destroy | DELETE /contacts/{id}/ |
wafeq_cost_centers_destroy | DELETE /cost-centers/{id}/ |
wafeq_credit_notes_destroy | DELETE /credit-notes/{id}/ |
wafeq_credit_notes_line_items_destroy | DELETE /credit-notes/{credit_note_id}/line-items/{id}/ |
wafeq_custom_fields_destroy | DELETE /custom-fields/{id}/ |
wafeq_debit_notes_destroy | DELETE /debit-notes/{id}/ |
wafeq_debit_notes_line_items_destroy | DELETE /debit-notes/{debit_note_id}/line-items/{id}/ |
wafeq_employees_destroy | DELETE /employees/{id}/ |
wafeq_expenses_destroy | DELETE /expenses/{id}/ |
wafeq_files_destroy | DELETE /files/{id}/ |
wafeq_invoices_destroy | DELETE /invoices/{id}/ |
wafeq_invoices_line_items_destroy | DELETE /invoices/{invoice_id}/line-items/{id}/ |
wafeq_item_units_of_measure_destroy | DELETE /item-units-of-measure/{id}/ |
wafeq_items_destroy | DELETE /items/{id}/ |
wafeq_manual_journals_destroy | DELETE /manual-journals/{id}/ |
wafeq_payment_requests_destroy | DELETE /payment_requests/{id}/ |
wafeq_payments_destroy | DELETE /payments/{id}/ |
wafeq_payslips_destroy | DELETE /payslips/{id}/ |
wafeq_payslips_pay_items_destroy | DELETE /payslips/{payslip_id}/pay-items/{id}/ |
wafeq_projects_destroy | DELETE /projects/{id}/ |
wafeq_purchase_orders_destroy | DELETE /purchase-orders/{id}/ |
wafeq_purchase_orders_line_items_destroy | DELETE /purchase-orders/{purchase_order_id}/line-items/{id}/ |
wafeq_quotes_destroy | DELETE /quotes/{id}/ |
wafeq_quotes_line_items_destroy | DELETE /quotes/{quote_id}/line-items/{id}/ |
wafeq_request | escrito a mano |
wafeq_revenue_recognitions_destroy | DELETE /revenue-recognitions/{id}/ |
wafeq_simplified_invoices_destroy | DELETE /simplified-invoices/{id}/ |
wafeq_simplified_invoices_line_items_destroy | DELETE /simplified-invoices/{invoice_id}/line-items/{id}/ |
wafeq_units_of_measure_destroy | DELETE /units-of-measure/{id}/ |
wafeq_warehouses_destroy | DELETE /warehouses/{id}/ |
Cobertura
| Área | Herramientas | 🟢 Lectura | 🟡 Escritura | 🔴 Irreversible | 🔴 Eliminación |
|---|---|---|---|---|---|
| Ventas y cuentas por cobrar | 69 | 25 | 31 | 3 | 10 |
| Compras y cuentas por pagar | 54 | 19 | 27 | 0 | 8 |
| Banca | 18 | 6 | 9 | 0 | 3 |
| Libro mayor e informes | 31 | 19 | 6 | 2 | 4 |
| Nómina | 19 | 7 | 9 | 0 | 3 |
| Datos maestros y dimensiones | 54 | 18 | 27 | 0 | 9 |
| Archivos y organización | 6 | 3 | 2 | 0 | 1 |
| Vía de escape y conveniencia | 2 | 1 | 0 | 0 | 1 |
| Total | 253 | 98 | 111 | 5 | 39 |
"Escritura" incluye las dos herramientas de 🟠 cambio de estado. Las áreas se asignan a los recursos de Wafeq de la siguiente manera — Ventas: facturas, facturas simplificadas, cotizaciones, notas de crédito, pagos, solicitudes de pago · Compras: facturas de compra, órdenes de compra, notas de débito, gastos, beneficiarios · Banca: cuentas bancarias con su libro mayor y transacciones de estado de cuenta · Libro mayor e informes: cuentas, asientos manuales, partidas de asiento, los cuatro informes, tasas impositivas, amortizaciones, reconocimientos de ingresos · Nómina: recibos de pago, empleados · Datos maestros: contactos, artículos, unidades de medida, almacenes, proyectos, centros de costo, sucursales, campos personalizados.
Dos herramientas escritas a mano
Todo lo anterior es generado. Dos herramientas están escritas a mano:
wafeq_account_ledger(🟢) — partidas de asiento con su fecha de transacción real. Las filas de/journal-line-items/de Wafeq llevancreated_ts(cuando la fila llegó a Wafeq), que suele ser un mes diferente al de la transacción, y no tienen ningún campo de fecha. Esta herramienta recupera la fecha usando los filtros dedate_after/date_beforedel propio endpoint, que sí operan sobre la fecha de transacción. Sondea un mes a la vez y solo divide en consultas por día donde existen filas, por lo que los períodos tranquilos cuestan una solicitud cada uno; el resultado informarequests_made.wafeq_request(🔴) — la vía de escape: cualquier método, cualquier ruta, más query, body y headers. Es el respaldo para cualquier cosa que el spec incluido no cubra, no la interfaz principal. Categorizado como destructivo porque su efecto no se puede conocer de antemano.
Ejecutar desde el código fuente (stdio, sin Docker)
npm ci
npm run build
Luego regístralo con tu cliente MCP. Para Claude Desktop, agrega a claude_desktop_config.json:
{
"mcpServers": {
"wafeq": {
"command": "node",
"args": ["/absolute/path/to/Wafeq MCP/dist/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"WAFEQ_API_KEY": "your-key-here"
}
}
}
}
Para Claude Code:
claude mcp add wafeq --env WAFEQ_API_KEY=your-key-here -- node /absolute/path/to/dist/index.js
Ejecutar el contenedor sobre stdio
También puedes dejar que tu cliente inicie la imagen publicada directamente, sin servidor HTTP y sin compilación local:
{
"mcpServers": {
"wafeq": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT=stdio",
"-e", "WAFEQ_API_KEY",
"ghcr.io/ohneben/wafeq-mcp:latest"
],
"env": {
"WAFEQ_API_KEY": "your-key-here"
}
}
}
}
MCP_TRANSPORT=stdio es requerido aquí: la imagen usa por defecto el transporte HTTP.
Scripts útiles:
| Comando | Qué hace |
|---|---|
npm run build | Compila TypeScript a dist/. |
npm test | Ejecuta la suite de Vitest. |
npm run list-tools | Imprime el catálogo categorizado. No necesita credenciales. |
npm run start:stdio | Ejecuta sobre stdio. |
npm run start:http | Ejecuta el servidor HTTP Streamable. |
Mantener el spec actualizado
Las herramientas se generan desde spec/wafeq-public-api.json al inicio — no hay paso de generación de código ni lista de herramientas escrita a mano. Coloca un documento OpenAPI más nuevo (JSON o YAML), recompila, y los nuevos endpoints se convierten en nuevas herramientas. Consulta spec/README.md para ver de dónde proviene la copia incluida y qué revisar después de una actualización.
Las correcciones de comportamiento observado viven en src/overrides.ts, con clave por operationId y fechadas, de modo que una entrada cuya operación desaparezca simplemente deja de aplicarse.
Notas y convenciones
- Fechas son
YYYY-MM-DD. Montos usan un punto como separador decimal. - Paginación: las herramientas de listado toman
limityoffset, e informan el recuento total. - Informes toman parámetros de fecha específicos del informe — balance general
date+period_count; pérdidas y ganancias y flujo de cajadate_after+date_before; balance de comprobaciónfrom_date+to_date. Wafeq ignora silenciosamente un parámetro de query mal escrito, por lo que un nombre incorrecto parece una llamada exitosa; los esquemas por informe existen para hacer eso imposible. - Períodos completos: los rangos de pérdidas y ganancias y flujo de caja deben cubrir meses o años completos. El servidor verifica localmente y responde con el rango válido más cercano en lugar de gastar un viaje de ida y vuelta en un HTTP 400.
- Subidas de archivos (
wafeq_files_*): pasa contenido base64 más un nombre de archivo.POST /files/es solo multipart yPOST /files/raw/necesita un headerContent-Disposition— ambos se manejan por ti. - Descargas de PDF regresan codificadas en base64 en un pequeño sobre que lleva el tamaño y el tipo de contenido, no como texto distorsionado.
- Idempotencia: cada endpoint de escritura que soporta
X-Wafeq-Idempotency-Keyrecibe un UUID v4 automáticamente, reutilizado entre reintentos. Pasa el tuyo propio para hacer una re-ejecución deliberada segura. - Reintentos: las respuestas transitorias de
429/5xxse reintentan con retroceso exponencial con jitter, respetandoRetry-After, bajo la misma clave de idempotencia. - Límite de tasa: Wafeq no publica un límite numérico, por lo que el valor predeterminado del lado del cliente (
WAFEQ_MAX_REQUESTS=20porWAFEQ_RATE_WINDOW_MS=10000) es deliberadamente conservador. Auméntalo si conoces tu asignación. - Una organización por credencial. Una clave de API de Wafeq está limitada a la organización; cada llamada de herramienta actúa sobre esa organización, y
/healthla nombra.
CI y lanzamientos
Cada push y pull request se compila y prueba en Node 20 y 22, y el catálogo de herramientas se genera sin credenciales presentes — que es lo que detecta un nombre de herramienta duplicado o ilegal según el esquema antes de que se publique. CI también falla si .env alguna vez se vuelve rastreado.
Un lanzamiento es una etiqueta vX.Y.Z y nada más. No se mantiene ningún número de versión a mano. Empujar la etiqueta ejecuta toda la cadena:
- La versión se deriva una sola vez, a partir de la etiqueta.
- La imagen se compila y se publica en
ghcr.io/ohneben/wafeq-mcp— etiquetada con la versión,MAJOR.MINOR, el SHA corto ylatestenmain. - La entrada se publica en el Registro MCP
con
server.jsonfijado a esa etiqueta de imagen exacta. La propiedad se demuestra mediante la etiquetaio.modelcontextprotocol.server.nameen la imagen, que debe coincidir con elnamedeserver.json— una prueba garantiza que así sea. - El número publicado se escribe de vuelta en
package.jsonyserver.jsonenmain, y la etiqueta se mueve a ese commit. Así, el repositorio siempre indica la última versión publicada, y el servidor la reporta a través de MCP y en/healthsin necesidad de editar código.
npm version 2.0.1 --no-git-tag-version # optional; CI stamps it either way
git tag v2.0.1 && git push origin v2.0.1
workflow_dispatch vuelve a publicar una versión dada sin crear una nueva etiqueta. Los envíos a
main compilan una imagen -dev.g<sha> y se detienen ahí — nunca tocan el registro.
Seguridad
- Las credenciales permanecen en el servidor. Se leen del entorno y se inyectan
por solicitud. El modelo ve las entradas de las herramientas y las respuestas de la API, nunca la clave. La
herramienta de paso directo no puede sobrescribir el encabezado
Authorization, y se niega a enviar la credencial a cualquier host que no sea la base de API configurada. - Nunca confirmes
.env. Está ignorado por git, y la CI falla si alguna vez se rastrea..env.examplesolo contiene marcadores de posición. - Vincula a localhost, o establece un token.
docker-compose.ymlpublica en127.0.0.1únicamente. Si expones el puerto más allá, estableceMCP_SHARED_TOKENprimero; se compara en tiempo constante. - Las cargas de archivos locales están desactivadas por defecto.
WAFEQ_ALLOW_LOCAL_FILE_UPLOAD=falsesignifica que el servidor no leerá archivos de su propio sistema de archivos. Activarlo permite que cualquier cosa que pueda llamar al servidor le pida leer una ruta local — déjalo desactivado a menos que lo necesites y confíes en cada cliente. Las cargas en Base64 funcionan de cualquier manera. - Verifica la organización en
/healthantes de la primera escritura. Una clave de API está limitada a una organización, y una clave incorrecta falla escribiendo en la empresa equivocada en lugar de generar un error. - Las herramientas 🔴 significan lo que dicen. Las eliminaciones son permanentes, terminar un horario
antes de tiempo no tiene deshacer en la API, y una declaración ante la autoridad fiscal no se puede
recuperar. Mantén las confirmaciones del host activadas para cualquier cosa que lleve
destructiveHint.
Consulta SECURITY.md para reportar una vulnerabilidad.
Créditos y licencia
MIT — consulta LICENSE.md. Construido sobre el SDK de TypeScript del Protocolo de Contexto de Modelo, siguiendo la misma arquitectura que ohneben's LearnWorlds MCP. No está afiliado ni respaldado por Wafeq.