{
  "markdown": "# solvegate-mcp\n\n[![CI](https://github.com/SolveGate/solvegate-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/SolveGate/solvegate-mcp/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/solvegate-mcp)](https://www.npmjs.com/package/solvegate-mcp)\n[![Glama score](https://glama.ai/mcp/servers/SolveGate/solvegate-mcp/badges/score.svg)](https://glama.ai/mcp/servers/SolveGate/solvegate-mcp)\n\nAn MCP server that lets an agent deal with Cloudflare Turnstile: check whether a\npage has one, and clear it when it does.\n\nThree tools. One of them needs no account.\n\n| Tool | What it does | Needs a key |\n|---|---|---|\n| `inspect_page` | Fetch a URL and report whether Cloudflare Turnstile is on it, its sitekey, how it renders, its `data-*` configuration, and whether the page is a full-page WAF challenge instead of a widget | **No** |\n| `solve_turnstile` | Clear a Turnstile or Turnstile WAF challenge and return a token | Yes |\n| `get_solve` | Fetch a solve by id — free, never re-bills | Yes |\n\n## Install\n\n```bash\nnpx solvegate-mcp\n```\n\nClaude Desktop / any MCP client, in your config:\n\n```json\n{\n  \"mcpServers\": {\n    \"solvegate\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"solvegate-mcp\"],\n      \"env\": { \"SOLVEGATE_API_KEY\": \"sk_test_…\" }\n    }\n  }\n}\n```\n\nLeave `SOLVEGATE_API_KEY` out and `inspect_page` still works. That is deliberate:\nyou should be able to see what the server does before deciding whether to sign\nup for anything.\n\nGet a key at [solvegate.io](https://solvegate.io). A free `sk_test_` sandbox key\nneeds no card and returns a deterministic token instantly — right for wiring this\nup, and it never clears a real gate.\n\n## Why `inspect_page` exists\n\nThe commonest wrong turn with a solver is calling it when you should have looked\nfirst. Three cases account for most of it:\n\n- **The page carries reCAPTCHA or hCaptcha, not Turnstile.** Those are different\n  products from different vendors. This server does not solve them, and neither\n  does SolveGate — `inspect_page` says so by name instead of letting you find out\n  from a `422`.\n- **It is a WAF challenge, not a widget.** A full-page Cloudflare interstitial\n  has no `data-sitekey`, because the challenge belongs to a zone rule rather than\n  to a widget you embed. There is nothing to read off the page, and the gate is\n  `waf` rather than `turnstile`.\n- **The sitekey is rendered from script after load.** Then it is not in the\n  served HTML at all, and the tool says that rather than guessing.\n\nInspecting is free, takes about a second, and is quite often the whole answer.\n\n## What it will not tell you\n\n**The widget mode.** Managed, non-interactive and invisible are stored on the\nwidget inside the Cloudflare account that owns the sitekey. The page carries only\nthe key, so no tool can read the mode off the source — including this one, and\nincluding anything that claims otherwise.\n\nIt does not matter for solving: all three modes resolve to the same request. A\nsitekey, a page URL, and a token back.\n\nThe one exception is Cloudflare's five documented dummy sitekeys, whose widget\ntype Cloudflare publishes itself. `inspect_page` reports those, and finding one\non a page tells you something useful — you are looking at a staging build rather\nthan production.\n\n## Configuration\n\n| Variable | Default | What it does |\n|---|---|---|\n| `SOLVEGATE_API_KEY` | — | Your key. `sk_test_` for the sandbox, `sk_live_` for real gates. |\n| `SOLVEGATE_BASE_URL` | `https://api.solvegate.io` | API base. |\n| `SOLVEGATE_SITE_URL` | `https://solvegate.io` | Where `inspect_page` runs. |\n| `SOLVEGATE_TIMEOUT_MS` | `30000` | Per-request timeout. |\n| `SOLVEGATE_MAX_WAIT_MS` | `60000` | How long `solve_turnstile` waits for a pending solve. |\n\nThe key is read from the environment and is never a tool argument — a tool\nargument is model-visible and ends up in transcripts.\n\n## Notes on behaviour\n\n**Solving is async underneath.** `solve_turnstile` creates the solve with\n`async: true` and polls it, rather than holding a connection open for the whole\nattempt. An agent's tool call has a timeout it does not control, and a\nsynchronous solve makes a slow gate look like a dead tool. It also means a\ntimeout here leaves you a solve id: the error names it, and `get_solve` will pick\nit up rather than losing a solve that was already billed.\n\n**Errors are results, not exceptions.** Every failure comes back as an `isError`\nresult carrying SolveGate's own `error.code` — `balance_empty`, `unknown_sitekey`,\n`rate_limited`, `forbidden_target`. A model can act on those. It can do nothing\nuseful with a stack trace.\n\n**Tokens are single-use and short-lived.** `expiresAt` is Unix seconds; past it,\nCloudflare stops accepting the token and the solve record is just a record.\nRequest a token at the moment you submit it.\n\n**Check `mode` before trusting a token.** An `sk_test_` key returns\n`mode: \"sandbox\"`, and a sandbox token will not clear a real gate. The field\nexists so a test key in a production config fails loudly rather than quietly.\n\n## Acceptable use\n\nSolve only against properties you own or are authorised to test. This exists for\nend-to-end tests that keep failing on a challenge, CI against your own staging,\nand synthetic monitoring of your own production. The\n[acceptable use policy](https://solvegate.io/legal) is the binding version, and\ntargets on the denylist return `403 forbidden_target` regardless of what any\nagent asks for.\n\n## Development\n\n```bash\nnpm install\nnpm run build\nnpm test          # spawns the built server and speaks MCP to it\nOFFLINE=1 npm test  # skips the two tests that reach the network\n```\n\nThe tests drive a real stdio transport rather than calling the tool callbacks\ndirectly. That is on purpose: a schema the SDK rejects at registration, or a\nstray write to stdout — which corrupts the transport, since stdout *is* the\ntransport — only shows up when something actually speaks the protocol to it.\n\n## Links\n\n- [SolveGate API reference](https://solvegate.io/docs)\n- [OpenAPI spec](https://solvegate.io/openapi.json)\n- [Turnstile checker](https://solvegate.io/tools/turnstile-checker) — the same\n  inspection this server exposes, in a browser\n- [Turnstile error index](https://solvegate.io/turnstile-errors)\n\nMIT.\n",
  "bytes": 6238,
  "sha": "cd2e22952d60816d898fac6faf29df7ef6dba6490230d61d1511cc3e0f0e9e02",
  "repo_slug": "solvegate/solvegate-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_solvegate_solvegate_mcp_a1bb9c18/readme"
}