Skip to main content
Glama

@timbrix/mcp

npm version License: MIT

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.

Full guide: see docs.timbrix.mx/ai-agents for setup, the complete tool reference, LangChain (TS/Python) examples, error handling, and authentication best practices for agents.

This is the official public repository for @timbrix/mcp — open issues and PRs here.

Listed in the Official MCP Registry as mx.timbrix/mcp.

v1 tools

Tool

Description

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.

Related MCP server: brazil-invoice-mcp

Installation

No install step is required to try it — npx @timbrix/mcp always runs the latest published version. To install it globally instead:

npm install -g @timbrix/mcp
TIMBRIX_API_KEY=sk_... timbrix-mcp

Claude Desktop (local, npx)

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "timbrix": {
      "command": "npx",
      "args": ["@timbrix/mcp"],
      "env": {
        "TIMBRIX_API_KEY": "sk_..."
      }
    }
  }
}

Claude Desktop (hosted, no install)

Point at https://mcp.timbrix.mx/mcp instead — same config file, no local process:

{
  "mcpServers": {
    "timbrix": {
      "url": "https://mcp.timbrix.mx/mcp",
      "headers": {
        "Authorization": "Bearer sk_..."
      }
    }
  }
}

Any MCP client that supports a url + custom headers remote server config (Cursor included) works the same way.

Environment variables

Variable

Required

Description

TIMBRIX_API_KEY

only for stdio (default)

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

MCP_ALLOWED_HOSTS

only when MCP_HTTP_HOST is non-loopback

Comma-separated hostnames this server is publicly reachable as (Host-header allowlist)

Running the HTTP transport

MCP_TRANSPORT=http PORT=8787 npx @timbrix/mcp

Endpoints:

Endpoint

Purpose

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, Host validation, and authentication

In http mode, each session authenticates independently via the Authorization: Bearer <api-key> or X-API-Key header sent with the client's initialize request — there is no single, process-wide API key. The key is never validated by this package itself; it's forwarded to the Timbrix API on every call, exactly as stdio mode already does, so the Timbrix API's own key validation is the source of truth. An initialize request with neither header is rejected with 401 before any session is created.

  • 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 also requires MCP_ALLOWED_HOSTS, since Host-header validation still applies on a non-loopback bind (the server refuses to start without it, rather than skipping validation altogether).

  • New-session creation is rate-limited per IP (30/minute by default) to protect the process from unbounded session creation; requests on an already-established session are never affected by this limit.

  • GET /health is exempt from Host validation, so infrastructure health probes (which send their own Host header, e.g. Railway's healthcheck.railway.app) don't need to be added to MCP_ALLOWED_HOSTS.

  • Once a session is established, its Mcp-Session-Id header alone authorizes further requests on it — the API key isn't re-checked per request — so treat a session ID as sensitive as the credential that created it for the rest of that session's life.

For local, single-user agents, stdio (the default) still needs no port at all and is the simplest option.

Development

pnpm install
pnpm dev   # watch build
pnpm test  # vitest
pnpm build # tsup

License

MIT © Timbrix — see LICENSE.

Available Tools

4 tools
timbrix_cancelar_cfdiCancelar CFDIA
DestructiveIdempotent

Solicita la cancelación de un CFDI ya timbrado ante el SAT. Si el receptor debe aprobar la cancelación, el resultado queda en estatus 'pendiente'.

ParametersJSON Schema
NameRequiredDescriptionDefault
uuidYesUUID fiscal (folio fiscal) del CFDI a cancelar
motivoYes01 = con relación (requiere folioSustitucion), 02 = sin relación, 03 = no se llevó a cabo la operación, 04 = operación nominativa de factura global
folioSustitucionNoUUID del CFDI que sustituye a este; requerido cuando motivo=01

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=true, so the safety profile is clear. The description adds valuable behavioral context: the cancellation is a request ('Solicita'), the result may be 'pendiente' if receiver approval is needed, and it operates on an already-timbrado CFDI. This goes beyond the annotations by explaining the asynchronous/pending nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the core action and includes the most important behavioral nuance (pending status). No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a cancellation tool with full schema coverage and annotations covering safety, the description is nearly complete. It explains the pending status and the SAT context. It could mention that motivo=01 requires folioSustitucion, but the schema already covers that. No output schema exists, so return values are not specified, but the description's mention of 'pendiente' status partially compensates.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters. The description adds no additional parameter-level meaning beyond what the schema provides. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Solicita la cancelación de un CFDI ya timbrado ante el SAT') and the specific resource (CFDI). It also distinguishes itself from siblings by focusing on cancellation, while siblings handle creation, listing, and balance queries. The verb 'cancelar' is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: when a CFDI is already stamped and needs cancellation. It also mentions the pending status when receiver approval is required, which is a key usage context. However, it doesn't explicitly state when NOT to use it or name alternatives (e.g., use timbrix_listar_cfdi to find the UUID first).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

