Paid MCP tool calls
@reinkey/mcp is an MCP server. It gives any MCP client — Claude among them — tools that buy things: one paid HTTP request, one paid stream, one trade. The assistant spends real USDC on Stellar testnet, inside a budget that lives in a contract rather than in a prompt.
MCP has no payments. x402 has payments, but one chain transaction per call. This server joins them with a session: the first call to a seller opens an x402 channel with one Stellar transaction; every call after that is a signed voucher verified in well under a millisecond; the seller settles them all with one claim.
assistant ──MCP──▶ reinkey-mcp ──HTTP + voucher──▶ any x402 seller
│
└─ Reinkey account (Soroban): per-tx cap, daily cap,
allowed payees, allowed pairs — enforced by StellarTools
| Tool | Cost | What it does |
|---|---|---|
reinkey_discover | free | Lists paid resources from the facilitator's Bazaar catalog. Optional text filter. |
reinkey_call | the resource's price | One paid HTTP request; returns the body, the amount paid and a verifiable receipt link. |
reinkey_stream | per second / per token | Consumes a paid stream for a bounded time; pays only for what was delivered. |
reinkey_quote | free | USDC/XLM quote with the account's policy pre-verdict. |
reinkey_swap | one transaction | Trade with mandatory slippage protection. |
reinkey_budget | free | On-chain limits, what is left today, open sessions, payments vs. chain transactions. |
A policy rejection comes back as a result, not an error: { ok: false, code: "PER_TX_CAP_EXCEEDED", … }. The assistant can read it and explain it; it cannot argue its way around it, because the rejection came from __check_auth on Stellar. See Reason codes.
Setup
- Create an agent account in the console → Reins → Create your own agent account. Your wallet is the owner; the agent secret is shown once. See the Console guide.
- Send the account some testnet USDC and fund a relayer with friendbot. See Testnet setup.
- Point your MCP client at the server:
{
"mcpServers": {
"reinkey": {
"command": "npx",
"args": ["tsx", "/path/to/Reinkey/packages/mcp/src/index.ts"],
"env": {
"REINKEY_API": "https://reinkey.onrender.com",
"REINKEY_ACCOUNT": "C…",
"AGENT_SECRET": "S…",
"RELAYER_SECRET": "S…"
}
}
}
}| Variable | |
|---|---|
REINKEY_API | Facilitator base URL. The hosted testnet one is https://reinkey.onrender.com. |
REINKEY_ACCOUNT | The Reinkey account (C…) the assistant spends from. |
AGENT_SECRET | The agent key from account creation. It can only do what the policy allows. |
RELAYER_SECRET | A funded G… account that pays the transaction fees. The agent key holds no XLM. |
REINKEY_SESSION_DEPOSIT | Optional. Default deposit per session in base units; default 100000 (0.01 USDC). |
Pre-release.
@reinkey/mcpis not on npm yet. Run it from the monorepo: clone github.com/devbugra/Reinkey,pnpm installat the root, then pointargsatpackages/mcp/src/index.tsas above.
What the agent key can do
Only what the account's policy allows. The secret in that config can pay the allowed payees within the per-transaction and daily caps, and trade the allowed pairs with slippage protection. It cannot move funds anywhere else, raise its own limits, or unfreeze the account — those need the owner wallet. A prompt injection that talks the assistant into paying an attacker fails on-chain with PAYEE_NOT_ALLOWED.
Read the trust model for what a stolen agent key can and cannot do.
Verified
pnpm --filter @reinkey/mcp exec tsx check.ts starts the server from a real MCP client over stdio and, on testnet: opens a session in one transaction, makes three paid calls and a five-slice per-second stream with vouchers only, and gets PER_TX_CAP_EXCEEDED for a trade above the cap. On 20 Sep 2026 that run produced sessions #17 (4cac65d6…) and #18 (57510316…): 8 payments, 2 chain transactions.