MoneySwitch MCP Server
Provides an OpenAI-compatible gateway so OpenAI SDK-compatible clients can use MoneySwitch to make paid requests through the policy-enforced USDC payment engine.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MoneySwitch MCP ServerPay the image API up to 2 USDC to generate a product photo"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MoneySwitch
Give your AI an API key for money.
Website: moneyswitch.dev · 中文说明 →
An AI agent holds a mk_live_xxx MoneyKey — not a wallet private key —
and spends USDC through x402-priced HTTP APIs on the
Monad testnet. MoneySwitch checks policy (budgets,
per-request limits, an approval threshold, a host allowlist, an SSRF guard)
before every payment, then signs the USDC authorization itself with a
locally-held, low-balance wallet. The agent never sees the private key.
Why
The industry already taught AI agents one pattern: hold a string that starts
with a prefix (sk-…, mk_live_…), put it in an Authorization header,
and the rest is handled for you. MoneySwitch reuses exactly that pattern for
money instead of inventing a new one — no wallet extension, no seed phrase,
no signing UI for the agent to click through. The agent calls an HTTP API
with a bearer token; MoneySwitch is the thing standing between that token
and an on-chain USDC transfer, enforcing the same kind of limits an
API-key-issuing platform already enforces on rate and spend.
Related MCP server: obol-mcp
30 seconds
Try it — fully offline, no real money (Node.js 22+):
npx moneyswitch demoA throwaway MoneySwitch starts on free local ports with a mock wallet, a demo
LLM channel, two MoneyKeys ("Claude Code", "Codex"), a toll booth in front of
a demo API and a few payments, and the Dashboard opens already signed in.
Send a message in the Playground ($0.01), try to buy a $5 report and watch
the per-request limit block it, then look at the toll booth's income. Every
screen says DEMO · simulated settlement; settlement goes through a local
mock facilitator and never touches a chain. Ctrl+C stops it and deletes the
data. (moneyswitch demo downloads the separate, AGPL-3.0-only
moneyswitch-server package; if your npm mirror has not synced it yet, add
--registry=https://registry.npmjs.org/.)
Self-host the server + Dashboard in one command:
npx moneyswitch-server # http://127.0.0.1:4020, data in ~/.moneyswitch/serverOn first start it prints a one-time setup link (http://127.0.0.1:4020/setup#ms_setup_…)
that signs you in and walks you through wallet → channel → first key →
connecting an agent. --data-dir, --port and --host change the defaults.
Connect your local Claude Code / Codex to a MoneySwitch server with a MoneyKey:
npx moneyswitch connect --server http://127.0.0.1:4020 --key mk_live_xxx --applyThis detects Claude Code / Codex on your machine and wires up the
MoneySwitch MCP server (without --apply it only prints the planned
changes). npx moneyswitch status --server … --key … checks a MoneyKey's
remaining budget; npx moneyswitch remove --apply undoes it;
npx moneyswitch ui opens the local desktop console. The Dashboard's
Connect agent page and the "send to employee" message generate these
commands with the right address.
Charge AI for your own API (no server needed):
npx moneyswitch sell --upstream http://localhost:8000 --price 0.01 --pay-to 0xYourPublicAddressFrom a checkout (contributors):
pnpm install
pnpm build
pnpm demo:localpnpm demo:local starts a mock x402 facilitator, a demo x402 seller, and
the MoneySwitch server (with the Dashboard UI) from the repository, entirely
offline — no real payment happens. See docs/quickstart.md
for the real Monad-testnet path (pnpm demo:testnet) and the manual
step-by-step version.
Architecture
mk_live_xxx (MoneyKey, not a private key)
│
┌──────────────┐ MCP / OpenAI-compatible / REST ┌────────────────────┐
│ AI Agent │ ───────────────────────────────► │ MoneySwitch server │
│ (Claude Code, │ │ (apps/server) │
│ Codex, ...) │ ◄─────────────────────────────── │ policy → wallet │
└──────────────┘ result / usage / error │ (apps/dashboard) │
└─────────┬──────────┘
│ x402 (EIP-3009 USDC auth)
▼
┌────────────────────┐
│ x402 facilitator │
│ (settles on-chain) │
└─────────┬──────────┘
▼
┌────────────────────┐
│ Monad testnet │
│ USDC Transfer │
└─────────┬──────────┘
▼
┌────────────────────┐
│ x402 seller / │
│ priced API │
└────────────────────┘The server holds the private key in an encrypted, low-balance local wallet
(packages/wallet); the agent process never has it. Every payment is
checked against policy (packages/core) inside a database transaction
before a signature is produced.
Three ways to plug an agent in
MCP (
apps/mcp, stdio) —money_status,paid_fetch,money_historytools.npx moneyswitch mcp, ormoneyswitch connect --applywires it into Claude Code / Codex automatically. Seedocs/claude.md,docs/codex.md.OpenAI / NewAPI-compatible gateway — set
Base URL = http://<server>/v1,API Key = mk_live_xxxin any OpenAI-SDK-compatible client (openai SDK, Cherry Studio, Open WebUI, NewAPI upstream channel).GET /v1/models,POST /v1/chat/completions, and the legacy OpenAI billing endpoints are implemented — seeSPEC-v0.2.mdanddocs/money-api-v0.md.REST —
POST /v1/fetch { url, method?, headers?, body?, max_price? }fetches any x402-priced URL through the policy engine directly. Seedocs/money-api-v0.md.
Get paid: toll booths (v0.5)
MoneySwitch can also receive money. Put a toll booth in front of an API you already run: AI agents pay USDC per call over x402, the money goes straight to your receiving address, and the Dashboard shows it like revenue. You need no secret to sell — only a public receiving address — and your service does not change a single line.
The three things (read this first)
Thing | Think of it as | Give it to | In MoneySwitch |
Private key | the key to the safe | nobody | never shown anywhere; it only lives (decrypted) in the server's memory |
MoneyKey | a capped company card for an employee | only your own AI | 🔒 amber, "Secret: whoever holds it can spend within its limits — never send it to a seller" |
Receiving address | your payment QR code | anyone | ✅ green, "Public: people pay you with it, safe to share" |
Paste a MoneyKey, admin token, private key or recovery phrase into any
receiving-address field and it is blocked and explained (the server refuses
it too with INVALID_PAY_TO); paste a 0x… address into a key field and it
is blocked the same way. The receiving address defaults to this
MoneySwitch's own wallet (one wallet receives and pays); you can point it
at any other address you control, e.g. a cold wallet — MoneySwitch then
cannot spend that money for you.
In the Dashboard
Toll booths → New toll booth: ① which service (http://127.0.0.1:8000,
with a free "test connection") ② how to charge (templates such as "the whole
service, $0.01 per call" or "/v1/chat/completions $0.01, everything else
free"; rules are METHOD /path or /prefix/*, the most specific wins; paths
that match no rule are charged a default price, passed through free, or
refused) ③ where the money goes. You get a public address
https://<server>/t/<slug>/… to hand to buyers, plus ready-made buyer
snippets. Earnings shows today / 7 days / all, per toll booth and per
rule, every payment (payer, route, amount, tx, upstream status) and a CSV
export.
# anyone: 402 + price + pay_to
curl -i http://127.0.0.1:4020/t/weather/v1/today
# a buyer, with THEIR OWN MoneyKey
curl -s http://127.0.0.1:4020/v1/fetch \
-H "Authorization: Bearer mk_live_xxx" -H "Content-Type: application/json" \
-d '{"url":"http://127.0.0.1:4020/t/weather/v1/today"}'An OpenAI-compatible upstream behind a toll booth can be added as a
channel in another MoneySwitch (Base URL = https://<server>/t/<slug>/v1).
Buyers are only charged when your service answers 2xx/3xx. The payment
is verified first, the request is forwarded, and it is settled only on
success; on 4xx/5xx/timeouts it is cancelled and recorded as "not charged".
Your upstream receives X-MoneySwitch-Payer, X-MoneySwitch-Amount and
X-MoneySwitch-Tollbooth, never the buyer's Authorization/Cookie or
payment headers. Only /t/* has to be reachable by buyers — keep the admin
API and Dashboard private (see docs/security.md); set
MONEYSWITCH_PUBLIC_URL to the address buyers use. API details:
docs/money-api-v0.md.
Without a server: moneyswitch sell
npx moneyswitch sell \
--upstream http://localhost:8000 --price 0.01 --pay-to 0xYourPublicAddress \
--route "POST /v1/chat/completions=0.02" --route "GET /health=0"A single process on your machine (official @x402/express), with the same
rule matching and forwarding code as the server's toll booths. It prints the
public address and your (public) receiving address, and refuses a MoneyKey
or private key as --pay-to.
Roles
Role | Holds | Uses | Can do |
Admin (owner / finance) |
| Dashboard | wallet, channels, issue/revoke MoneyKeys, approve payments, see all usage |
Employee | one or more | Dashboard "My Budget" view + desktop CLI | see own budget/history, Playground, one-command connect to their own local agent; cannot see others, cannot touch the wallet |
Agent (Claude Code / Codex / Cherry Studio / …) |
| MCP or OpenAI-compatible interface | spend money, bounded by policy |
Seller | only a public receiving address | a MoneySwitch toll booth, | receive USDC; with a toll booth, see income under Earnings |
Security model & guardrails
The agent never holds a private key. Only a
mk_live_…MoneyKey, scoped by budgets/allowlist/approval — the same shape as any other API key an agent already knows how to use.Policy runs before signing, inside one database transaction: per-request limit →
max_pricecap → daily/total budget → approval threshold. Nothing is signed until every check passes.Host allowlist governs every outbound request, including free ones —
POST /v1/fetchis fundamentally an outbound proxy. An empty allowlist denies everything.SSRF guard: MoneySwitch always refuses to let an agent point it back at its own listening address, in any common literal form (
127.0.0.1/localhost/0.0.0.0/::1). This is literal/hostname matching, not a DNS-rebinding defense — see SECURITY.md for the exact limitation.Secrets never round-trip. The full MoneyKey and admin token are shown exactly once, at creation; only their SHA-256 hash is stored. The wallet private key exists decrypted only in-process memory while unlocked, never on disk, never logged, never returned by any API response.
unknownpayment outcomes count as spent, conservatively, rather than risk silently exceeding a budget when an upstream result can't be determined (timeout, dropped connection). Audit them manually viaGET /v1/admin/usage.
Full threat model: docs/security.md /
SECURITY.md.
Monad testnet
MoneySwitch's x402 client and mock-facilitator test suite are built against
these testnet facts, checked against a live RPC as part of the repo's own
pnpm test:testnet (see SPEC.md §1 for the full, dated table):
Value | |
CAIP-2 network |
|
RPC |
|
USDC (testnet) |
|
Facilitator |
|
Payment scheme |
|
A real settlement (no mock) is a paid_fetch//v1/fetch call that produces
a tx_hash, independently checkable by fetching that transaction's receipt
and finding a matching USDC Transfer(from=wallet, to=seller, value=…) log
— see tools/m6/verify-transfer.mjs. MoneySwitch never auto-funds a wallet
or auto-requests testnet tokens; that's always a manual, out-of-band step
(see docs/quickstart.md).
As of 2026-09-26, 11 real (non-mock) x402 payments have been settled on the
Monad testnet this way — paid fetches, OpenAI-SDK chat completions and an
approval-gated payment — all visible on-chain; 4 of them (first payment,
Claude Code via MCP, OpenAI SDK chat, approval-gated) were checked
Transfer-by-Transfer with tools/m6/verify-transfer.mjs. All were gas-free for the agent's wallet (the facilitator relays and pays
gas for exact/EIP-3009 settlement), first tx 0x1c83a45d…4d4d (block
65595248).
Roadmap
v0.1 (done): MoneyKey, policy engine, local wallet, x402 client, MCP, Dashboard, offline (T1/T2) and testnet-read (T3) test suites.
v0.2 (done): OpenAI/NewAPI-compatible gateway (
/v1/chat/completions,/v1/models, billing endpoints), channels, Playground.v0.3 (done): employee-facing Dashboard view, one-command desktop connect (
moneyswitch-connect→ themoneyswitchnpm package).v0.4 (done): child MoneyKeys (multi-level delegation) and the local desktop console (
moneyswitch ui).v0.5 (done): toll booths — sell any API to AI for USDC (
/t/<slug>, Earnings,moneyswitch sell); v0.5.1:npx moneyswitch demo(offline tour) andnpx moneyswitch-server(one-command self-host).Next: per-token pricing (x402
upto), MetaMask / OKX wallet drivers, multi-user organizations with department budgets and approval flows.Not planned (see
SPEC.md§12 for the full list and why): wallet-extension import, mainnet-by-default, fiat on-ramp.
License
MoneySwitch is dual-licensed by component: the parts an agent or seller embeds in their own process are permissive; the self-hosted server stays copyleft so that hosted forks give improvements back.
Component | License |
| |
| |
| |
| |
Everything else ( |
The two npm packages are published separately: moneyswitch (Apache-2.0)
never contains server code; moneyswitch demo only runs
moneyswitch-server (AGPL-3.0-only) through npx as a separate process.
To embed the server in a closed-source product, open an issue to discuss a commercial license.
Contributing
See CONTRIBUTING.md. Contributions require agreeing to CLA.md (so the project can keep offering the dual-license terms above). Please read CODE_OF_CONDUCT.md first.
This server cannot be deployed
Maintenance
Related MCP Connectors
Pay for HTTP APIs and charge for your own: x402 micropayments in USDC on Base.
Wallet and payments for AI agents: auto-pay x402 APIs in USDC on XDC, within on-chain limits.
30 pay-per-call APIs for AI agents: compliance, trade, safety, web, data. USDC on Base via x402.
Pay-per-call tools for autonomous agents, settled in USDC on Base via x402.
Related MCP Servers
AlicenseAqualityAmaintenanceEnables AI agents to call paid APIs and settle HTTP 402 payment challenges with USDC on Base, without private keys ever being involved.7168 npmMIT- AlicenseAqualityCmaintenanceLets AI agents discover, pay for, and call any HTTP API per request using USDC, with gasless nanopayments and no API keys or accounts needed.563 npmMIT

@hpp-io/x402-mcp-bridgeofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to autonomously pay for and discover services using HPP USDC.e over the x402 protocol, without API keys or manual signing.54 npmApache 2.0- AlicenseNot gradedqualityDmaintenanceMulti-chain x402 payment gateway enabling AI agents to pay per HTTP call with real on-chain settlement across 5 mainnet chains, providing 18 paid endpoints for utilities, data, and security.MIT