timbrix_consultar_saldoConsultar saldo de CFDIA
Read-onlyIdempotent

Devuelve cuántos CFDI ha timbrado la organización configurada en el mes calendario actual (hora Ciudad de México) contra el límite incluido en su plan, y cuándo se reinicia el periodo. Importante: cfdiIncluded y cfdiRemaining son null cuando el plan es enterprise (timbrado ilimitado), no cero — nunca reportes que al cliente le quedan 0 timbres en ese caso.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds valuable context beyond that: the scope is the current calendar month in Mexico City time, the response includes a reset period, and the critical enterprise caveat that cfdiIncluded/cfdiRemaining are null, not zero, with explicit instructions not to report 0 timbres.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero filler: the first front-loads the core functionality and timeframe, the second is a tightly-scoped edge-case warning. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even without an output schema, the description gives the essential return semantics: usage vs limit, reset timing, and the null-values caveat that prevents misreporting. An agent has everything needed to call the tool and interpret the result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the description has no parameter behavior to document. Per the rubric, a tool with 0 params gets a baseline of 4; no further param info is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the exact verb ('Devuelve') and resource (CFDI timbrados in the current calendar month against the plan limit, plus the reset period). It clearly distinguishes from sibling tools like timbrix_crear_cfdi_ingreso and timbrix_cancelar_cfdi by being a read-only status query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The full purpose makes the usage scenario obvious: an agent should call this when it needs current CFDI stamping usage against the plan limit or the period reset time. It does not explicitly name alternatives or state when not to use it, but confusion with the mutation/list siblings is unlikely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

timbrix_crear_cfdi_ingresoTimbrar CFDI de ingresoA

Timbra (sella ante el SAT vía PAC) un CFDI 4.0 de tipo Ingreso para la organización configurada. Devuelve el UUID fiscal, el XML timbrado y el estatus.

ParametersJSON Schema
NameRequiredDescriptionDefault
useYesClave SAT de uso de CFDI (catálogo c_UsoCFDI), ej. 'G01'
dateYesObligatorio. Fecha y hora de emisión del CFDI en ISO 8601 sin zona horaria, en hora local de Ciudad de México (America/Mexico_City, UTC-6) — NUNCA en UTC. El PAC compara este valor directamente contra su propio reloj de servidor, que está en hora de México sin ninguna conversión; una fecha en UTC se ve ~6 horas en el futuro y el timbrado falla (a veces reportado como el confuso 'CFDI40102 - digestión no coincide con el sello' en vez de un error de fecha claro). El SAT exige que esté dentro de las 72 horas previas al timbrado, por lo que debe indicarla explícitamente el llamador; el servidor no la asigna por su cuenta.
itemsYesConceptos del CFDI
seriesYesSerie del folio (ej. 'A')
currencyNo
customerNoDatos del receptor (excluyente con customerId)
exchangeNo
confirmadoNoEnvíalo como true en una segunda llamada, después de que un humano confirme explícitamente, para timbrar a pesar de que el subtotal supere `umbral_confirmacion_mxn`. Default: false.
customerIdNoID de un cliente ya registrado (excluyente con customer)
folioNumberYesNúmero de folio
paymentFormYesClave SAT de forma de pago (catálogo c_FormaPago), ej. '01' = Efectivo
paymentMethodNo
idempotencyKeyNo
requiere_confirmacionNoSi es true, valida el subtotal estimado del CFDI (suma de items[].amount) contra `umbral_confirmacion_mxn` antes de timbrar. Si lo supera y `confirmado` no es true, el tool NO timbra: retorna un mensaje estructurado pidiendo confirmación explícita en vez de proceder. Default: false (no bloquea el flujo estándar).
umbral_confirmacion_mxnNoMonto en MXN a partir del cual se requiere confirmación explícita antes de timbrar. Obligatorio cuando `requiere_confirmacion` es true.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate it is not read-only (mutating), not idempotent, and not destructive. The description adds the return format (UUID, XML, status) but does not disclose side effects, permission requirements, or irreversible consequences. It does not contradict annotations; the added value is modest, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler, front-loading the core action and return values. Every sentence contributes meaning, and it is appropriately sized for the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the tool's complexity (15 parameters, nested objects, a confirmation threshold flow, timezone-sensitive date handling), the description provides only a minimal overview. It does not mention the `requiere_confirmacion`/`confirmado` workflow or the date timezone pitfall, which are critical for correct invocation. With no output schema, the description should summarize these to guide the agent; it falls short.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (73%), and many parameters have explicit descriptions (e.g., date timezone warning, confirmation flow fields). The description itself adds no parameter-level detail beyond what the schema already provides. Baseline 3 is correct when the schema carries the documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear, specific verb ('Timbra' = stamps) and resource ('CFDI 4.0 de tipo Ingreso') and explicitly lists what it returns (UUID, XML, status). This distinguishes it from sibling tools that cancel, list, or check balance, so an agent can identify it unambiguously.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies it is for creating/stamping income CFDI but offers no explicit guidance on when to use it versus alternatives, nor any prerequisites (e.g., configured organization) or conditions for use. Since siblings perform different actions, the lack of exclusions is acceptable, but the description does not add usage context beyond the action itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

