Local MCP server for policy-controlled x402 API payments using USDC on Base.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent โ or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag โ we're steadily working through the catalog.
๐ก Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Payfetch.
payfetch lets an AI agent fetch a URL and, when the server answers HTTP 402 (the x402 payment protocol), pay for it automatically, but only within a spending policy you control. It is non-custodial: you bring your own wallet, the key stays on your machine, and no MCP tool can raise the limits. It ships as a local stdio MCP server with a small library and CLI alongside it.
The reference x402 clients pay whatever a 402 asks for. payfetch is the opposite: the policy and safety surface is the point. Per-call, per-day, and per-host spend caps; host allow and deny lists; a human-approval threshold; optional pre-payment trust and safety checks; and an append-only local receipt for every attempt, whether it paid, was denied, was a dry run, or failed.
p3f.policy.v1, client schema p3f-1.0.0.exact scheme. Solana-settled x402, the upto scheme,
and MPP are parsed and then refused with a reason recorded in your receipts.The package ships compiled JavaScript, so there is no build step and no tsx for
consumers. Run it on demand with npx:
The package exposes two binaries: payfetch (the operator CLI) and payfetch-mcp
(the stdio MCP server). Because there are two, the server is launched with
npx -p @forum-labs/payfetch payfetch-mcp; the -p flag selects the named binary.
payfetch refuses to start if zero or more than one signer source is set. It never guesses which wallet to spend from.
Raw private key, the simplest option. Use a dedicated low-balance wallet:
Key file, which must be mode 600 (payfetch refuses to start otherwise):
Coinbase CDP server wallet, where the keys are managed by CDP under your account instead of being pasted into an environment variable:
Claude Desktop, in claude_desktop_config.json:
Claude Code:
The examples set PAYFETCH_TEST_MODE=1 so your first runs settle on Base Sepolia
and never touch mainnet. Drop it when you are ready to spend real USDC.
Quote before you pay. payment_quote returns the terms, the selected quote, the
trust-check result, your remaining budgets, and the policy decision (would_pay or
would_deny). It signs nothing and reserves nothing:
Dry run the whole pipeline. paid_fetch with "dryRun": true runs the exact code
path a real payment takes, up to but not including the signature.
Pay for real with paid_fetch:
maxAmountUsd tightens the per-call cap for this one call. It can only lower the
limit, never raise it. If the price is above your approval threshold, approval is
required first (see Approvals). The result carries the response body, the payment
outcome and transaction reference, any warnings, and a receiptId.
Policy lives in {dataDir}/config.json (the data dir defaults to ~/.payfetch).
On first run payfetch writes the defaults there so you can read and edit exactly
what you are running. A missing file falls back to the defaults. An invalid file
fails closed: every paying tool returns policy_config_invalid until you fix it, so
a typo never silently restores a cap you lowered. The file is re-read when its mtime
changes.
Only you can change the policy. No MCP tool mutates it and no tool clears an
auto-deny. Agent-supplied parameters such as maxAmountUsd can only tighten, never
loosen. Every denied paid_fetch result repeats this back to the agent so a
prompt-injected model cannot mistake the boundary for something negotiable.
caps.perCallUsd (default 1.00): maximum for a single payment.caps.dailyUsd (default 2.00): maximum per UTC day.caps.perHostDailyUsd (default 1.00): maximum per host per UTC day.caps.totalUsd (default null): optional lifetime cap.Caps are hard and reserve before paying. A signed authorization is held against the budget until it provably expires, so budgets can over-count but never under-count. At most one payment attempt happens per request, so a retry loop cannot drain the wallet.
There is deliberately no default lifetime cap. The dedicated wallet's balance
already bounds lifetime spend on-chain (see Security), so a software lifetime ceiling
would be one more field to forget. Set totalUsd only if you want a software
ceiling on top of a larger-balance wallet.
mode is open by default. Set it to allowlist to pay only hosts listed in
allow. Patterns in deny are always refused and win over allow. A pattern like
*.example.com matches subdomains, not the apex.
A payment whose price is strictly above approval.thresholdUsd (default 0.10)
triggers approval. An approval authorizes one payment only. There is no "always
allow", and it never widens future authority.
elicit (default): the client prompts a human with the host, resource, amount,
network and asset, guard results, and today's remaining budgets. They approve once
or deny. The prompt times out after 120 seconds and is then treated as a denial.
Some MCP clients cannot service an elicitation prompt: as of Claude Code v2.1.198
and current Claude Desktop, neither does (Claude Code does not advertise the
elicitation capability; Claude Desktop advertises it but cancels the prompt
immediately). When a client adds elicitation support, the prompt works with no
payfetch change. payfetch tells apart a real human "deny"
from a client that simply cannot ask, and it never treats "cannot ask" as a silent
denial. When a payment is blocked only because the client cannot elicit, the tool
result says so and names the ways to allow it.queue: the payment is not executed. The result returns an approvalId. A human
with approval authority resolves it with the approve_pending tool. An approved
entry is a grant to re-run: the follow-up paid_fetch runs the full pipeline again
and matches on host and exact amount. It expires after one hour, and drifted terms
require a fresh approval.deny: anything above the threshold is refused, for unattended fleets.For clients that cannot prompt a human, two config-only settings let above-threshold
payments through without a dialog. Both are explicit operator authorization, not the
agent's, and neither is reachable from a tool. approval.preApprovedUpToUsd (default
null) auto-approves above-threshold payments up to a ceiling.
approval.preApprovedHosts (default empty) auto-approves specific hosts. Both still
pass through every cap and every guard.
Approval never bypasses caps. An approved payment that fails budget reservation is still denied.
approve_pending with {"action":"list"} is always allowed and shows the queue.
Approving or denying an entry requires PAYFETCH_APPROVER=1 in the server's
environment; without it the tool returns approver_not_enabled. An agent must not
approve its own payments, so the server refuses to start if PAYFETCH_APPROVER=1 is
combined with a queue-capable approval mode.
Every outcome, including free fetches, dry runs, denials, and unknown-settlement cases, appends one immutable JSON line to the ledger:
A receipt records the URL, method, and host; the outcome and deny code; the pipeline
steps traversed; the selected quote and a tally of rejected quotes; guard results;
approval info; the payment (payer address, nonce, validBefore, settled amount,
transaction reference, and whether it confirmed); the budgets at decision time; and
an HTTP summary. Key material, signatures, full payment payloads, response bodies,
and request header values are never stored. Response bodies are recorded as a
SHA-256 hash plus a byte count. URL query strings are stored, because this is your
own audit trail on your own disk; guard calls, by contrast, strip the query (see
Security). Nothing is rewritten. Corrections append p3f.adjust.v1 records.
Factual signals from GitHub, npm, and our automated checks โ not a rating.
No reviews yet โ be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/forum-labs-payfetch)<a href="https://allmcps.com/mcp/forum-labs-payfetch"><img src="https://allmcps.com/api/badge/forum-labs-payfetch?style=directory" alt="Payfetch on AllMCPs" /></a>