Documentación
Servidor MCP
Bloques incluye un servidor MCP (Model Context Protocol): el estándar abierto con el que asistentes y agentes IA — Claude, Claude Code, y cualquier cliente MCP — usan herramientas externas. Conectándolo, tu agente puede emitir boletas y facturas, consultar documentos, gestionar el catálogo y revisar tu consumo, conversando: "emite una boleta de S/ 118 por consultoría a CLIENTES VARIOS".
Endpoint y protocolo
| Propiedad | Valor |
|---|---|
| URL | POST https://<tu-host>/api/mcp |
| Transporte | Streamable HTTP, stateless: cada POST es una petición JSON-RPC independiente; no hay sesiones ni SSE (GET responde 405). |
| Versiones de protocolo | 2025-06-18, 2025-03-26, 2024-11-05. |
| Autenticación | Cabecera Authorization: Bearer sk_live_… — los mismos tokens con scopes de la API REST (Configuración → API). Sin token válido no se revela nada del servidor (401). |
| Capacidades | Solo tools (sin resources ni prompts en v1). |
Cómo conectarlo
Claude Code
claude mcp add --transport http bloques https://<tu-host>/api/mcp \
--header "Authorization: Bearer sk_live_..."Listo: en la siguiente sesión verás las herramientas bloques disponibles. Verifica con claude mcp list.
claude.ai (conector personalizado)
En claude.ai ve a Settings → Connectors → Add custom connector y registra la URL https://<tu-host>/api/mcp. Como el servidor se autentica con cabecera Bearer (no OAuth), necesitas un plan/cliente que permita configurar cabeceras personalizadas para conectores; si tu cliente no lo permite, usa Claude Code o la API REST.
Otros clientes MCP (config JSON genérica)
{
"mcpServers": {
"bloques": {
"type": "http",
"url": "https://<tu-host>/api/mcp",
"headers": {
"Authorization": "Bearer sk_live_..."
}
}
}
}Cualquier cliente que soporte transporte http (Streamable HTTP) con cabeceras personalizadas funciona.
Herramientas
Cada token solo ve las herramientas que sus scopes permiten — un token de solo lectura ni siquiera sabe que create_document existe — y, cuando la herramienta pertenece a un módulo (como create_expense, del módulo Finanzas), solo si tu empresa tiene ese módulo activo. La lista que ve tu agente es, por eso, la intersección de las dos cosas.
create_documentdocuments:writeaccepted/rejected). factura exige cliente con RUC; boleta es para consumidores (DNI, u omite el cliente para CLIENTES VARIOS). Los precios son finales con IGV incluido. Consume el límite mensual del plan. Es una emisión fiscal real: el agente debe confirmar con el usuario antes de llamarla.| Argumento | Requerido | Descripción |
|---|---|---|
type | Sí | "factura" o "boleta". |
series | No | Serie como F001/B001 (por defecto la activa). |
issue_date | No | YYYY-MM-DD, por defecto hoy (Lima). Máx. 7 días atrás. |
currency | No | PEN (por defecto) o USD. |
customer | Factura: sí | Objeto con id (cliente existente) o doc_type("6" RUC, "1" DNI, "4" CE, "7" pasaporte, "0" ninguno), doc_number, name, email, address. |
items | Sí | 1–100 ítems: product_id o code (catálogo), o description + unit_price (línea libre); más quantity, unit_code, affectation (10/20/30). |
payment | No | { "type": "contado" | "credito", "installments": [{ "amount", "due_date" }] } — las cuotas deben sumar el total. |
notes | No | Texto libre impreso en el PDF. |
send_email | No | Enviar PDF + XML al cliente (por defecto, configuración de la empresa). |
idempotency_key | Recomendado | Clave de reintento seguro: repetirla devuelve el documento original en vez de emitir dos veces. |
get_documentdocuments:readF001-42.| Argumento | Requerido | Descripción |
|---|---|---|
id_or_number | Sí | UUID del documento o número completo (serie-correlativo). |
list_documentsdocuments:read| Argumento | Requerido | Descripción |
|---|---|---|
from | No | Fecha de emisión mínima (YYYY-MM-DD). |
to | No | Fecha de emisión máxima (YYYY-MM-DD). |
type | No | factura | boleta. |
status | No | accepted | rejected | error | processing. |
q | No | Búsqueda por número, nombre o documento del cliente. |
page | No | Por defecto 1. |
per_page | No | Por defecto 25, máx. 100. |
get_document_filesdocuments:readAuthorization: Bearer usada para MCP.| Argumento | Requerido | Descripción |
|---|---|---|
id | Sí | UUID del documento. |
list_productsproducts:read| Argumento | Requerido | Descripción |
|---|---|---|
q | No | Búsqueda por nombre o código. |
page | No | Por defecto 1 (100 por página). |
create_productproducts:writeunit_price es el precio FINAL (IGV incluido cuando la afectación es 10 gravado).| Argumento | Requerido | Descripción |
|---|---|---|
code | Sí | Código único por empresa. |
name | Sí | Nombre del producto. |
description | No | Descripción opcional. |
unit_code | No | Por defecto NIU. |
unit_price | Sí | Precio final, mayor a 0. |
currency | No | PEN (por defecto) | USD. |
affectation | No | "10" (por defecto) | "20" | "30". |
search_customerscustomers:read| Argumento | Requerido | Descripción |
|---|---|---|
q | No | Texto de búsqueda; sin él lista los primeros clientes. |
create_expenseexpenses:write · módulo Finanzastotal es lo que dice el papel y es el único monto obligatorio: Bloques sugiere el desglose con la tasa de IGV efectiva de tu empresa, salvo que envíes amounts — y entonces los seis componentes deben sumar el total exacto.| Argumento | Requerido | Descripción |
|---|---|---|
issue_date | Sí | YYYY-MM-DD, la fecha del comprobante del proveedor. |
total | Sí | Total del documento, IGV incluido. Acepta string ("118.00", exacto) o número. |
doc_type | No | 01 factura (por defecto) · 02 recibo por honorarios · 03 boleta · 04 liquidación de compra · 07/08 nota de crédito/débito recibida · 10 arrendamiento · 12 ticket · 13 banco/seguro · 14 servicios públicos · 00 sin comprobante. Fija el valor por defecto de credito_fiscal. |
supplier_id / supplier | No | El UUID de un proveedor del directorio, o uno tipeado (doc_type, doc_number, name). Sin ninguno: PROVEEDOR VARIOS. |
description | No | Nombre corto del gasto — en qué se gastó, en pocas palabras («Compra de gaseosas para la tienda»). Máx. 200 caracteres. Se muestra en la lista de gastos y entra a la búsqueda. Es distinto de notes, la nota interna larga, y no tiene ningún efecto fiscal. |
series / number | No | Serie y correlativo tal como vienen impresos (texto libre). |
currency / exchange_rate | No | PEN (por defecto) o USD; en USD el tipo de cambio es obligatorio. |
amounts | No | Desglose copiado del documento: base_gravada, igv, base_exonerada, base_inafecta, isc, otros_tributos. Debe sumar el total. |
detraction | No | { code, rate, amount, constancy, date } — la tasa es fracción (0.12 = 12 %) y se guarda tal como se envía (es un snapshot de la constancia). |
category_id / branch_id / cash_register_id | No | UUIDs de la categoría, la sucursal y la caja a las que se imputa. |
due_date / payment_terms | No | Vencimiento y contado | credito (cuentas por pagar). |
items | No | Líneas opcionales que reparten el total (por categoría o producto), no la fuente de los impuestos: si las envías, deben sumar el total. |
deductible / is_fixed_asset / igv_destination / credito_fiscal / notes | No | Marcas contables del gasto. |
get_usagesin scope (cualquier token)Sin argumentos.
Modelo de seguridad
- Scopes por token filtran las herramientas visibles.
tools/listsolo devuelve lo que el token puede ejecutar; la superficie no autorizada permanece oculta (no solo bloqueada). - Los módulos filtran igual que los scopes. Una herramienta de un módulo que tu empresa no tiene activo no se lista, y llamarla igual falla — el servidor lo vuelve a verificar al ejecutar.
- Gastos y dinero: escritura sin lectura.
create_expenseregistra, pero ninguna herramienta lee gastos, saldos ni movimientos de dinero. Es deliberado: un agente puede anotar lo que se gastó sin poder consultar cuánta plata tienes ni en qué se va. Esa información se ve únicamente iniciando sesión en la app. - Aislamiento por empresa. Cada token pertenece a exactamente una empresa; toda herramienta opera únicamente sobre los datos de esa empresa. No existe forma de cruzar tenants.
- Auditoría de cada llamada. Toda ejecución de herramienta queda registrada en la bitácora de eventos de la empresa (
mcp.tool_call), con el token como actor. Las emisiones registran además qué token las originó. - Sin estado, sin divulgación anónima. El servidor no responde nada (ni siquiera su nombre) sin un Bearer válido, y no mantiene sesiones que secuestrar.
Recomendación: un token por agente, con scopes mínimos
Crea un token dedicado para cada agente y dale solo lo que necesita. Un agente de análisis o reportes: documents:read (+ products:read) — jamás podrá emitir. Un agente de caja: documents:write + documents:read. Evita * salvo para pruebas tuyas. Si un agente se comporta mal, revoca su token en Configuración → API y solo ese agente pierde acceso.
¿Vas a programar la integración tú mismo (o tu agente)? Sigue con la guía para agentes IA o apunta directamente a /llms-full.txt.