timbrix_listar_cfdiListar CFDIA
Read-onlyIdempotent

Lista los CFDI timbrados de la organización configurada, más recientes primero, con filtros opcionales de tipo y estatus.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
typeNo
limitNo
statusNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already communicate read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral context beyond those annotations: results are restricted to the configured organization and are sorted most recent first. No additional side effects, rate limits, or response details are disclosed, but the safety profile is well covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It packs the resource, scope, ordering, and filters into a concise statement that earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list operation with annotations covering safety, the description is mostly sufficient. However, with no output schema and no mention of pagination semantics, the documentation is not fully complete for an agent needing to use paginated results correctly. The core purpose is clear, but the page/limit handling is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It clarifies that 'type' and 'status' are optional filters, but it does not explain the pagination parameters 'page' and 'limit', nor the meaning of the enum values ('I', 'E', 'T'; 'vigente', 'cancelado'). This leaves half the parameters semantically underdocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Lista') and a clear resource ('CFDI timbrados'), plus the organizational scope and ordering ('más recientes primero'). It also names the optional filters, making its purpose distinct from the sibling mutation and balance tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: it is a read-only listing tool for the configured organization's stamped CFDI. However, it does not explicitly state when to use this tool over alternatives or when not to use it, leaving selection to inference from the tool name and siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.5.0
    • First observedtimbrix_cancelar_cfdi
    • First observedtimbrix_consultar_saldo
    • First observedtimbrix_crear_cfdi_ingreso
    • First observedtimbrix_listar_cfdi

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Cada herramienta cubre una acción distinta: timbrar, cancelar, listar y consultar saldo. No hay solapamiento real entre ellas; incluso listar y consultar saldo se diferencian claramente porque uno devuelve documentos y el otro uso mensual del plan.

Naming Consistency5/5

Las cuatro herramientas siguen el patrón consistente timbrix_ + verbo en infinitivo + objeto: crear_cfdi_ingreso, cancelar_cfdi, listar_cfdi, consultar_saldo. La variante con subtipo en crear_cfdi_ingreso es descriptiva y no rompe la convención.

Tool Count5/5

Cuatro herramientas es una cantidad adecuada para un servicio especializado de timbrado fiscal: cubre las operaciones esenciales sin inflar la superficie. No hay herramientas redundantes ni faltan piezas obvias dentro del alcance declarado.

Completeness4/5

El ciclo principal queda cubierto: crear/timbrar, cancelar, listar y monitorear saldo. Faltan detalles menores como consultar un CFDI específico por UUID o descargar el XML de uno ya timbrado, pero no son huecos que impidan el flujo de trabajo central.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to issue Mexico CFDI 4.0 electronic invoices (factura electrónica) via Facturapi, with tools for creating, querying, canceling, and sending invoices.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that lets AI agents issue Brazilian NFS-e service invoices via Focus NFe, with tools for creating, querying, and canceling invoices.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server that exposes Brazilian tax infrastructure as tools, resources, and prompts, enabling AI agents to emit and manage fiscal documents (NF-e, NFC-e, NFS-e, CT-e, MDF-e, DC-e) through natural language.
    -
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to access the Billingo v3 invoicing API through MCP, providing 49 read/write tools for managing invoices, partners, and related data over stdio or HTTP transports.
    22
    48 npm
    MIT