Connect Claude Code
Claude Code talks to the TxNod MCP server over HTTP. Two credential modes ship in parallel: OAuth 2.1 auto-discovery (default) and Personal Access Tokens (advanced / CI).
Quick start (recommended — OAuth auto-discovery)
When you add https://mcp.txnod.com/api/mcp/transport to Claude Code’s MCP server config without an Authorization header, Claude Code auto-discovers the TxNod authorization server, opens a browser for sign-in (email-OTP or Google), and stores the resulting OAuth tokens locally. Subsequent runs use cached tokens until they expire or you revoke the client at /account/connected-apps.
{
"mcpServers": {
"txnod": {
"url": "https://mcp.txnod.com/api/mcp/transport"
}
}
}The claude mcp add CLI auto-handles OAuth when no --header Authorization=... flag is passed:
claude mcp add txnod \
--transport http \
--url https://mcp.txnod.com/api/mcp/transportSee the MCP OAuth guide for protocol details, token TTLs, and revocation.
Advanced — manual paste (Personal Access Token)
PATs remain useful for CI pipelines (no browser available), shared automation accounts, and operators who prefer not to grant a client browser-based session access.
Mint a token
Open the dashboard’s Developer → Tokens page and click New token. Pick the scopes the agent actually needs and a short-ish expiry — :read scopes are the safest default for exploration, but :write, webhooks:manage, and admin:all are available when you want the agent to act on your behalf. Copy the token immediately — the secret is shown exactly once. See the Personal Access Tokens guide for the full scope matrix.
Add the server
Claude Code reads MCP server configuration from a JSON config file (typical paths: ~/.claude/mcp_servers.json on Linux/macOS, the equivalent under your Windows profile). Add the txnod entry:
{
"mcpServers": {
"txnod": {
"url": "https://mcp.txnod.com/api/mcp/transport",
"headers": {
"Authorization": "Bearer <YOUR_TOKEN>"
}
}
}
}Replace <YOUR_TOKEN> with the secret you just minted. The dashboard’s MCP helper card on the Developer Tokens page renders the same JSON with your mcp.txnod.com URL pre-filled — copy it directly to skip a step.
You can also add the server via the claude mcp add CLI in one command — same URL, same Authorization header:
claude mcp add txnod \
--transport http \
--url https://mcp.txnod.com/api/mcp/transport \
--header "Authorization: Bearer <YOUR_TOKEN>"Verify
Restart Claude Code. The next agent run should list txnod among the available MCP servers and expose 21 tools — 7 read-only data tools (list_projects, list_invoices, get_invoice, get_webhook_events, get_orphan_payments, get_rates, quote_amount) plus 14 sandbox-only simulation tools that mutate state (driving the full invoice lifecycle without on-chain spend). The sandbox tools require both the sandbox:simulate PAT scope and a kind='sandbox' project; mint a PAT with sandbox:simulate only when the agent actually drives simulations. If the connection fails, check that:
- The PAT secret is set correctly (no surrounding whitespace, no missing characters).
- The PAT has not expired.
- The PAT has scopes that cover the tools the agent is calling (table below).
- The URL is the HTTP transport endpoint above, not the bare
https://mcp.txnod.comhost.
OAuth-mode failures show different symptoms: a browser window pops up unexpectedly mid-call (auto-discovery / DCR registration failed and the client is retrying the consent flow), or tools start returning 401 invalid_token after a session that previously worked (/account/connected-apps revoke happened, or the access token expired and refresh failed). Re-run the flow by removing the cached token from Claude Code and reconnecting.
Per-tool scopes
21 MCP tools today: 7 read + 14 sandbox-mutating. Mint the PAT with the narrowest scope set the agent actually needs — keep sandbox:simulate off PATs that only consume read tools. PAT scopes themselves are not limited to MCP-tool-coverage; :write, webhooks:manage, and admin:all are available for direct partner-API use today and would gate any future write-capable MCP tool.
| 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_simulate_detect | sandbox:simulate |
sandbox_simulate_paid | sandbox:simulate |
sandbox_simulate_overpaid | sandbox:simulate |
sandbox_simulate_partial | sandbox:simulate |
sandbox_simulate_expire | sandbox:simulate |
sandbox_simulate_late_payment | sandbox:simulate |
sandbox_simulate_reorg | sandbox:simulate |
sandbox_simulate_reconfirm | sandbox:simulate |
sandbox_simulate_duplicate_delivery | sandbox:simulate |
sandbox_simulate_event | sandbox:simulate |
sandbox_clock_advance | sandbox:simulate |
sandbox_reset | sandbox:simulate |
sandbox_delete | sandbox:simulate |
sandbox_list_wallets | projects:read |
Sandbox tools require the
sandbox:simulatescope, which is PAT-only. OAuth’s scope set is structurally fixed at 4 read scopes (projects:read,invoices:read,transactions:read,webhooks:read) —sandbox:simulateis not in it, so OAuth tokens cannot call any sandbox tool (calls return403 insufficient_scope). To drive sandbox tools, mint a PAT withsandbox:simulateand akind='sandbox'target project. The server’sassertSandboxProjectKindpredicate also rejects production projects from sandbox tools — a token with the scope cannot drive simulation against a production project.
Tool inputs do not 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, mint a PAT scoped to a testnet-kind project; production / testnet rows never co-exist within one project. get_orphan_payments returns on-chain receipts that did not match any invoice (TRON activation transactions are server-side excluded). get_rates and quote_amount are indicative pricing — the binding rate is captured at createInvoice time on the partner side.
What to expect in tool responses
The webhook envelope’s mode: 'production' | 'testnet' | 'sandbox' field carries the kind of the emitting project — branch on it if your agent processes events from multiple kinds via one webhook URL. InvoiceResponse itself no longer carries a network discriminator: a project credential implies the kind. TRON invoices (coin: 'trx' / 'usdt_trc20') depend on operator-side address pre-activation; if the operator pool has zero activated addresses, downstream invoice-create attempts surface as error_code: 'tron_no_activated_addresses_available' carrying a wallet_id. BSC usdt_bep20 / usdc_bep20 use 18 on-chain decimals — amount_crypto already reflects this, 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-hex payment_token placed in the on-chain transaction comment; deposits whose comment is missing or unparseable land in get_orphan_payments with chain ton instead of ever reaching invoice.paid. See Wallets · TRON activation, Supported chains · TON, and supported chains for full per-chain quirks.
Other MCP clients
- MCP OAuth (protocol details) — discovery, registration, PKCE, audience binding, token TTLs, revocation.
- Claude Desktop — needs the
@txnod/mcp-stdiowrapper because Claude Desktop only speaks stdio. - Cursor — same HTTP transport as Claude Code; the JSON config is paste-equivalent.