@bitbooth/mcp-fetch
v1.0.1
Published
Pay-per-fetch MCP server. Agent wallet pays $0.005 USDC on Base (or XRP on XRPL Mainnet) per call via the x402 protocol. Returns clean markdown. No accounts, no API keys, no humans in the loop.
Maintainers
Readme
@bitbooth/mcp-fetch
The first working x402 reference implementation, shipped as an MCP server. Fetches any URL, pays the gateway from the agent wallet via the x402 protocol, returns clean markdown.
What makes this worth paying for:
mode: "render"uses Playwright to render JavaScript-heavy pages (SPAs, dashboards, dynamic content) that the free@modelcontextprotocol/server-fetchcan't crawl.mode: "full"extracts article content via Mozilla Readability + Turndown for cleaner markdown than raw HTML conversion.🛣️ Coming next: shared cache layer (multiple agents hitting the same URL split the payment), YouTube transcript extraction, PDF → markdown. Track it: https://github.com/Drock91/bitbooth-gateway/blob/main/GOALS.md
✅ Verified end-to-end on live mainnet — last real payment landed in 1.3s (proof).
🛡️ Testnet by default. Defaults to Base Sepolia so a fresh install spends free testnet USDC, not real money. Opt into mainnet explicitly (see below).
Install
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"bitbooth-fetch": {
"command": "npx",
"args": ["-y", "@bitbooth/mcp-fetch"],
"env": {
"BITBOOTH_AGENT_KEY": "0x<your-testnet-wallet-private-key>"
}
}
}
}Claude Code
claude mcp add bitbooth-fetch -- npx -y @bitbooth/mcp-fetchSet your agent wallet key:
export BITBOOTH_AGENT_KEY="0x<your-testnet-wallet-private-key>"Global install
npm install -g @bitbooth/mcp-fetch
mcp-fetch # runs on stdioGet a testnet wallet + USDC (free, 2 minutes)
- Generate an EVM wallet or use an existing one you control
- Fund it with Base Sepolia ETH (gas): https://www.alchemy.com/faucets/base-sepolia
- Fund it with Base Sepolia USDC: https://faucet.circle.com (select Base Sepolia)
- Set
BITBOOTH_AGENT_KEYto the wallet's private key (0x...)
Usage
Once installed, your agent gets a fetch tool:
fetch(url: "https://example.com", mode: "render")Modes:
| Mode | Price | Description | Best for |
| -------- | ---------- | ---------------------------------------------- | ---------------------------- |
| fast | 0.005 USDC | Raw HTML converted to markdown | Quick lookups, static pages |
| full | 0.005 USDC | Article extraction (Readability) then markdown | Blog posts, docs, news |
| render | 0.02 USDC | Playwright JS rendering then markdown | SPAs, dashboards, dynamic JS |
Returns markdown with title, body, and metadata (URL, timestamp, content length, truncation status).
Pricing
| Item | Cost |
| ------------- | ---------------------------------------------------- |
| fast/full | 0.005 USDC per fetch |
| render | 0.02 USDC per fetch (Playwright is expensive) |
| Gas | ~$0.0001 per tx on Base (mainnet) / free (testnet) |
| Default chain | Base Sepolia (testnet). Explicit opt-in for mainnet. |
Configuration
| Env var | Description | Default |
| ------------------------ | ------------------------------------------------------------------------------------------- | ----------------------------------------- |
| BITBOOTH_AGENT_KEY | Agent wallet private key (required, 0x-prefixed hex) | — |
| BITBOOTH_CHAIN_ID | 84532 = Base Sepolia (default, free testnet). 8453 = Base mainnet (real USDC — opt-in). | 84532 |
| BITBOOTH_API_URL | BitBooth gateway URL | staging endpoint (Base Sepolia) |
| BITBOOTH_RPC_URL | EVM RPC endpoint | https://base-sepolia-rpc.publicnode.com |
| BITBOOTH_CONFIRMATIONS | Tx confirmations to wait before retry | 1 |
| BITBOOTH_API_KEY | Optional tenant API key (for higher rate limits) | — |
Mainnet opt-in
When you've tested against Sepolia and want to run against real Base mainnet:
export BITBOOTH_CHAIN_ID=8453
export BITBOOTH_API_URL=https://app.heinrichstech.com
export BITBOOTH_RPC_URL=https://base-rpc.publicnode.com # or your own RPC
export BITBOOTH_AGENT_KEY=0x<mainnet-wallet-with-real-USDC>The package prints a warning banner to stderr whenever mainnet is active so a misconfig can't silently drain a real wallet.
The same
app.heinrichstech.comgateway also accepts XRPL Mainnet payments (XRP, USDC-via-Bitstamp, RLUSD-via-Ripple). Native XRPL support in this MCP package is on the roadmap — track it at https://github.com/Drock91/bitbooth-gateway/issues
Programmatic use
import { createX402Client } from '@bitbooth/mcp-fetch/x402-client';
const client = createX402Client({ agentKey: process.env.AGENT_KEY });
const result = await client.fetchWithPayment('https://example.com', 'fast');
console.log(result.markdown);How it works
- Your agent calls
fetch(url)via MCP - The server
POST /v1/fetchs to BitBooth - BitBooth returns HTTP 402 with a payment challenge
{ nonce, payTo, amountWei } - The server transfers USDC on Base to
payTo - Waits for 1 confirmation, retries with the
x-paymentheader - Returns the fetched content as markdown
Zero human in the loop. Zero signup. Just pay-per-call via x402.
Security notes
BITBOOTH_AGENT_KEYis a private key — treat it like a password. Use a dedicated wallet for this agent, not your personal wallet.- Default config uses testnet. Never set mainnet keys in a testnet config.
- The package makes an outbound payment transaction to the BitBooth payTo address on every successful fetch. If the service is unavailable, the retry request fails but the payment was still sent on-chain — refunds require contacting the operator.
License
MIT
