mcp.cashu.exchange
Planned as a stretch payment rail integration, allowing payment instructions and quotes for services via Lightning.
Provides a prepaid Mastercard payment rail for payable services. Supports payment quotes and can expose card credentials when configured.
Provides EV charging station search using OpenStreetMap/Overpass data, returning chargers near a point with default central Berlin.
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., "@mcp.cashu.exchangefind EV chargers near central Berlin and quote the payment"
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.
mcp.cashu.exchange
Successor: the unified order platform DropShop (working title) lives at https://api.cashu.exchange in Amperstrand/mcp-oda — chat, fleet console, map, and MCP over one 402-gated pipeline (demo tier). This repo remains the Berlin hackathon exchange scaffold.
A modular MCP service exchange: one registry, one gateway, and swappable payment rails for payable services — EV charging, food, and more. Built as a hackathon project (Berlin, 2026) to let AI agents discover and pay for real-world services.
Live: https://mcp.cashu.exchange · MCP endpoint: POST https://mcp.cashu.exchange/mcp
Route | What |
| enters the in-repo demo: redirects to |
| Berlin cinema box-office chat (Cashu-settled, Yorck programme) — in this repo |
| links to the flagship favrit closed-beta chat — a private-kit deployment, not in this repo |
| Leaflet map of Berlin EV chargers (OSM/Overpass, KV-cached) |
| MCP server (streamable HTTP, stateless) |
| JSON surfaces for the map/other clients |
| generic registry search — the REST twin of every |
What is deployed right now, with verified example calls and a handover: docs/LIVE.md. Hackathon: demo script with fallbacks — docs/DEMO.md; the 24-hour run-up plan — docs/ROADMAP-24H.md; the slide deck — rendered · source; every claim and how to verify it — docs/EVIDENCE.md.
The idea
An exchange, not a monolith — and one capability, many surfaces: every
provider is reachable as an MCP tool (<id>.search), as REST
(/api/search?category=…), and as a plain library (the underlying package).
Clients pick their transport; the registry does not care.
Three moving pieces:
Native plugins (public, in this repo) — safe to open-source: OpenStreetMap data, checkout-handoff payment instructions, generic contracts.
Federated downstreams (private, yours) — existing MCP servers (
oda-mcp,vipps-mcp, …) mounted through the gateway. Their code and personal data never enter this repo; only their URL + token (secrets).Payment rails — interchangeable
PaymentRailimplementations:2fiat-card(own-card checkout handoff — no card ever touches this repo), Cashu (via pecan for alternative numeraires), Lightning (stretch). See docs/PAYMENT.md.
Related MCP server: remit.md MCP Server
Layout
packages/
contracts/ The two contracts: ServiceProvider, PaymentRail
core/ Registry + MCP server + downstream gateway + catalog
plugin-berlin-charging/ OSM/Overpass charging stations (native plugin)
plugin-pay-2fiat/ Own-card checkout handoff rail (holds no card)
map/ Map frontend (placeholder: worker serves Leaflet page)
chat/ Chat frontend (placeholder: any MCP client works today)
apps/
worker/ Composition root → deploys to mcp.cashu.exchange
docs/
PAYMENT.md The own-card payment pattern (why no card lives here)Architecture
flowchart LR
subgraph P["Participant — own keys, own card"]
B["Browser<br/>(chat / map / checkout)"]
MC["MCP client"]
INBOX["own cashu.email inbox<br/>(npub = account)"]
CARD["own card<br/>(personal or 2fiat)"]
end
subgraph X["mcp.cashu.exchange — public worker (Cloudflare)"]
MCP["POST /mcp<br/>stateless MCP server"]
CHAT["chat sessions + offers"]
SETTLE["Cashu settle"]
REG["registry"]
GW["downstream gateway"]
KV[("KV cache")]
end
subgraph PLUG["Native plugins (this repo, public)"]
CHG["berlin-charging<br/>OSM/Overpass"]
CIN["cinema<br/>(Yorck programme)"]
RAIL["2fiat-card rail<br/>own-card handoff —<br/>holds no card"]
end
subgraph J["Amperstrand/jamezz (public)"]
JC["JamezzClient<br/>menu read + order prepare"]
TESTS["synthetic fakes<br/>+ wiring tests"]
PROMPTS["onboarding prompts<br/>(table / platform / brand)"]
end
subgraph NP["Numo POS — in flight (ai-legion lane)"]
NUMO["Numo Android POS<br/>Cashu tap-2-pay + Lightning"]
NBR["numo-bridge (private)<br/>paid basket to venue order"]
end
subgraph EXT["External"]
QR["qrv5.jamezz.app<br/>(venue API)"]
MOL["Mollie hosted checkout"]
MINT["Testnut Cashu mint"]
OVP["OSM Overpass API"]
end
subgraph KIT["Private kits (federated, never public)"]
DS["europark-parking MCP<br/>(+ oda/vipps/…)"]
end
B --> CHAT --> SETTLE --> MINT
MC --> MCP
MCP --> REG --> CHG & CIN
MCP --> RAIL
MCP --> GW --> DS
CHG --> OVP
CHG --> KV
JC --> QR --> MOL
NUMO -->|customer pays BTC| MINT
NUMO --> NBR --> JC
NBR -->|operator completes| MOL
CARD --> MOL
INBOX -. verification codes .-> BPayment boundary: the hosted checkout URL. The participant opens it and
pays with their own card; no card number ever enters a repo, secret, or tool
(docs/PAYMENT.md). Venue identity flows the other way:
a table QR becomes a JamezzClient venue with zero credentials
(Amperstrand/jamezz).
Component status
Component | Where | Status |
Exchange worker (MCP + chat + map + JSON APIs) |
| deployed; CD blocked on |
Contracts ( |
| done |
Registry + gateway + catalog |
| done |
Berlin charging plugin (OSM/Overpass, KV-cached) |
| done |
Search results KV cache (generic, per-provider keys) |
| done — 10 min TTL |
Cinema plugin (Yorck programme) |
| demo data, capture-dated ( |
Own-card payment rail (card-free) |
| done |
Cashu settlement (chat offers → Testnut mint) |
| done |
Jamezz client + prompts + offline tests | done (1 table mapped) | |
plugin-jamezz: venue tools on the exchange |
| done (live after next deploy) — discovery + menu preview; ordering deliberately stays in the jamezz package |
Numo POS + numo-bridge (customer pays Bitcoin → venue order) | private | proven E2E 2026-10-02 — two live webhook payments, real venue order via jamezz, hosted checkout answered then abandoned; bridge dry-run by default |
Platform clients (read-only) | three public gated clients; 75 live-verified jamezz tables; gastronovi solves the ALTCHA PoW; ordermonkey is plain header-auth | |
Trust-ring vendor vetting (LSAG gate + real Cashu paid leg) |
| reviewed + approved; CI blocked on formatting fix; answers to design questions on #11 |
Venue catalog growth (more QR mids) | jamezz | 75 tables live-verified (chain-crawl + photographed + venue-published); see its |
Pecan (alternative-numeraire settlement) | catalog entry only | wiring not started |
Lightning rail | — | stretch |
jamezz npm publish | — | open decision |
Leak gates + commit wrappers (both repos) |
| done, enforced in CI |
MCP tools
Tool | What it does |
| Catalog + native providers + payment rails |
| Tools from federated downstream MCP servers (europark parking) |
| EV chargers near a point (defaults: central Berlin) |
| Berlin cinema programme (category |
| Jamezz table-ordering venues (category |
| Payment instructions for an amount, per rail |
Develop
npm install
npm test # vitest
npm run typecheck # tsc --noEmit (strict)
npm run check # biome
npm run dev # wrangler dev on :8787Copy .dev.vars.example → .dev.vars for local secrets (gitignored).
Deploy
Deployments run only from the protected prod branch through the
gated production environment (.github/workflows/deploy.yml). The flow:
PR →
main: CI (leak gate + biome + typecheck + tests).PR
main→prod: branch protection requires review and blocks force pushes and deletion.Merge to
prod: the workflow references theproductionenvironment, which requires a reviewer to approve before any secret is touched — any member can initiate, a second person signs off, the owner can override (admin merge /workflow_dispatch).The job re-runs the full gates, then
wrangler deploy.
Secrets live only as environment secrets on production — never in the
repo, never on main-only runs:
CLOUDFLARE_API_TOKEN— custom token, scoped to the one account and thecashu.exchangezone: Account → Workers Scripts → Edit, Zone → Zone → Read (add DNS → Edit only if routes change)CLOUDFLARE_ACCOUNT_ID
The worker serves only mcp.cashu.exchange (workers_dev: false in
apps/worker/wrangler.jsonc — no *.workers.dev surface).
Worker runtime secrets (wrangler secret put, per-name):
DOWNSTREAMS— JSON array[{"name":"oda-mcp","url":"https://…/mcp"}](plus aTOKEN-style secret per downstream if you extend the env parsing)
There are no card secrets, on purpose: participants pay with their own card on the merchant's hosted checkout page. See docs/PAYMENT.md.
Hygiene rules (why this repo stays clean)
Secrets only via
wrangler secret/.dev.vars(gitignored) / GitHub Actions secrets. Never in code, commits, or issues.Fixtures are synthetic. No real names, PANs, cookies, or order histories.
Reverse-engineered API knowledge lives in private kits; this repo consumes them through the gateway. A plugin that needs personal data is a private kit implementing the same MCP surface — not a plugin here.
No tool returns card details — there is no
payment.card_detailsand no card in any secret. The payment boundary is the merchant's hosted checkout URL, opened by the person paying (see docs/PAYMENT.md).
Publication & leak policy
What may be public: contracts/types, synthetic fixtures (inline in tests, with a provenance comment), architecture, infrastructure config that carries no credential material.
What never enters this repo:
Card numbers, license plates, phone numbers, tokens, cookies, session captures — in code, fixtures, docs, or comments.
Captured/sample payloads.
**/fixtures/captures/,**/captures/,*.har,*.pcapare gitignored. If a test needs a response shape, write a synthetic fixture and say so in a comment.Reverse-engineered API knowledge stays in private kits — this repo consumes it over MCP (the gateway), it does not vendor it.
Enforcement: node scripts/leak-scan.mjs . --history runs in CI on every PR
and push — PAN (Luhn-validated), Norwegian/German plates, phones, JWTs, Cashu
tokens, GitHub tokens, secret-shaped key/value pairs. Exceptions live in
scripts/leak-scan-allowlist.txt and require a # because: justification
line above each entry; unjustified entries fail the build.
Adding a component
New provider → new package implementing
ServiceProvider, register it inapps/worker/src/index.ts. Tools appear automatically (<id>.search).New rail → implement
PaymentRail, add toexchangeDeps.Federate an existing MCP server → append to
DOWNSTREAMS. Done.
License
MIT — see LICENSE. Map data © OpenStreetMap contributors (ODbL).
This server cannot be deployed
Maintenance
Related MCP Connectors
AI service marketplace — agents discover, call, and pay for API services automatically.
Marketplace and payment rail for AI agents: list, buy and settle with signed receipts.
Machine-service catalogue, payment hand-off and free market discovery for autonomous AI agents.
Directory of APIs, merchants, and tools AI agents can actually use.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server for AgentPay — the payment gateway for autonomous AI agents. Fund a wallet once, give your agent the key, and it discovers, provisions, and pays for tool APIs on its own. One key, every tool.112 npm1MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to perform financial transactions such as direct payments, escrows, and bounty management using natural language with zero code integration. It provides a comprehensive suite of tools for fund streaming, subscriptions, and reputation tracking to facilitate secure agent-to-agent commerce.5 npmMIT
- FlicenseNot gradedqualityFmaintenanceEnables AI agents to discover, evaluate, and call any x402 API service with automatic USDC payment, including tools for wallet setup, service catalog browsing, recommendations, health checks, and direct API calls.4 npm-
- AlicenseAqualityDmaintenanceEnables AI agents to discover, inspect, and pay for paid HTTP and MCP services using USDC on Solana with a self-custodial wallet.433 npm9Apache 2.0