Documentation

What it is

An MCP server that fetches a web page with a real, stealth browser (a fingerprint-patched Firefox that gets through bot walls — even Google — with a real-Chrome engine as an option) and returns:

Same code as mcp-fetch-ux, fronted by a Rust edge that handles auth, queueing, and per-second billing. No LLM in the loop. No credit multipliers. JavaScript is always rendered. Stealth is always on.


Quickstart

  1. Mint a trial key. Visit the signup box on the home page and enter your email. You get $0.10 of trial credit (about 100 typical fetches) and a key like pithy_live_…. No credit card. The key is stored in your browser’s localStorage.
  2. Try it without leaving the page. The Try-it box on the home page uses your key to fetch any URL you paste and shows the receipt headers (X-Compute-Seconds, X-Charge-USD, X-Balance-USD) inline. Cheapest way to see exactly what your agent will see.
  3. Wire it into your MCP client (Claude Code, Cursor, Windsurf, …) and restart:
{
  "mcpServers": {
    "pithy": {
      "type": "http",
      "url": "https://pithy.bot/mcp/",
      "headers": { "Authorization": "Bearer pithy_live_..." }
    }
  }
}

Then ask your model to fetch a page. It will call the fetch tool over MCP and you’ll get the receipt in response headers.

When you’re ready for more than the trial, top up in $5 packs via Stripe Checkout (coming online shortly). Credits don’t expire; refundable while unused.

Two paths, same fetch engine

Want full control and zero dollars? Self-host mcp-fetch-ux (MIT). Clone, make server, you’ve got the same Patchright + clipboard extraction running on localhost:5006 in five minutes. You own the box; you ship the page.

Want to ship the agent instead of the infra? Use pithy.bot. Paste the block above, mint a key, you’re fetching in seconds. Same fetch code, we run it; you ship the agent.

Both make you the one who built it. Pick the one that gets you to building faster.

Endpoint: https://pithy.bot/ (dev.pithy.bot points at the same backend for staging). Signup, magic-link login, metering, queue, SSRF guard, MCP proxy — all live. Stripe top-ups come next.

Authentication

One thing: an Authorization header carrying a bearer token.

Authorization: Bearer pithy_live_<32 hex chars>

Keys are scoped to a single bowl (your balance). A request with no key returns 401. A request with an unknown key returns 401. A request whose key has less than $0.003 in its bowl returns 402 — we won’t start a fetch we might not be paid for, since the per-fetch cap is $0.003.


The fetch tool

One tool: fetch. Same shape over MCP and over the direct HTTP API.

Parameters

nametypedefaultdescription
urlstringrequiredhttp or https URL to fetch.
actionsarraynoneActions to perform after the page loads. See Actions.
max_lengthint50000Maximum characters to return.
start_indexint0Resume from this character index (pagination).
rawboolfalseReturn raw HTML instead of clipboard text.

Direct HTTP call

curl -X POST https://pithy.bot/fetch \
  -H "Authorization: Bearer pithy_live_..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://en.wikipedia.org/wiki/Octopus"}'

What you get back

{
  "content": "Contents of https://en.wikipedia.org/wiki/Octopus:\nTitle: Octopus - Wikipedia\n\nAn octopus (pl.: octopuses or octopodes...\n\n---\nAvailable actions on this page:\n  - click: \"a:has-text('Edit')\"\n  - fill: \"input[name='search']\"\n  ..."
}

Actions

The first call returns the page text and the list of available buttons / inputs on it. Your agent picks one and calls back with an actions array:

{
  "url": "https://www.roche.com/solutions/pipeline",
  "actions": [
    {"action": "click", "selector": "button:has-text('Download current view as CSV')"}
  ]
}
actionparamsexample
clickselector{"action":"click","selector":"text=Download CSV"}
fillselector, value{"action":"fill","selector":"input[name=q]","value":"octopus"}
waitselector or timeout (ms){"action":"wait","selector":".results"}
selectselector, value{"action":"select","selector":"select#lang","value":"en"}
scrolldirection{"action":"scroll","direction":"bottom"}

Actions run sequentially. If a click triggers a file download (CSV, PDF, etc.), the file contents come back in content instead of the page text. PDFs are converted to text via pdftotext; other binaries return a curl command your agent can use to save the file locally.

