Captcha solver MCP server for AI agents: solve reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest and image captchas via CapSkip, a local unlimited captcha solver with no per-solve fees.
CapSkip MCP demonstrates solid tool definitions with consistent naming, comprehensive descriptions, and explicit input schemas. All 9 tools follow verb_noun naming (capskip_solve_*). Descriptions are detailed (150-400 chars) and explain WHEN to use each tool, prerequisites, and common failure modes. Input schemas are present with type annotations and parameter descriptions. However, output schemas are not documented in the source code, responses are described narratively but lack formal JSON Schema definitions. Error handling is implicit (timeouts, invalid inputs mentioned in descriptions) but not explicitly structured with recovery guidance. Tool composition is excellent: each tool solves one captcha type, and descriptions guide parameter selection. No security issues detected (no credentials in params, all inputs are URLs/keys/images). The server targets a specialized domain (captcha solving) with appropriate tool granularity.
Solve an ALTCHA proof-of-work challenge. ALTCHA is not a recognition captcha — there is nothing to read; the client brute-forces a number that satisfies a challenge, so a solve is deterministic and takes milliseconds. Give it either challenge_url (the endpoint the <altcha-widget> fetches from, which CapSkip will fetch) or challenge_json (the challenge document itself). Returns a token to put in the page's form field named `altcha`, verbatim. IMPORTANT: challenges expire quickly — some sites inside two minutes — so read the challenge immediately before calling and submit the token promptly. An expired challenge is rejected with a bare "verification failed" that looks exactly like a wrong answer.
Solve a CaptchaFox challenge. CaptchaFox scores the browser itself rather than asking the visitor to read anything, so most solves draw no puzzle at all. Returns a token to put in the form field named 'cf-captcha-response', verbatim — it is verified server side against the session that produced it, so any edit invalidates it. IMPORTANT: the url must be the page the widget actually runs on. CaptchaFox checks it against the domains the key is registered for and refuses a mismatch permanently, not intermittently — so a sitekey that fails immediately and consistently usually means the wrong page URL, not a bad key. The result also carries the User-Agent the token was minted under; submit under that one, not your own.
Solve a Capy Puzzle captcha — a slide puzzle where a piece is dragged into a hole cut out of a photograph. IMPORTANT: unlike every other captcha tool here, the answer is NOT a single token. It is three values — captchakey, challengekey and answer — which all go into the target form, in fields named 'capy_captchakey', 'capy_challengekey' and 'capy_answer'. Submit the answer verbatim: it is the drag path the widget would have recorded, so trimming or re-encoding it invalidates the solve. The challenge key is single-use and short-lived, so submit promptly rather than caching the three values. A solve takes about two seconds — Capy refuses answers that arrive faster than a human could have produced them, so CapSkip holds the result back deliberately.
Output schemas not formally documented. Descriptions mention return values (e.g., 'Returns a token', 'Returns geetest_challenge, geetest_validate, geetest_seccode') but no JSON Schema definitions are visible in source. LLMs cannot reliably parse unstructured responses or plan downstream tool calls without explicit output schemas.
Error handling lacks structured recovery guidance. Descriptions mention failure modes (e.g., 'stale challenge', 'wrong version', 'expired challenge') but do not provide actionable next steps. Errors should categorize as retryable/user-fixable/fatal and suggest recovery actions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | 2025-06-18+ | v2 |
Solve a Friendly Captcha proof-of-work challenge. Nothing is shown on screen — the widget does arithmetic instead of asking the visitor to do anything. IMPORTANT: two entirely different protocols ship under this one name, sharing a brand and a sitekey namespace and nothing else, and a sitekey does not tell you which a site uses. Send version (v1 or v2), or send module_script and let CapSkip read the version off the build the site loads. Solving the wrong one returns a well-formed token the site rejects, with nothing to indicate the version was the problem. The form field also differs by version: v1 uses 'frc-captcha-solution', v2 uses 'frc-captcha-response'. Solve time is not a constant — the service sets the difficulty per request — so budget for that rather than assuming a fixed duration.
Solve a GeeTest v3 slide-puzzle captcha. Returns geetest_challenge, geetest_validate, and geetest_seccode to post back exactly as the site's own front-end would. IMPORTANT: the challenge value is single-use and expires in roughly a minute, so fetch gt and challenge from the page immediately before calling. A stale challenge is the most common failure.
Read the text out of a distorted-text captcha image. Returns the recognized text, which you type into the page's captcha field. Proxies are not supported for image captchas.
Solve a reCAPTCHA v2 or v3 challenge. Returns a token to submit in the page's g-recaptcha-response field.
Check if CapSkip is running and reachable at the configured host and port.
Solve a Cloudflare Turnstile challenge. Returns a token to submit in the page's cf-turnstile-response field.
Optional parameters lack clear defaults. Parameters like 'timeout', 'api_server', 'proxy', 'version', 'min_score' are marked optional but default behavior is not always explicit in descriptions. E.g., capskip_solve_friendly_captcha defaults to v1 'when neither is given' but this is buried in the description.
Mutually exclusive parameters not clearly marked. capskip_solve_altcha accepts 'challenge_url' OR 'challenge_json' (mutually exclusive); capskip_solve_friendly_captcha accepts 'version' OR 'module_script' OR 'nomodule_script'. Descriptions state 'Pass this or that' but do not explicitly warn against passing both.
Timeout parameter lacks bounds documentation. All tools accept 'timeout' (seconds, max 600) but no minimum is stated. Descriptions should clarify: 'Timeout in seconds, 1 - 600 (default: 120)' to prevent LLMs from passing invalid values.