mcpField
D
DebitMyData Agentic Superhighway

DebitMyData Agentic Superhighway

Remote
id.debitmydata.ioOther0Updated today

About DebitMyData Agentic Superhighway

DebitMyData Agent Gateway is in development for agents, people, and organizations to register for a DID-LLM, pay, and receive credentials. Its end-to-end flow currently runs only on test networks and does not accept real payments.

Key features

  1. 01Discover the service and request a registration quote
  2. 02Pay through enabled payment rails
  3. 03Prove control of a wallet or key
  4. 04Issue a DID-LLM and signed credential

Use cases

  1. 01Register a DID-LLM for an agent on test networks
  2. 02Complete quoting, payment, and identity proof through MCP
  3. 03Receive signed credentials and entitlements for a registration

MCP support

A Streamable HTTP MCP server at `/agenticsuperhighway` exposes the gateway registration flow. Test-network flows support DMD and USDC on Base Sepolia; real payments are not accepted currently.

Configuration

Remote servers need no local install. Pick your client, then copy the config or install in one click.

Endpointhttps://api.debitmydata.io/agenticsuperhighway
Copy install command
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.

Tools

Details

From the project README

DebitMyData Agent Gateway

Status: in development. Nothing accepts real payments yet and every payment rail is switched off by default. The full flow runs on test networks (a private DebitMyData regtest chain, and Base Sepolia for USDC through x402). See Status.

The Agent Gateway is being built as the public integration surface that will let autonomous agents, bots, digital twins, people and organizations discover DebitMyData, get a quote, pay through an approved rail, prove control of their wallet or key, and receive a DebitMyData DID-LLM, signed credential and entitlements.

The gateway sits around the DebitMyData Proof-of-Work chain. It does not change DebitMyData consensus, and it never exposes node RPC, private keys or treasury controls to callers.

Naming. DMD is the ticker of the DebitMyData coin, the native coin of the DebitMyData Proof-of-Work chain (addresses start with dm1); it is what every DebitMyData wallet shows. It is not a token on Ethereum or Base, and it is unrelated to other tokens that use the same ticker. So amounts and prices are in DMD, the payment option is named DebitMyData coin (native PoW chain), and the project, its chain, nodes and explorer are called DebitMyData.

Agent wallet (Coinbase / AWS / DMD / other approved)
        │
        ▼
Discovery: REST / MCP / x402 Bazaar
        │
        ▼
Agent Gateway ── quote + payment intent + policy
        │
        ├── Native DMD adapter ──► private DebitMyData nodes (watch-only)
        ├── x402 / USDC Base adapter ──► facilitator
        ├── Card adapter ──► Stripe Checkout (payment page hosted by Stripe)
        └── future approved rails (disabled until reviewed)
        │
        ▼
Settlement & finality ──► DID-LLM + receipt + credential + entitlements ──► append-only audit

Status

This is an early development release (0.36.3). The whole registration flow (quote, payment, controller proof, DID-LLM and signed credential) works end to end on test networks, through REST and through MCP, paid either in native DMD (private regtest chain) or in USDC through x402 (Base Sepolia); nothing accepts real payments yet:

AreaState
FastAPI service, settings, structured JSON logs, request correlation IDsdone
/healthz, /readyz, /v1/discovery, /v1/payment-options, OpenAPI at /docs/advanceddone
"Get a DID-LLM" page for people at /get-did (production's /docs leads there): quote, payment, a message signed with their wallet, the DID-LLMdone (DMD; USDC through the API)
The debitmydata.com look (top bar, footer, colours, font) on every page for people: "Get a DID-LLM", the advanced API docs, the policies, staging's guided testdone
Advanced API docs that open like the guided pages: the steps as cards that follow the answers, bigger text and buttons, every endpoint belowdone
Payment route registry with per-rail enable flags and kill switchesdone
Normalized payment state machine and the DID-issuance ruledone
Exact decimal / base-unit money arithmeticdone
PostgreSQL schema + migration, append-only audit and payment ledgersdone
Quote endpoint (POST /v1/dids/registration-quotes), price-source rules, Idempotency-Key retriesdone (answers only for enabled rails)
Native DMD payment adapter: per-quote address, independent verification, confirmations, reorg and double-spend handlingdone (regtest)
Payment worker (dmd-gateway-worker) and payment status (GET /v1/payments/{id})done
Controller proof: one-time challenges signed with the agent's Ed25519 key and/or its EVM wallet (ordinary wallets, and smart wallets through ERC-1271 and ERC-6492)done
DID-LLM issuance (did:web), signed registration credential (W3C VC 2.0, eddsa-jcs-2022), dmd_did_holder entitlementdone (regtest; production signer still needed)
MCP server, the Agentic Superhighway, at /agenticsuperhighway with the directive's tools (Streamable HTTP), payer transaction referencesdone
Staging server behind Cloudflare; the whole flow can be tried from its docs page, a guided test page on staging (advanced: Swagger UI step by step at /docs/advanced; staging-only test tools)done
x402 / USDC on Base: HTTP 402 on the registration, facilitator verify/settle, settlement checked on chain, Bazaar description, MCP paymentsdone (Base Sepolia)
Base mainnet readiness: DebitMyData's USDC receiving address (DEC-08), Coinbase's CDP facilitator with API-key authentication, 402 with the real terms for x402 tools that probe the route without a quote (Coinbase's Bazaar validator), scripts/validate_bazaar.pydone (needs DebitMyData's CDP API key and the production server)
Request rate limits (per address and in total, on staging's nginx), open-quote limit per controller key, load-test scriptdone (production limits go at the edge, see docs/staging.md)
DMD/USD reference price from the cost of mining DMD (the electricity a block's work takes), computed every 5 minutes with its inputs stored, GET /v1/prices/dmd-usddone (staging reads the DebitMyData difficulty from the public explorer)
Monitoring and alerts by email and Discord (dmd-gateway-monitor, every 2 minutes): API, payment worker, each payment option's node/RPC/facilitator, DMD price, DebitMyData node vs explorer, payments left the chain after issuance, refunds due, stuck payments, changed receiving addresses; daily reconciliation report that checks every payment settled in the last 30 days again on chain (docs/monitoring.md)done (needs the email and Discord settings on each server)
Minimum DMD/USD rate until DMD has a market price: the price is the higher of 0.001 USD per DMD and the mining cost (a 25.00 USD DID-LLM costs 25,000 DMD), both shown on the price pagedone (approved by DebitMyData on 27 October 2026)
Policy pages (terms, privacy, security, payment methods, refunds, DID-LLM policy) served at /policies, linked from every quotedone (approved, published 2026-11-02)
Inference donations for agents (POST /v1/donations/inference): an amount the agent chooses, paid in USDC through x402 to DebitMyData's inference wallet, answered with a signed receipt; REST, MCP (dmd_purchase) and Bazaar description. People keep donating on debitmydata.com ("Inference $")done (Base Sepolia; production needs DMD_USDC_BASE_INFERENCE_ADDRESS and the CDP facilitator)
Products bought for a DID-LLM: BottyBotty in three tiers (Entry 49, Standard 99, Premium 199 USD), each paid once and owned for good, a higher tier for the difference (/v1/products), paid in DMD, then a receipt signed by DebitMyData and the tier's entitlement on the DID-LLM; REST and MCP (dmd_purchase, dmd_complete_purchase)done (on staging; off in production until BottyBotty's side is connected)
"Get a DID-LLM": the DMD payment as a QR code and an "Open in my DMD wallet" link (debitmydata: payment link)done
"Get a DID-LLM" as an app for phones: on its own address (DMD_GW_APP_HOST, id.debitmydata.io) the page is served at the root with a web app manifest, icons and a service worker, to add to the home screen (docs/production.md); USDC listed first (greyed, "coming soon", while it is off); a short guide to what DMD is and how to get itdone (needs the DNS record)
The pages' top bar is white and stays at the top while scrolling, folds into a menu button on phones (no script needed), the DebitMyData name leads to the site's home, and the footer is in columns like the Agentic Spaces site; a "back to top" button appears as the page scrollsdone
DebitMyData's own logo (the coin side of debitmydata.com's logo, redrawn sharp) in the pages' top bar and as the favicon, with black binary lines; the app's icons show it with red lines (for dark home screens) in a white circle with a gold ringdone
The app offers itself on phones and tablets in a window centred on the screen, with its icon: never inside the app nor when the browser says it is installed (getInstalledRelatedApps, asked at every visit, so the offer comes back once the app is removed); only "Not now" is remembered in the browser, for 30 days (the cross or a tap outside just close it); a "Get the app" button in every page's footer opens it again, or says the app is already installeddone
"Get a DID-LLM" explains DID-LLMs before the steps, in the Agentic Spaces style: the numbers, what a DID-LLM is, why AI agents need one, how it works, with cards that rise into view and lift under the mouse or a tap; the app is named "DID-LLM DebitMyData" on the home screendone
The name DID-LLM everywhere people and agents read it (pages, app, policies, API docs, MCP descriptions, error messages); identifiers stay as they are (did:web, did, /get-did, dids paths)done
For AI agents: /llms.txt (how to register and pay by themselves, with this server's addresses and the payment options open now), linked from the Get a DID-LLM page's top, its footer and a no-script note; the page gives the MCP server's addressdone
The pages' footer lists the three DMD explorers (Mempool explorer, Lite explorer, Rich list & API), as on debitmydata.io; once a DID-LLM is issued, the page offers "Join the Agentic Hub"done
"Get a DID-LLM" shows a debit or credit card (Stripe) and PayPal greyed as coming soon, after USDC and DMD, until the gateway offers themdone
Card payments for DID-LLMs (payment option card_stripe): each quote gets its own Stripe payment page (Stripe Checkout, payment_url), open as long as the 31-minute quote; card details go to Stripe only; the worker checks each payment with Stripe itself (restricted key: Checkout Sessions write, PaymentIntents and Charges read), and settled payments for 30 days for refunds and disputes (refunded, disputed; a registration not yet issued is cancelled, an issued DID-LLM raises an alert); the page sends people to Stripe and continues by itself when they come back; agents get the link for their human (pay_at_payment_url) (docs/card-payments.md)done (tested on staging in Stripe test mode; approved for production by DebitMyData on 2026-11-11, on once the production server has its live key)
Card payments always in US dollars: Stripe's prices in the payer's own currency (Adaptive Pricing, which adds a 2–4% conversion fee for the payer) are off on every payment page; "Get a DID-LLM" says the signature formats oncedone
Own a DID-LLM with a key instead of a wallet: scripts/did-owner-key.py makes an Ed25519 owner key on the owner's computer and signs the registration's message (https gateways only, never for another key or gateway), with a guide (docs/owner-key.md); step 3 of "Get a DID-LLM" says how to continue after signing with a tool, and explains a pasted message instead of a signaturedone
After a reload, "Get a DID-LLM" brings the registration in progress into view: it scrolls to it, puts the focus on Continue and makes it glow for a moment (no glow with reduced motion)done
"Join the Agentic Hub" hidden after issuance until the hub's "Create Entity" saves entries (SHOW_AGENTIC_HUB in get-did.js)done (back once the hub is ready)
Updates pause the monitor and the daily report (deploy/*/update.sh), so new settings are never read by the old code (no false "configuration cannot be loaded" alert); they start again at the end, even after a failed updatedone
PayPalwaiting for DebitMyData's PayPal account access
The company's test DID-LLMs left out of the daily report's figures (DMD_GW_REPORT_EXCLUDED_DIDS); a payment option's rate-limit refusals alerted only when they last (3 checks in a row)done
Naming: the payment option is "DebitMyData coin (native PoW chain)" and its asset DMD; the ticker is explained on the payment methods page, the price page, the MCP introduction and the API guide; the project, chain, nodes, explorer and alert subjects say DebitMyDatadone
Production server package (deploy/production, docs/production.md): DebitMyData node on the main chain holding only the treasury's watch-only key, every payment option off until switched on, nightly backup encrypted with an offline key to object storage (monitored), go-live checklistdone (needs the production server)
Credential signer (ID-15): in production the issuer key is held only by dmd-gateway-signer (own user, no network), which checks the database before signing; the API checks every signaturedone
DID-LLM directory: owners list their DID-LLM with a public profile (the Agentic Hub's fields, no pictures: type avatar/robot/sentient, specialty, description, optional owner's name, region, country, creation date), signed with the DID-LLM's own key or wallet like the proof of control, and change or remove it the same way; plain text only (no links, e-mail addresses or hidden characters); shown while the DID-LLM is active; open API with CORS (GET /v1/directory, search, type, pages), pages /directory, /directory/{id} and /directory/list, MCP (dmd_search_directory, dmd_list_in_directory), did-owner-key.py directory; operators hide a listing (dmd-gateway-admin directory hide), and the monitor reports every new or changed listing; "Get a DID-LLM" offers it after issuance (docs/directory.md)done
The top bar is wider than the page (1180 px) so every link fits on one line with "Directory" (staging's too), with the links a little closer on narrower screens and folded into the menu button below 900 px done
On staging, the directory page's owner-key command names the staging gateway (DMD_GATEWAY_API=...), and the tool says which gateway it asked when a message is not found theredone
The directory's pages have one address for people, the app's (id.debitmydata.io): on the API's address they lead there (308, same path and query), and entry_url and the alerts link there; the API stays on api.debitmydata.iodone
Signing with a key, on "Get a DID-LLM" (step 3) and the directory's listing page: the owner-key tool's command (with the registration or message ID, and DMD_GATEWAY_API off production) and a full-size Continue are the main way; pasting a signature made with other software is folded belowdone
The owner-key tool takes the folder of key files (~/did-keys) and signs with the one that owns the DID-LLM, or says that none does (listing the keys it found) and signs nothing; the pages' commands give the folderdone
"Get a DID-LLM", step 1, "My agent's public key": how to make a key with the owner-key tool (the new command and the guide; on staging, a test key of its own and the guide's staging part)done
The MCP server moves to /agenticsuperhighway, its name in DebitMyData's plans: the pages, llms.txt, discovery (mcp_url) and the API docs show the new address; /mcp, its first address, is still served with the same rate limits, so agents and listings that know it keep working. llms.txt points agents to Agentic Spaces for their own social pages and communitiesdone
A browser opening the MCP server's address (/agenticsuperhighway, or /mcp) gets a short page saying what it is: the address to give an MCP client, llms.txt, the REST API and "Get a DID-LLM" (before: an empty event stream, a blank page). MCP clients get exactly what they got before; the page is never cached (no-store, Vary: Accept)done
Each server's update.sh refuses to run on the other server (by its settings' DMD_GW_ENVIRONMENT) before changing anything, and staging's setup.sh refuses production's settings: staging's test settings and test key can never land on productiondone
One address for people, one for agents and developers (api/hosts.py): on the API's address (api.debitmydata.io), "Get a DID-LLM", the site's root and the policies lead to the app's (id.debitmydata.io), as the directory already did; on the app's address, the API docs (/docs/advanced, /redoc) lead to the API's. The menu's links therefore always land on the right address, and the installed app keeps people inside it. The API (/v1/...), llms.txt, the policies in Markdown and the MCP server answer at both, unmoveddone
MCP clients, crawlers and registries find the Agentic Superhighway without being told its address (api/server_card.py): its MCP Server Card (the MCP extension SEP-2127) at /agenticsuperhighway/server-card gives its name, version, what it does and how to connect (no tools: the server lists them itself), the AI Catalog at /.well-known/ai-catalog.json points to it, and DebitMyData's discovery runbook gets its two files in its own format (application/json): /.well-known/mcp/server-card.json, with the tools the server lists, and /.well-known/mcp, a short manifest; both point to the standard card. server.json lists it in the official MCP Registry as io.debitmydata/agenticsuperhighway (docs/production.md); a test keeps it the same as the carddone (the listing needs the DNS record)
No drop-down lists on the pages, so AI agents see every choice at once: "What is it for?" on Get a DID-LLM (in three groups, on an even grid) and the listing form's type are visible buttons, and the directory's types are links that keep the search wordsdone
Native DMD wallet proofs (DEC-07), controller rotation and revocationnext

Every payment rail is off by default. The native DMD rail can be switched on for a private regtest chain (see docs/regtest-demo.md); on mainnet it is priced by the higher of a minimum rate (0.001 USD per DMD) and the cost of mining DMD, and still needs the gateway's own DebitMyData node with the watch-only receiving wallet. The x402 USDC rail runs on Base Sepolia on staging; on Base mainnet it pays DebitMyData's receiving address and settles through Coinbase's CDP facilitator, which needs DebitMyData's CDP API key (DEC-08). Card payments run in Stripe's test mode on staging once its restricted test key is set; in production they are approved and stay off until the production server has its restricted live key (docs/card-payments.md). A staging server with the full flow on a private regtest chain runs at https://staging-api.debitmydata.io: anyone can try the registration from its guided test page, or step by step from the advanced API docs (see docs/staging.md). See docs/roadmap.md for the task list and decisions.

Quick start

Requirements: Python 3.12+, Docker (for PostgreSQL) or a local PostgreSQL 16.

Windows (PowerShell)
git clone https://github.com/DebitMyData-PoW/agent-gateway.git
cd agent-gateway
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
Copy-Item .env.example .env

docker compose up -d db
alembic upgrade head
uvicorn --factory dmd_gateway.main:create_app --reload
Linux / macOS
git clone https://github.com/DebitMyData-PoW/agent-gateway.git
cd agent-gateway
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env

docker compose up -d db
alembic upgrade head
uvicorn --factory dmd_gateway.main:create_app --reload

Then open http://localhost:8000/docs, or:

curl http://localhost:8000/readyz
curl http://localhost:8000/v1/discovery
curl "http://localhost:8000/v1/payment-options?service=did_registration"

Request a DID-LLM registration quote (the directive's example request, with an example controller key; python scripts/demo_agent.py new-key agent-key.pem creates a real one):

curl -X POST http://localhost:8000/v1/dids/registration-quotes \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f14e45f-ceea-467a-9a3b-3c5a1d2e7b90" \
  -d '{"display_name": "ResearchClaw-01", "participant_type": "autonomous_agent",
       "controller_public_key": "ed25519:z6MktwupdmLXVVqTzCw4i46r4uGyosGXRnR3XjN4Zq7oMMsw",
       "preferred_payment_option": "x402_usdc_base"}'

While every payment rail is off, this answers 409 with "code": "payment_option_unavailable".

Registration flow

StepEndpoint
Discover the offer and enabled payment optionsGET /v1/discovery, GET /v1/payment-options
Get a quote (fixed 25.00 USD, exact amount in the chosen asset)POST /v1/dids/registration-quotes
Pay (DMD), then follow the paymentGET /v1/payments/{payment_intent_id}
Get a one-time message to sign with the controller key or walletPOST /v1/dids/registrations/{registration_intent_id}/controller-challenges
Send the signaturePOST /v1/dids/registrations/{registration_intent_id}/controller-proofs
See what is still missingGET /v1/dids/registrations/{registration_intent_id}
Receive the DID-LLM, signed credential and entitlements (x402: pay here, see below)POST /v1/dids/registrations
Optionally report the payment transaction (a hint only)POST /v1/payments/{payment_intent_id}/references
Look them upGET /v1/dids/{identity_id}, GET /v1/credentials/{credential_id}, GET /v1/entitlements/{identity_id} (the identity ID or the DID-LLM itself)
Resolve the DID-LLM and the issuer keyGET /agents/{id}/did.json, GET /.well-known/did.json
Read the terms, privacy, payment, refund, DID-LLM and security policies/policies, GET /v1/policies
Optional: list the DID-LLM in the directory (signed by its owner), or read the directoryPOST /v1/directory/{did}/challenges, POST /v1/directory/{did}/proofs, GET /v1/directory

The same steps are available as MCP tools at /agenticsuperhighway (Streamable HTTP; /mcp, its first address, still works): dmd_discover, dmd_get_did_registration_offer, dmd_list_supported_payment_options, dmd_create_did_payment_quote, dmd_submit_payment_reference, dmd_get_payment_status, dmd_prove_wallet_control, dmd_register_did, dmd_get_registration_status, dmd_catalog, dmd_get_purchase_quote, dmd_purchase, dmd_marketplace_provider_requirements, dmd_search_directory and dmd_list_in_directory. Each tool calls the REST API above in-process, so both give the same results and error codes. Its Server Card, /agenticsuperhighway/server-card (listed in /.well-known/ai-catalog.json), tells MCP clients and registries what it is and how to connect.

Inference donations (agents). POST /v1/donations/inference with {"amount_usd": "5.00"} (from 0.50 to 1,000.00 USD; optionally donor_name and donor_did) answers 402 with the x402 terms for exactly that amount, paid to DebitMyData's inference wallet (DMD_USDC_BASE_INFERENCE_ADDRESS, not the DID-LLM payment address). Send the same body again with the signed payment in PAYMENT-SIGNATURE: no quote is needed, the payment is checked on chain like a DID-LLM payment, and the answer (201) carries a receipt signed by DebitMyData (a DebitMyDataDonationReceipt credential), or 202 with a status_url (GET /v1/donations/{purchase_id}) while confirmations come in. Sending the same payment again returns the same donation. Through MCP: dmd_catalog lists inference_donation, and dmd_purchase takes the amount in details and the payment in x402_payment or _meta["x402/payment"]. Donations appear under donations in /v1/discovery.

Paying with x402 (USDC on Base). Quote with "preferred_payment_option": "x402_usdc_base", prove the controller key, then call POST /v1/dids/registrations. It answers 402 with a PAYMENT-REQUIRED header (x402 version 2, scheme exact: the quoted amount in USDC base units, the USDC contract, the network and DebitMyData's receiving address, plus a Bazaar discovery description). Call it again with the signed payment in the PAYMENT-SIGNATURE header: the gateway checks it against the quote, the facilitator verifies and settles it, the gateway checks the settlement on chain itself, and the DID-LLM comes back in the same answer with a PAYMENT-RESPONSE header (or 202 if the confirmations take longer; then call again without paying). Payment is asked for only once everything else is ready, so an agent is never charged for a DID-LLM that cannot be issued. Any standard x402 client can pay it; through MCP, dmd_register_did returns the payment requirements and takes the payment in x402_payment or _meta["x402/payment"].

DID-LLM issuance needs a credential signing key (DMD_GW_ISSUER_KEY_PATH, created with dmd-gateway-issuer-key secrets/issuer-key.pem). Without it, everything else works and the issuance endpoint answers 503. See docs/architecture.md for the rules behind each step.

Run commands from the repository root (the route registry path is relative to it).

Tests

pytest                                   # unit and API tests
ruff check . && ruff format --check .    # lint

Database tests run only when TEST_DATABASE_URL points at a disposable database (they drop and recreate every table). The compose database creates one for you:

$env:TEST_DATABASE_URL = "postgresql+psycopg://gateway:gateway-dev-only@localhost:5432/agent_gateway_test"
pytest

CI runs lint plus the full suite, database tests included, on every push and pull request.

Configuration

Gateway settings use the DMD_GW_ prefix and can come from the environment or .env (see .env.example). Outside development the gateway refuses to start with the development database credentials or a non-HTTPS public URL.

Payment rails

config/payment_routes.yaml is the single source of truth for how an agent may pay. A rail is enabled only when all of these hold:

  1. its enable flag (named by enable_env, e.g. DMD_RAIL_DMD_POW_NATIVE_ENABLED) is true (1/true/yes/on);
  2. its kill switch (named by kill_env) is unset or 0/false/no/off;
  3. it is approved in the registry;
  4. canonical asset identity and confirmation/finality policy are set;
  5. for non-USD assets, the price policy is complete (approved source, maximum price age, permitted price deviation and fallback) and its price sources are implemented;
  6. its receiving destination is configured;
  7. its payment adapter is implemented;
  8. x402 rails only: the exact scheme with EIP-3009 transfers, the token's EIP-712 domain, a confirmation count, and their facilitator and chain RPC addresses (DMD_X402_FACILITATOR_URL, DMD_BASE_RPC_URL). Coinbase's CDP facilitator (https://api.cdp.coinbase.com/platform/v2/x402) also needs a usable CDP API key (DMD_X402_CDP_API_KEY_ID, DMD_X402_CDP_API_KEY_SECRET).

Rails on test networks (DebitMyData regtest/testnets, Base Sepolia) are refused in production.

If a rail is switched on while 3–8 are not met, the gateway refuses to start instead of running a half-configured rail. Kill switches fail safe: any unrecognised value counts as "killed". Kill switches are read at startup, so flipping one takes effect on restart. /v1/payment-options lists only enabled rails, so the API never advertises a payment method that cannot actually be verified.

Payment worker

Payments are tracked by a separate process that watches every open payment on the enabled rails and moves it through the normalized statuses:

dmd-gateway-worker          # runs until stopped
dmd-gateway-worker --once   # one pass

It never changes a payment while the node is unreachable, and several workers can run at once safely. To try the whole flow on a private chain, from quote to DID-LLM, follow docs/regtest-demo.md.

Project layout

config/payment_routes.yaml   payment rails, services, commercial price (no secrets)
config/payment_routes.regtest.yaml   the same, on test networks (DebitMyData regtest, Base Sepolia)
deploy/staging/              staging server setup (nginx, systemd services, Cloudflare-only firewall)
deploy/production/           production server setup, signer and backup units, nightly backup
server.json                  the MCP server's listing in the official MCP Registry
migrations/                  Alembic migrations (hand-reviewed)
src/dmd_gateway/
  main.py                    application factory
  mcp_server.py              MCP tools at /agenticsuperhighway, calling the REST API in-process
  worker.py                  payment worker (dmd-gateway-worker), also refreshes the DMD price
  monitoring/                health checks, email/Discord alerts, daily reconciliation report
                             (dmd-gateway-monitor)
  identity/                  controller keys, did:web documents, issuer key, signed credentials
  signer/                    the production credential signer (dmd-gateway-signer) and its client
  runtime.py                 registry, adapters and price sources shared by API and worker
  settings.py                environment configuration
  observability.py           JSON logging, correlation IDs
  audit.py                   append-only audit helper
  api/                       HTTP routes
  adapters/                  payment adapters (native DMD, x402 USDC), restricted RPC clients,
                             x402 facilitator client
  pricing/                   price-source rules and the DMD mining-cost price
  services/                  quotes, settlement, payment references, controller proofs,
                             registrations, x402 payments, donations, staging test tools
  db/                        SQLAlchemy models and session handling
  domain/                    money, ids, payment states, settlement rules, issuance rule, registry
scripts/demo_agent.py        agent side for demos: key, signature, credential check, MCP client
scripts/did-owner-key.py     owner key for a DID-LLM without a wallet (docs/owner-key.md)
scripts/load_test.py         load test: requests per second and response times
tests/
docs/                        architecture, roadmap, operator checklists

Before connecting the gateway to any DebitMyData node, verify that node's RPC isolation with docs/sec-04-rpc-isolation.md.

Ground rules

These apply to every change in this repository:

  • Do not modify DebitMyData consensus code to support gateway features.
  • Never expose DebitMyData Core RPC publicly or forward arbitrary RPC methods.
  • Never give callers private keys, seed phrases, wallet unlock or unrestricted signing.
  • No treasury or spending keys on gateway hosts; payment tracking is watch-only.
  • Never accept an asset by ticker symbol; match chain ID + canonical contract/identifier.
  • Never use binary floating point for money or token amounts.
  • Never issue an identity unless payment is settled, controller proof is verified, policy checks passed and the registration intent is valid and unused.
  • Never put secrets in source, tickets, logs or chat. .env files are git-ignored.
  • Public documentation describes only rails that are actually enabled and verified.

Reporting security issues

Please report vulnerabilities privately, never in public issues. See SECURITY.md.

Database notes

audit_events, payment_events, credited_outputs, controller_proofs and payment_references are append-only: database triggers reject UPDATE, DELETE and TRUNCATE. credited_outputs has a primary key on (network, transaction, output index), so a payment output can be credited to only one intent. In staging and production, run migrations as a separate owner role and let the application connect as a role that has only the privileges it needs.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.