Selectors are Playwright locators. CSS by default; selectors starting with / are treated as XPath.


Response & headers

The body is always JSON with a single content string. The receipt lives in response headers:

headermeaning
X-Queue-Wait-MsHow long the request sat in the queue before a Chromium opened up. Not billed.
X-Compute-SecondsActual Chromium work time. Billed. Capped at 30.000.
X-Charge-USDWhat you paid for this fetch, six decimal places.
X-Balance-USDWhat’s left in your bowl after this fetch.
X-Gruel-Served-USDSame as X-Charge-USD. We had to.

Pricing

Per second of Chromium time:

$0.000092 / second  (Daytona medium-equivalent × 2)
capped at         $0.003 per fetch  (the 30-second timeout)
rounded up to     next microdollar
fetch shapeelapsedcharge
simple (Wikipedia, blog)~5s$0.000460
JS-heavy (SPAs, Shadow DOM)~10s$0.000920
with actions (click + download)~15s$0.001380
worst case (30s cap)30s$0.002760

Queue time isn’t billed. Only the seconds Chromium actually spent on your page. Failed fetches aren’t billed either — if the worker returns an error, your bowl is not touched.

Top-ups via Stripe Checkout in $5 / $20 / $50 packs. Credits don’t expire. Refundable while unused.


Errors

JSON errors carry a please_sir field. The status code tells your tooling what to do; the body tells you the why.

statusbodywhy
401{"please_sir": "no key — buy gruel at pithy.bot"}No Authorization header.
401{"please_sir": "unknown key — sign up at pithy.bot"}Key not recognised.
402{"please_sir": "may I have some more? balance ..."}Balance below the $0.003 per-fetch cap. Top up.
429{"please_sir": "you have too many in flight already; ..."}Per-key cap hit (max 2 in flight / queued per key).
429{"please_sir": "the workhouse is full; ..."}Global queue full after 30s wait. Retry shortly.
502{"please_sir": "the kitchen is unwell; ..."}Worker error. You are not charged.
404{"please_sir": "that page doesn’t exist."}Wrong route.

MCP clients

Claude Code

claude mcp add pithy --transport http https://pithy.bot/mcp/ \
  --header "Authorization: Bearer pithy_live_..."

Or edit ~/.claude.json directly with the JSON block above.

Cursor

Add to your project’s .cursor/mcp.json (or User Settings → MCP):

{
  "mcpServers": {
    "pithy": {
      "type": "http",
      "url": "https://pithy.bot/mcp/",
      "headers": { "Authorization": "Bearer pithy_live_..." }
    }
  }
}

Windsurf / Continue / generic MCP client

Same JSON. Streamable HTTP transport, Authorization header for auth. If your client only supports stdio, run mcp-fetch-ux locally instead and skip the hosted service.


FAQ

Why is it called pithy.bot?

Pithy means concise and forcefully expressive. The clipboard capture strips the page to its visible text. The metering returns the bill in the response headers. The pricing fits on one line. The name fits.

Is there a free tier?

Every new signup gets a $0.10 trial — about 100 typical fetches, no credit card. Beyond that, top up in $5 packs ($0.000092/sec, ~$0.001 per typical 10 s fetch, $5 covers ~5,400 fetches). No monthly minimum, no subscription. Credits don’t expire.

What happens if the workhouse is overwhelmed?

Max 3 Chromiums concurrently (hard limit). Max 2 in-flight + queued per key. Past that, you get a 429 with Retry-After. No request waits more than ~30 seconds in the queue.

Do you log the URLs I fetch?

The host portion of each URL is logged in your usage table for billing receipts (e.g. en.wikipedia.org). Path, query, response body, and rendered content are not stored. We don’t train on, sell, or share your traffic.

Do you support residential proxies / specific countries?

No. The service runs from a residential ISP in Darien, CT. Patchright handles bot detection on the page-script side; we don’t rotate IPs. Sites that geofence away from the US East coast will see a US East coast residential IP.

What’s the source?

Two pieces, dual-source. The open-source MCP library is mcp-fetch-ux (MIT) — same Patchright + clipboard extraction the hosted service runs, but you can clone it, make server, and have it on localhost:5006 in five minutes. Free, no signup. pithy.bot is the managed version: auth, queueing, billing, hosting — that wrapper is closed source.