@txnod/mcp-stdio
v0.1.0
Published
stdio↔HTTPS bridge for the TxNod MCP server — wraps `https://mcp.txnod.com/api/mcp/transport` for MCP clients that only speak the stdio transport (Claude Desktop). Zero runtime deps, zero CLI flags, zero config — reads exactly one env var (`TXNOD_PAT`).
Readme
@txnod/mcp-stdio
Tiny stdio↔HTTPS proxy that lets Claude Desktop talk to the TxNod MCP server. Claude Desktop only speaks the stdio MCP transport; the TxNod server is HTTP-only at https://mcp.txnod.com/api/mcp/transport. This wrapper is the bridge.
For Claude Code, Cursor, or any other MCP client that already supports HTTP, you do NOT need this package — point them directly at the URL above. See the HTTP-transport guides.
Install
npm install -g @txnod/mcp-stdio
# or, no install — let Claude Desktop run it on demand:
npx -y @txnod/mcp-stdioNode ≥ 20 is required. Zero runtime and zero peer dependencies. The global install exposes a single binary, txnod-mcp-stdio.
Claude Desktop config
Add the following block to ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows:
{
"mcpServers": {
"txnod": {
"command": "npx",
"args": ["-y", "@txnod/mcp-stdio"],
"env": {
"TXNOD_PAT": "txnod_pat_<your-token>"
}
}
}
}Restart Claude Desktop after editing the config. The txnod server will appear in the MCP panel and its tool inventory will show up in the next agent run.
If you prefer the global-install path, replace command: "npx" and args: [...] with "command": "txnod-mcp-stdio" (no args). Both forms are equivalent.
Get a token
Generate a Personal Access Token in the TxNod dashboard at https://txnod.com/developer/tokens. The PAT is shown exactly once at creation; copy it directly into claude_desktop_config.json rather than into a notepad you'll forget about. The PAT format is txnod_pat_<32 base62 chars>.
OAuth 2.1 path (alternative to PAT)
This bridge ships PAT bearers only. You do not need to use OAuth to use TxNod's MCP server — a PAT in claude_desktop_config.json is the simplest, lowest-friction path and is what the rest of this README documents. If your MCP client already speaks HTTP + OAuth (Claude Code, Cursor, and most MCP-marketplace templates), the client can use TxNod's RFC 6749 + RFC 7591 endpoints directly without this stdio bridge at all.
If you are an author of such an MCP client, the relevant TxNod endpoints are:
- Authorization-server metadata (RFC 8414):
https://txnod.com/.well-known/oauth-authorization-server - Protected-resource metadata (RFC 9728):
https://mcp.txnod.com/.well-known/oauth-protected-resource/api/mcp/transport - Dynamic client registration (RFC 7591):
https://txnod.com/api/oauth/register - Token endpoint (
authorization_code+refresh_token, PKCE-required):https://txnod.com/oauth/token - Revocation endpoint (RFC 7009):
https://txnod.com/oauth/revoke - Canonical resource URI (must be sent on every code/refresh exchange):
https://mcp.txnod.com/api/mcp/transport
A confidential client receives client_secret exactly once in the registration response — capture it immediately, the server only stores its sha256 hash. There is no "show me my secret again" recovery path; lose it and you re-register. The token endpoint enforces per-IP and per-client_id rate limits and is strict about PKCE, the canonical resource URI, and refresh-token rotation lineage (a replayed refresh token cascade-revokes its lineage).
The MCP transport endpoint at https://mcp.txnod.com/api/mcp/transport accepts both PAT and OAuth bearers — it switches on the Authorization: Bearer <token> prefix structurally — so the same set of 21 tools is reachable via either path.
Required scopes
PATs carry a flat scope list. TxNod's MCP server exposes 21 tools today — 7 read-only data tools, 13 sandbox-only simulation tools that mutate state (advance invoices, fire webhooks, reset / delete sandbox projects), plus one sandbox read tool (sandbox_list_wallets) which is gated by projects:read, not sandbox:simulate. The 13 simulation tools require both the sandbox:simulate PAT scope and a project with kind = 'sandbox'; sandbox actions cannot ever target a production project (server enforces this with a uniform not_found collapse, defended by assertSandboxProjectKind). Mint a PAT with sandbox:simulate only when the agent actually drives sandbox simulations — leave it off otherwise.
Read tools (7) — non-sandbox:
| Tool | Required scope |
|---|---|
| list_projects | projects:read |
| list_invoices | invoices:read |
| get_invoice | invoices:read |
| get_webhook_events | webhooks:read |
| get_orphan_payments | transactions:read |
| get_rates | invoices:read |
| quote_amount | invoices:read |
Sandbox simulation tools (13, all require sandbox:simulate + a kind='sandbox' project):
| Tool | What it does |
|---|---|
| sandbox_simulate_detect | Mark an invoice as on-chain detected |
| sandbox_simulate_paid | Drive an invoice to paid |
| sandbox_simulate_overpaid | Drive to overpaid (extra amount credited) |
| sandbox_simulate_partial | Drive to partial (insufficient amount credited) |
| sandbox_simulate_expire | Force expiry past expires_at |
| sandbox_simulate_late_payment | Pay an already-expired invoice (expired_paid_late) |
| sandbox_simulate_reorg | Revert a paid invoice via simulated reorg |
| sandbox_simulate_reconfirm | Re-confirm after reorg (paid → reverted → paid) |
| sandbox_simulate_duplicate_delivery | Re-fire a terminal webhook event |
| sandbox_simulate_event | Dispatch an arbitrary webhook event |
| sandbox_clock_advance | Advance the project's simulated clock |
| sandbox_reset | Wipe all sandbox project data |
| sandbox_delete | Delete the sandbox project entirely |
Sandbox read tool (1) — gated by projects:read (not sandbox:simulate):
| Tool | Required scope |
|---|---|
| sandbox_list_wallets | projects:read (still requires kind='sandbox' project at runtime) |
sandbox_list_wallets is structurally a read tool — it returns the auto-provisioned per-chain testnet xpubs so an agent can echo them into .env for the SDK's address-verification path — and is gated by projects:read rather than sandbox:simulate. The cross-mode guard still fires at the server (the tool is unusable against a production project), but a token minted only for sandbox simulation will return insufficient_scope on this tool. The same scope split is documented in the Connect Claude Code guide.
Pick the narrowest set the agent actually needs. The full PAT scope reference lives at https://docs.txnod.com/guides/personal-access-tokens.
All MCP tools share a single 60-call-per-minute per-token rate limit; get_rates / quote_amount may additionally return internal_error during cold-start (retry after a short delay). Tool inputs no longer carry a network filter — the project's kind ('production' | 'testnet' | 'sandbox') is fixed at create time and selects the underlying chain network implicitly. To inspect testnet invoices, point the PAT at a testnet-kind project; production / testnet rows never co-exist within one project.
What you'll see
Tool responses are shaped by the same Zod schemas the TxNod REST API and SDK use. Notable fields the agent will encounter:
- The webhook envelope
mode: 'production' | 'testnet' | 'sandbox'field reflects the emitting project'skind.InvoiceResponseitself no longer carries anetworkdiscriminator — the kind is implicit from the project the PAT is bound to. If your agent processes events from multiple projects, branch on the webhook envelope'smodeto route across kinds. - TRON invoices (
coin: 'trx' | 'usdt_trc20') require the operator to pre-activate addresses; partner-side errors carryerror_code: 'tron_no_activated_addresses_available'with awallet_idfield. See https://docs.txnod.com/guides/wallets#tron-address-activation. - BSC
usdt_bep20/usdc_bep20use 18 decimals on-chain (not 6). Theamount_cryptofield already reflects this — render it verbatim, do not re-scale. - TON invoices (
coin: 'ton' | 'usdt_ton') are memo-chain: every TON invoice for a given operator shares the same deposit address and is disambiguated by an 8-hexpayment_tokenplaced in the on-chain transaction comment. Wallet apps auto-fill the comment when the user followsinvoice.payment_urior scans its QR code; if a user types the address by hand and omits the comment, the deposit surfaces inget_orphan_payments(chainton) rather than ever reachinginvoice.paid. See https://docs.txnod.com/guides/supported-chains#ton.
There is no scope named mcp_tools_* or similar; the mapping is the flat PAT scope list above. Note: the 13 sandbox simulation tools mutate state by design — they exist so an agent can drive an entire invoice lifecycle (detect → paid → reverted → re-confirmed) end-to-end without on-chain spend. Sandbox mutations are constrained to projects with kind = 'sandbox'; the server's assertSandboxProjectKind predicate collapses any miss (wrong project / wrong owner / production project / soft-deleted project) into a uniform not_found so an agent cannot oracle-probe production-project ULIDs through sandbox tools.
Security guarantee
This package reads exactly one environment variable (TXNOD_PAT) and accepts zero command-line flags. The remote URL https://mcp.txnod.com/api/mcp/transport is hard-coded in source. An attacker who controls your mcpServers config cannot redirect the wrapper to a different host or smuggle in additional credentials — the URL cannot be overridden, no flag is parsed, and no other env var is read.
The PAT is sent only to the hard-coded URL via Authorization: Bearer <pat>. It is never logged, never written to disk, never sent to a third party.
Server-side audit
Every MCP call is recorded in the mcp_audit_log table on the TxNod server (token id, tool name, project id, response status, error code, request/response timestamps). The dashboard does not yet expose this table through a UI — the data is available via direct database access for operator forensics. A user-facing audit view is planned but not yet shipped.
Troubleshooting
- PAT not found / 401: verify
TXNOD_PATis set in theenvblock of yourmcpServers.txnodentry. Re-issue the token from https://txnod.com/developer/tokens if you lost the original. Tokens are revocable and never recoverable — only re-issuable. - Tool call returns
insufficient_scope: the PAT was minted with too narrow a scope set. Either re-issue with the right scopes (table above) or pick a different tool. - Bridge keeps disconnecting: the wrapper does not retry transient errors inline — it writes a JSON-RPC error frame and lets Claude Desktop respawn the process. If you see repeated reconnects, check (a) network reachability of
mcp.txnod.com, (b) the TxNod server status, (c) that the PAT has not expired. - Stale tool inventory after token swap: Claude Desktop caches MCP server descriptors per session. Fully quit Claude Desktop (not just the window) and relaunch.
