@timbrix/mcp
MCP (Model Context Protocol) server for Timbrix — lets AI agents (Claude, Cursor, ChatGPT, etc.) stamp, cancel, and query CFDI 4.0 invoices directly, through the same REST API @timbrix/sdk uses.
v1 tools
timbrix_crear_cfdi_ingreso | Stamp a CFDI 4.0 Ingreso invoice |
timbrix_cancelar_cfdi | Cancel a stamped CFDI by UUID and motivo |
timbrix_consultar_saldo | Get CFDI usage/quota for the current billing month |
timbrix_listar_cfdi | List invoices with page/type/status filters |
timbrix_crear_emisor (registering a new RFC issuer + CSD) is not available in v1 — organization creation and CSD upload require an authenticated owner session today, not an API key. See the Timbrix dashboard or @timbrix/cli to onboard a new organization.
Installation (Claude Desktop)
Add to your claude_desktop_config.json:
{
"mcpServers": {
"timbrix": {
"command": "npx",
"args": ["@timbrix/mcp"],
"env": {
"TIMBRIX_API_KEY": "tk_live_..."
}
}
}
}
Environment variables
TIMBRIX_API_KEY | yes | API key created in the Timbrix dashboard, scoped to one organization |
TIMBRIX_API_URL | no | Overrides the API base URL (default https://api.timbrix.mx) |
MCP_TRANSPORT | no | stdio (default, for local agents) or http (for hosted use) |
PORT | no | HTTP transport port when MCP_TRANSPORT=http (default 8787) |
MCP_HTTP_HOST | no | HTTP transport bind address (default 127.0.0.1, loopback only) — see below |
Running the HTTP transport
MCP_TRANSPORT=http PORT=8787 TIMBRIX_API_KEY=tk_live_... npx @timbrix/mcp
Endpoints:
POST /mcp | Streamable HTTP — initialize, then every subsequent JSON-RPC request |
GET /mcp | SSE stream for server-to-client messages on an established session |
DELETE /mcp | Explicitly terminate a session |
GET /health | Health check ({ "status": "ok" }) |
Sessions
The endpoint is stateful, as the MCP spec requires. A client's first
POST /mcp carries an initialize request and no session header; the server
creates one MCP server instance for it and returns an Mcp-Session-Id. Every
later request (starting with notifications/initialized) must send that header
back and is routed to the same instance — an unknown or missing session ID is
rejected rather than silently given a fresh, uninitialized server.
A session lives until one of:
- the client sends
DELETE /mcp with its Mcp-Session-Id, or
- it goes 30 minutes without a request, at which point the idle sweep evicts
it (clients that crash, close, or lose the network never send
DELETE, so
without this they would leak).
After eviction, requests on that session ID get 404 Session not found; a client
recovers by re-running initialize.
Security: bind address and authentication
This transport implements no authentication of its own. Every session calls
the Timbrix API with the single TIMBRIX_API_KEY the process was started with,
so anyone who can reach the port can stamp and cancel real CFDIs against your
RFC, at your cost.
Because of that:
- The server binds to
127.0.0.1 by default — reachable only from the same
machine. Host-header (DNS-rebinding) validation is applied on this default, so
a malicious web page cannot point a hostname it controls at your loopback
server and drive it through the victim's browser.
- Set
MCP_HTTP_HOST (e.g. MCP_HTTP_HOST=0.0.0.0) to expose it further. This
is an explicit opt-in for real hosted deployments and requires you to put
your own authenticating front door in front of it — a reverse proxy, API
gateway, or private network — because this package will not do it for you. On
a non-loopback bind the built-in Host-header allowlist is skipped (your proxy's
hostname is not knowable here) and the server prints a warning on startup.
For local, single-user agents, prefer the default stdio transport — it needs
no port at all.
Development
pnpm --filter @timbrix/mcp dev
pnpm --filter @timbrix/mcp test
pnpm --filter @timbrix/mcp build