Yesterday we defined what "agent-native" means. Today we go under the hood of the bridge that makes it real: the NanoParse MCP server.
What Makes MCP Different
MCP — the Model Context Protocol — is not just another API. It's a standard for how AI agents discover and use tools. Think of it as USB-C for agent capabilities: one protocol, one connector, and the agent gains a new sense.
Before MCP, every tool integration was bespoke. You'd write a custom function for web search, another for file access, another for a database query. Each with its own auth, its own error handling, its own shape. MCP standardizes this: every tool advertises itself the same way, every agent discovers tools the same way, and every invocation follows the same JSON-RPC 2.0 contract.
NanoParse plugs into this standard with a single config block:
{
"mcpServers": {
"nanoparse": {
"url": "https://nanoparse.app/mcp"
}
}
}
That's it. Your agent can now read any URL on the web. No API key. No signup form.
The Protocol: What Actually Happens
When an MCP client (like Claude Code or Cursor) connects to the NanoParse MCP server, three things happen in sequence:
1. Initialize
The client sends an initialize request. The server responds with its capabilities:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "nanoparse-mcp",
"version": "1.0.0"
},
"capabilities": {
"tools": {}
}
}
}
2. Discover Tools
The client calls tools/list. The server advertises exactly one tool:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "nanoparse_fetch",
"description": "Fetch a URL and return clean markdown...",
"inputSchema": {
"type": "object",
"properties": {
"url": { "type": "string" },
"debug": { "type": "boolean" }
},
"required": ["url"]
}
}
]
}
}
One tool. One purpose. The agent now knows: "I can call nanoparse_fetch with a URL and get back clean markdown."
3. Invoke
The agent calls tools/call:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "nanoparse_fetch",
"arguments": {
"url": "https://react.dev/learn"
}
}
}
The server validates the URL, sends it to the NanoParse Worker, and the result comes back as clean markdown:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [{
"type": "text",
"text": "# React\n\nThe library for web and native..."
}]
}
}
The Architecture Under the Hood
The MCP server itself is thin — it's a protocol adapter. The real work happens in the Cloudflare Worker pipeline:
Agent → MCP Client → POST https://nanoparse.app/mcp
↓
Queue Consumer
↓
Puppeteer (Browser Rendering)
↓
Content Extraction
↓
Markdown → R2 storage
↓
Poll /status → Return to agent
Why This Architecture?
Browser rendering at the edge. Cloudflare Browser Rendering gives us a real Chromium instance per request. JavaScript executes. React hydrates. SPAs render. What your agent gets is what a human would see — not an empty <div id="root">.
Queue-based isolation. Browser rendering is expensive (500ms–5s per page). The queue consumer pattern decouples request acceptance from content processing. This keeps the MCP endpoint responsive and avoids browser-pool exhaustion.
Content extraction pipeline. Raw HTML is not useful to an agent. Our extraction pipeline:
- Strips noise: nav, footer, sidebar, ads, cookie banners, social widgets
- Identifies the main content:
<article>,<main>, or body heuristics - Converts to GFM-compliant markdown: headings, lists, links, and — critically — tables
- Post-processes: drops lines with <40% printable characters, collapses consecutive blank lines
One-hour cache with auto-expiry. Results are stored in R2 with a 1-hour TTL. The /status endpoint deletes on retrieval. If a result is never retrieved, it auto-expires. No permanent storage of fetched content.
x402: How the Agent Pays
This is where the "agent-native" property gets real. The MCP server handles payments without a human in the loop:
- Free tier check: First 10 MCP calls are free. After that, the Worker returns HTTP 402 Payment Required.
- Agent pays: The MCP client detects the 402, constructs an x402 transaction (EIP-191 signed message for USDC on Base), and resubmits with a
Payment-Signatureheader. - Settlement: The Worker verifies the signature via the x402 facilitator, credits the merchant wallet, and enqueues the job.
- Idempotency: Payment signatures include a nonce-based KV lock to prevent double-charge race conditions.
The agent never touches a credit card form. It never sees a CAPTCHA. It signs a cryptographic proof of payment, and the web opens up.
// What the MCP client does under the hood:
const payment = await signPayment({
to: "0x57a1d06873db575baeae1f6af30862a75c7bd570",
amount: "0.0174", // USD, settled in USDC
network: "base",
});
const response = await fetch("https://nanoparse.app/mcp", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Payment-Signature": payment.signature,
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: {
name: "nanoparse_fetch",
arguments: { url: "https://example.com" },
},
}),
});
Integration: Claude Code, Cursor, and Beyond
Claude Code
Add to your Claude Code MCP config (~/.claude/claude_desktop_config.json or project .mcp.json):
{
"mcpServers": {
"nanoparse": {
"url": "https://nanoparse.app/mcp"
}
}
}
Restart Claude Code. Your agent now has a nanoparse_fetch tool.
Cursor
Cursor's MCP support works the same way. Add the server config, and nanoparse_fetch appears in your agent's tool palette.
Any MCP-compatible client
The MCP protocol is open. If your agent framework speaks MCP, it speaks NanoParse. The server runs remotely on Cloudflare's edge at nanoparse.app/mcp — nothing to install, nothing to run. Source: github.com/NanoParse/nanoparse-mcp.
Building Your Own vs. Using NanoParse MCP
Let's be honest about what you'd need to replicate this:
| Component | DIY Cost | NanoParse MCP |
|---|---|---|
| Browser rendering | Headless Chrome: $20-50/month + ops | Included |
| Content extraction | Readability + Turndown: breaks on SPAs | Production-tested pipeline |
| GFM table preservation | Weeks of debugging edge cases | Solved |
| Anti-bot handling | IP rotation, UA management, evasion | Cloudflare edge network |
| Payment integration | Stripe, billing UI, invoices | x402 — agent-native, zero setup |
| Queue management | Redis, workers, retry/backoff | Cloudflare Queues |
| SSRF protection | DNS rebinding, encoded-IP detection | 14 payload classes blocked |
You could build all of this. It would take weeks. It would cost more to run than NanoParse costs to use. And when it breaks at 2 AM, you're the ops team.
Or: point your MCP client at nanoparse.app/mcp and your agent can read the web.
What's Next for the MCP Server
- Batch parsing: One MCP call, N URLs — fetch 20 docs at once.
- Structured extraction: Prompt-guided extraction. "Find every pricing tier on this page and return as JSON."
- Recursive crawling: Follow links N levels deep, with domain allowlisting.
- Streaming results: Return content as it's extracted, not after the full page renders.
Every feature will honor the core principle: agents should be able to discover, pay for, and use web infrastructure without a human ever touching a keyboard.
Try It
{
"mcpServers": {
"nanoparse": {
"url": "https://nanoparse.app/mcp"
}
}
}
One config block. Your agent's universe just got a lot bigger.
Tomorrow: "x402: How Software Pays for Software" — the payment protocol that makes agent-native commerce possible.