npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@timbrix/mcp

v0.6.0

Published

MCP (Model Context Protocol) server for Timbrix — stamp, cancel and query CFDI 4.0 invoices from AI agents

Readme

@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.

Public source, issues, and PRs: github.com/Timbrix/mcp.

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/date/rfcReceptor 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

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 --filter @timbrix/mcp dev # watch build
pnpm --filter @timbrix/mcp test # vitest
pnpm --filter @timbrix/mcp build # tsup

License

MIT © Timbrix — see LICENSE.