capskip-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ # Getting Started
2
+
3
+ This guide walks you through installing CapSkip, adding `capskip-mcp` to your MCP client, and running your first captcha solve.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ | Requirement | Details |
10
+ |---|---|
11
+ | **CapSkip app** | Windows desktop app from [capskip.com](https://capskip.com) |
12
+ | **Node.js** | 18 or newer (`capskip-mcp` runs via `npx`, no separate install) |
13
+ | **An MCP client** | Claude Desktop, Claude Code, Cursor, or VS Code |
14
+
15
+ ---
16
+
17
+ ## Step 1 — Install and configure CapSkip
18
+
19
+ 1. Download CapSkip from [capskip.com](https://capskip.com).
20
+ 2. Install and launch the application. Leave it running in the background — `capskip-mcp` talks to it over `localhost`, so it must be running whenever a tool is called.
21
+ 3. Open **Settings** and note:
22
+ - **Port** — default is `8080`
23
+ - **API key validation** — if enabled, copy your API key; if disabled, any string (e.g. `capskip`) is accepted
24
+
25
+ ### Verify CapSkip is running
26
+
27
+ **Windows (PowerShell):**
28
+
29
+ ```powershell
30
+ Invoke-WebRequest "http://127.0.0.1:8080/res.php?key=capskip&action=get&id=0" -UseBasicParsing
31
+ ```
32
+
33
+ **Linux / macOS:**
34
+
35
+ ```bash
36
+ curl "http://127.0.0.1:8080/res.php?key=capskip&action=get&id=0"
37
+ ```
38
+
39
+ Any response — even an error like `ERROR_WRONG_CAPTCHA_ID` — confirms CapSkip is up and listening.
40
+
41
+ ---
42
+
43
+ ## Step 2 — Add capskip-mcp to your client
44
+
45
+ Every client points at the same command:
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "capskip": {
51
+ "command": "npx",
52
+ "args": ["-y", "capskip-mcp"],
53
+ "env": {
54
+ "CAPSKIP_HOST": "127.0.0.1",
55
+ "CAPSKIP_PORT": "8080",
56
+ "CAPSKIP_API_KEY": "capskip"
57
+ }
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ Substitute your own port and API key from Step 1. Where that block goes differs per client:
64
+
65
+ ### Claude Desktop
66
+
67
+ Open **Settings → Developer → Edit Config** (or edit `claude_desktop_config.json` directly — `%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS) and paste the block above. Full file: [examples/claude-desktop.json](../examples/claude-desktop.json).
68
+
69
+ ### Claude Code
70
+
71
+ Add the server from the command line — no config file to edit:
72
+
73
+ ```bash
74
+ claude mcp add capskip -- npx -y capskip-mcp
75
+ ```
76
+
77
+ See [examples/claude-code.md](../examples/claude-code.md) for the custom-port variant and how to confirm it connected.
78
+
79
+ ### Cursor
80
+
81
+ Paste the block above into `.cursor/mcp.json` (project-level) or your global Cursor MCP settings. Full file: [examples/cursor.json](../examples/cursor.json).
82
+
83
+ ### VS Code
84
+
85
+ VS Code's MCP config uses `servers` instead of `mcpServers` and an explicit `type`:
86
+
87
+ ```json
88
+ {
89
+ "servers": {
90
+ "capskip": {
91
+ "type": "stdio",
92
+ "command": "npx",
93
+ "args": ["-y", "capskip-mcp"],
94
+ "env": { "CAPSKIP_PORT": "8080" }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ Paste this into `.vscode/mcp.json`. Full file: [examples/vscode.json](../examples/vscode.json).
101
+
102
+ ---
103
+
104
+ ## Step 3 — Verify with `capskip_status`
105
+
106
+ Restart your client, open a new chat, and ask it to call `capskip_status` (no arguments). With CapSkip running on the configured host and port, the tool returns:
107
+
108
+ ```json
109
+ {
110
+ "reachable": true,
111
+ "host": "127.0.0.1",
112
+ "port": 8080,
113
+ "latencyMs": 6,
114
+ "detail": "CapSkip answered at 127.0.0.1:8080 in 6ms."
115
+ }
116
+ ```
117
+
118
+ If CapSkip is not running, or the port is wrong, `capskip_status` still returns a normal (non-error) result — it reports the problem rather than failing — with `reachable: false` and a `detail` explaining what to check:
119
+
120
+ ```json
121
+ {
122
+ "reachable": false,
123
+ "host": "127.0.0.1",
124
+ "port": 8080,
125
+ "detail": "No response from 127.0.0.1:8080 (connect ECONNREFUSED 127.0.0.1:8080). Start the CapSkip desktop app, then confirm its API port matches — override with CAPSKIP_HOST / CAPSKIP_PORT."
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Step 4 — Your first solve
132
+
133
+ With CapSkip confirmed reachable, ask your agent to solve a captcha it has encountered while browsing, or try it directly. For a reCAPTCHA v2 widget with sitekey `6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-` on `https://example.com/login`, the agent calls:
134
+
135
+ ```json
136
+ {
137
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
138
+ "url": "https://example.com/login"
139
+ }
140
+ ```
141
+
142
+ against `capskip_solve_recaptcha`, and gets back:
143
+
144
+ ```json
145
+ {
146
+ "captchaId": "48213",
147
+ "code": "03AGdBq26f...",
148
+ "solveSeconds": 9.4
149
+ }
150
+ ```
151
+
152
+ `code` is the token — it goes in the page's `g-recaptcha-response` field before the form is submitted.
153
+
154
+ ---
155
+
156
+ ## Next steps
157
+
158
+ - [Tutorial](TUTORIAL.md) — every captcha type, end to end
159
+ - [API Reference](API_REFERENCE.md) — every tool, parameter, and return shape
160
+ - [Troubleshooting](TROUBLESHOOTING.md) — fix common errors
161
+ - [CapSkip API docs](https://capskip.com/api-docs/) — the raw HTTP API `capskip-mcp` wraps
@@ -0,0 +1,236 @@
1
+ # Troubleshooting
2
+
3
+ Common issues when running `capskip-mcp` and how to fix them.
4
+
5
+ ---
6
+
7
+ ## Client shows the server as failed to start
8
+
9
+ **Symptom:** Claude Desktop / Claude Code / Cursor / VS Code lists `capskip` as errored, crashed, or disconnected, with no useful detail in the UI.
10
+
11
+ **Cause:** Usually one of: Node.js is missing or too old, `npx` cannot reach the registry, or a config error (bad flag, bad env value) makes the process exit immediately.
12
+
13
+ **Fix**
14
+
15
+ 1. Confirm Node 18+:
16
+
17
+ ```bash
18
+ node --version
19
+ ```
20
+
21
+ 2. Run the server by hand and read stderr directly — this is the fastest way to see the real failure, since MCP clients often swallow it:
22
+
23
+ ```bash
24
+ npx -y capskip-mcp
25
+ ```
26
+
27
+ A healthy start prints one line to stderr and then waits:
28
+
29
+ ```
30
+ capskip-mcp ready (CapSkip at 127.0.0.1:8080)
31
+ ```
32
+
33
+ A config problem exits immediately with a message naming the offending flag or variable, e.g.:
34
+
35
+ ```
36
+ capskip-mcp: CAPSKIP_PORT must be a whole number, got 'abc'.
37
+ ```
38
+
39
+ 3. If it hangs with no output at all, the client is probably fine and CapSkip itself is the problem — see the next section.
40
+
41
+ ---
42
+
43
+ ## Every tool says "not reachable"
44
+
45
+ **Symptom:** A solve fails with:
46
+
47
+ ```
48
+ CapSkip is not reachable at 127.0.0.1:8080. Confirm the CapSkip desktop app is running and that its API port matches this setting (override with CAPSKIP_HOST / CAPSKIP_PORT).
49
+ ```
50
+
51
+ and `capskip_status` reports `reachable: false` with:
52
+
53
+ ```
54
+ No response from 127.0.0.1:8080 (connect ECONNREFUSED 127.0.0.1:8080). Start the CapSkip desktop app, then confirm its API port matches — override with CAPSKIP_HOST / CAPSKIP_PORT.
55
+ ```
56
+
57
+ **Cause:** The CapSkip desktop app is not running, or its API port does not match the `CAPSKIP_PORT` the server was started with.
58
+
59
+ **Fix**
60
+
61
+ 1. Launch (or un-minimize) the CapSkip desktop app.
62
+ 2. Open CapSkip Settings and confirm the **API port**.
63
+ 3. Match it in your client config:
64
+
65
+ ```json
66
+ "env": { "CAPSKIP_HOST": "127.0.0.1", "CAPSKIP_PORT": "8080" }
67
+ ```
68
+
69
+ 4. Call `capskip_status` again — it reports `reachable` and a `detail` string without needing CapSkip to solve anything, so it is the fastest way to confirm the fix worked.
70
+
71
+ ---
72
+
73
+ ## "Something is listening … but it did not answer as CapSkip"
74
+
75
+ **Symptom:** `capskip_status` reports `reachable: false` with:
76
+
77
+ ```
78
+ Something is listening on 127.0.0.1:8080 but it did not answer as CapSkip (HTTP 404). Check the API port in CapSkip settings, and that nothing else has taken that port — override with CAPSKIP_HOST / CAPSKIP_PORT.
79
+ ```
80
+
81
+ **Cause:** A different process holds that port. 8080 is a common default for local dev servers, proxies, and admin UIs, so this is easy to hit. CapSkip may not be running at all, or may be running on a different port.
82
+
83
+ **Fix**
84
+
85
+ 1. Find what actually holds the port:
86
+
87
+ ```bash
88
+ # macOS / Linux
89
+ lsof -i :8080
90
+
91
+ # Windows
92
+ netstat -ano | findstr :8080
93
+ ```
94
+
95
+ 2. Either stop that process, or point the server at CapSkip's real port with `CAPSKIP_PORT`.
96
+
97
+ Note that `capskip_status` deliberately reports this as **not** reachable. An earlier version treated any HTTP response as success, which meant it could report a healthy CapSkip seconds before a solve failed against the same port.
98
+
99
+ ---
100
+
101
+ ## "CapSkip rejected the API key"
102
+
103
+ **Symptom:**
104
+
105
+ ```
106
+ CapSkip rejected the API key. Set CAPSKIP_API_KEY to the key shown in CapSkip settings, or disable key validation there.
107
+ ```
108
+
109
+ **Cause:** API key validation is enabled in CapSkip, and either no key was configured or it does not match.
110
+
111
+ **Fix**
112
+
113
+ 1. Copy the exact key from CapSkip Settings and set it:
114
+
115
+ ```json
116
+ "env": { "CAPSKIP_API_KEY": "your-actual-key" }
117
+ ```
118
+
119
+ 2. Or, for local development only, disable API key validation in CapSkip Settings — any string (including the default `capskip`) is then accepted.
120
+
121
+ `capskip_status` diagnoses this without spending a solve. It reports `reachable: true` — CapSkip is running, the key is what is wrong — with:
122
+
123
+ ```
124
+ CapSkip is running at 127.0.0.1:8080, but it rejected the API key. Set CAPSKIP_API_KEY to the key shown in CapSkip settings, or disable key validation there. Solves will fail until this is fixed.
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Solve times out
130
+
131
+ **Symptom:**
132
+
133
+ ```
134
+ The solve did not finish within 300.0s. Raise the timeout parameter, or check CapSkip's own queue.
135
+ ```
136
+
137
+ **Cause:** The captcha is taking longer than the configured budget, or CapSkip is stuck on it.
138
+
139
+ **Fix**
140
+
141
+ 1. Pass a larger `timeout` on the tool call (capped at 600 seconds — a larger value is rejected outright, not silently clamped):
142
+
143
+ ```json
144
+ { "sitekey": "...", "url": "...", "timeout": 600 }
145
+ ```
146
+
147
+ 2. Or raise the default so you do not have to pass it every time. `CAPSKIP_TIMEOUT` covers `capskip_solve_image_captcha`; `CAPSKIP_RECAPTCHA_TIMEOUT` covers the other three tools. These env-level defaults have their own bound (1–3600s), independent of the 600s per-call cap:
148
+
149
+ ```json
150
+ "env": { "CAPSKIP_RECAPTCHA_TIMEOUT": "600" }
151
+ ```
152
+
153
+ 3. Check CapSkip's own queue/log in the desktop app — a solve that never finishes is often stuck there, not waiting on the network.
154
+
155
+ The timeout error also names the CapSkip captcha id when one was assigned, so a solve that completes just after the deadline can still be read back via `res.php` or any CapSkip SDK.
156
+
157
+ ---
158
+
159
+ ## GeeTest always fails
160
+
161
+ **Symptom:** `capskip_solve_geetest` fails or times out even though `gt` and `challenge` look correct.
162
+
163
+ **Cause:** `challenge` is single-use and expires in about a minute. A value copied earlier, cached, or reused across two solves is already dead — this is the most common cause of GeeTest failures.
164
+
165
+ **Fix:** Fetch `gt` and `challenge` from the target page immediately before calling `capskip_solve_geetest`, and on failure fetch a fresh pair rather than retrying the same one:
166
+
167
+ ```json
168
+ {
169
+ "gt": "81388ea1fc187e0c335c0a8907ff2625",
170
+ "challenge": "7cf6a8b1a2c34d5e6f7089abcdef0123",
171
+ "url": "https://example.com/login"
172
+ }
173
+ ```
174
+
175
+ If the site loads GeeTest from a non-default domain, pass it through as `api_server`, e.g. `"api-na.geetest.com"`.
176
+
177
+ ---
178
+
179
+ ## Turnstile token rejected by the site
180
+
181
+ **Symptom:** `capskip_solve_turnstile` returns a token, but Cloudflare still blocks the submission.
182
+
183
+ **Cause:** The token was submitted using a different User-Agent than the one CapSkip used to solve it. Cloudflare binds the token to the solving User-Agent and rejects a mismatch.
184
+
185
+ **Fix:** Use `userAgent` from the tool result as the `User-Agent` header (or equivalent setting in your browser-automation tool) when you submit `cf-turnstile-response`. If the result has no `userAgent`, CapSkip did not return one for that solve — retry, since resubmitting under an arbitrary User-Agent will not work either.
186
+
187
+ ---
188
+
189
+ ## hCaptcha or FunCaptcha never solves
190
+
191
+ **Symptom:** `capskip_solve_recaptcha` is called on a widget that has a `data-sitekey`, and every attempt fails, times out, or returns a token the site rejects.
192
+
193
+ **Cause:** The captcha is not a reCAPTCHA. CapSkip supports exactly four types — image captchas, reCAPTCHA v2/v3, Cloudflare Turnstile, and GeeTest v3. It **cannot** solve hCaptcha or FunCaptcha/Arkose, and there is no tool for them.
194
+
195
+ hCaptcha is easy to misidentify because it also carries a `data-sitekey`:
196
+
197
+ ```html
198
+ <div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
199
+ ```
200
+
201
+ **Fix:** Check the widget's class or script source before choosing a tool.
202
+
203
+ | Markup | Type | Tool |
204
+ |---|---|---|
205
+ | `class="g-recaptcha"`, `www.google.com/recaptcha/` | reCAPTCHA v2/v3 | `capskip_solve_recaptcha` |
206
+ | `class="cf-turnstile"`, `challenges.cloudflare.com` | Turnstile | `capskip_solve_turnstile` |
207
+ | `gt=` / `challenge=` from a GeeTest init call | GeeTest v3 | `capskip_solve_geetest` |
208
+ | `class="h-captcha"`, `js.hcaptcha.com` | hCaptcha | **not supported** |
209
+ | `funcaptcha` / `arkoselabs.com` | FunCaptcha/Arkose | **not supported** |
210
+
211
+ The server tells connected models this in its instructions, but a model can still guess wrong from the DOM alone. Retrying will not help — the type is the problem.
212
+
213
+ ---
214
+
215
+ ## reCAPTCHA v3 accepted but the site still blocks
216
+
217
+ **Symptom:** `capskip_solve_recaptcha` returns a token, the site's own verification accepts it, but the site still treats the visit as suspicious (blocks, challenges, or degrades the experience).
218
+
219
+ **Cause:** reCAPTCHA v3 is score-based. Google assigns the score from signals CapSkip has no access to — device and browsing history, IP reputation, and so on — and a locally-solved token carries whatever score Google decided. No solver, local or cloud, can raise a score after the token is issued. This is also why there is no `min_score` parameter on `capskip_solve_recaptcha`.
220
+
221
+ **Fix:** There isn't one at the token level. If the target consistently scores low, that is a signal problem with the requesting environment (IP reputation, browser fingerprint, request pattern), not something a solver call can override.
222
+
223
+ ---
224
+
225
+ ## Still stuck?
226
+
227
+ 1. [CapSkip API docs](https://capskip.com/api-docs/)
228
+ 2. [GitHub Issues](https://github.com/capskip/capskip-mcp/issues)
229
+ 3. CapSkip support: support@capskip.com
230
+
231
+ When opening an issue, include:
232
+
233
+ - Node.js version (`node --version`)
234
+ - `capskip-mcp` version (from `package.json`, or `npx -y capskip-mcp@latest` to confirm you're current)
235
+ - CapSkip port and the captcha type involved
236
+ - The exact tool call and the full error text (redact sitekeys, tokens, and API keys)
@@ -0,0 +1,284 @@
1
+ # CapSkip MCP Server — Complete Tutorial
2
+
3
+ This tutorial takes you from zero to solving every captcha type CapSkip supports, one page-recognition pattern at a time. Work through it top to bottom, or jump to the section you need.
4
+
5
+ For each captcha type, four questions in order:
6
+
7
+ 1. **How do I recognize this captcha on a page?**
8
+ 2. **What do I read off the page?**
9
+ 3. **What call do I make?**
10
+ 4. **Where does the answer go?**
11
+
12
+ **Contents**
13
+
14
+ 1. [Image captcha](#1-image-captcha)
15
+ 2. [reCAPTCHA v2](#2-recaptcha-v2)
16
+ 3. [reCAPTCHA v2 Invisible](#3-recaptcha-v2-invisible)
17
+ 4. [reCAPTCHA v2 Enterprise](#4-recaptcha-v2-enterprise)
18
+ 5. [reCAPTCHA v3](#5-recaptcha-v3)
19
+ 6. [Turnstile widget](#6-turnstile-widget)
20
+ 7. [Turnstile challenge page](#7-turnstile-challenge-page)
21
+ 8. [GeeTest v3](#8-geetest-v3)
22
+ 9. [Using a proxy](#9-using-a-proxy)
23
+
24
+ ---
25
+
26
+ ## 1. Image captcha
27
+
28
+ ### How do I recognize this captcha on a page?
29
+
30
+ A plain `<img>` element showing distorted, wavy, or noisy text, almost always sitting next to a text input for the answer. There is no JavaScript widget, no sitekey, and no site-key attribute to find — the whole captcha is the image.
31
+
32
+ ### What do I read off the page?
33
+
34
+ The image itself — its `src` URL, or the raw bytes if it is served inline. Nothing else is needed; there is no sitekey or page URL requirement for this tool.
35
+
36
+ ### What call do I make?
37
+
38
+ ```json
39
+ {
40
+ "image": "https://example.com/captcha.png"
41
+ }
42
+ ```
43
+
44
+ `image` also accepts a local file path, a `data:` URI, or a raw base64 string — the tool auto-detects which form was passed.
45
+
46
+ ### Where does the answer go?
47
+
48
+ `code` is the recognized text. Type it into the adjacent text input and submit the form.
49
+
50
+ ---
51
+
52
+ ## 2. reCAPTCHA v2
53
+
54
+ ### How do I recognize this captcha on a page?
55
+
56
+ The classic "I'm not a robot" checkbox: a `<div class="g-recaptcha" data-sitekey="...">`, or a call to `grecaptcha.render(container, { sitekey: '...' })` in the page's scripts. The widget iframe's `src` also carries the sitekey and `size` query parameters.
57
+
58
+ ### What do I read off the page?
59
+
60
+ The `data-sitekey` attribute (or the `sitekey` field of the JS config object), and the full URL of the page the widget is on.
61
+
62
+ ### What call do I make?
63
+
64
+ ```json
65
+ {
66
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
67
+ "url": "https://example.com/login"
68
+ }
69
+ ```
70
+
71
+ `version` defaults to `v2`, so it can be omitted for a standard checkbox widget.
72
+
73
+ ### Where does the answer go?
74
+
75
+ `code` is the `g-recaptcha-response` token. reCAPTCHA's own widget normally creates a hidden `textarea` with that `name` for you to populate — set its value to `code`, then submit the form (or invoke the page's `data-callback`, if it uses one, with the token).
76
+
77
+ ---
78
+
79
+ ## 3. reCAPTCHA v2 Invisible
80
+
81
+ ### How do I recognize this captcha on a page?
82
+
83
+ No visible checkbox. Instead, `data-size="invisible"` on the `.g-recaptcha` div, `grecaptcha.render(..., { size: 'invisible' })` in script, or `size=invisible` in the widget iframe's `src` URL. The captcha typically fires when a form is submitted or a button is clicked, rather than presenting anything to click beforehand.
84
+
85
+ ### What do I read off the page?
86
+
87
+ The same `data-sitekey` as a standard v2 widget, plus the fact that it is invisible.
88
+
89
+ ### What call do I make?
90
+
91
+ ```json
92
+ {
93
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
94
+ "url": "https://example.com/login",
95
+ "invisible": true
96
+ }
97
+ ```
98
+
99
+ ### Where does the answer go?
100
+
101
+ Same as standard v2 — `code` goes in the `g-recaptcha-response` field. Because invisible widgets are usually wired to a `data-callback`, you may also need to invoke that callback with the token to unblock the page's own submit logic.
102
+
103
+ ---
104
+
105
+ ## 4. reCAPTCHA v2 Enterprise
106
+
107
+ ### How do I recognize this captcha on a page?
108
+
109
+ The page loads `https://www.google.com/recaptcha/enterprise.js` instead of the standard `api.js`, or calls `grecaptcha.enterprise.render(...)`. The loader script URL is the reliable signal — sitekey formatting alone does not distinguish Enterprise from standard reCAPTCHA.
110
+
111
+ ### What do I read off the page?
112
+
113
+ The `data-sitekey` as usual, and the fact that it is served via the Enterprise loader.
114
+
115
+ ### What call do I make?
116
+
117
+ ```json
118
+ {
119
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
120
+ "url": "https://example.com/login",
121
+ "enterprise": true
122
+ }
123
+ ```
124
+
125
+ `enterprise` works with either `version`, so it also applies to Enterprise v3 (Section 5).
126
+
127
+ ### Where does the answer go?
128
+
129
+ Same as the non-Enterprise variant of whichever version you set — `g-recaptcha-response` for v2 Enterprise, or wherever the page's own JS reads the resolved token for v3 Enterprise.
130
+
131
+ ---
132
+
133
+ ## 5. reCAPTCHA v3
134
+
135
+ ### How do I recognize this captcha on a page?
136
+
137
+ No visible widget at all — at most a small badge in a page corner reading "protected by reCAPTCHA". Look in the page's scripts for `<script src=".../api.js?render=SITEKEY">` and a call to `grecaptcha.execute(sitekey, { action: '...' })`.
138
+
139
+ ### What do I read off the page?
140
+
141
+ The sitekey from the `render=` query parameter (or the first argument to `grecaptcha.execute`), and the exact `action` string passed as `grecaptcha.execute`'s second argument — it must match what the call site sends.
142
+
143
+ ### What call do I make?
144
+
145
+ ```json
146
+ {
147
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
148
+ "url": "https://example.com/login",
149
+ "version": "v3",
150
+ "action": "submit"
151
+ }
152
+ ```
153
+
154
+ ### Where does the answer go?
155
+
156
+ v3 has no fixed field name the way v2 does. The page's own JavaScript normally calls `grecaptcha.execute(...).then(token => ...)` and does something specific with the result — sets a hidden input, or sends it via `fetch`/XHR. Read what the page does with its own resolved token and do the same with `code`.
157
+
158
+ Because the score behind this token is assigned entirely by Google from signals CapSkip cannot see, there is no `min_score` parameter to request a higher one — see [Using a proxy](#9-using-a-proxy) below and [Troubleshooting](TROUBLESHOOTING.md#recaptcha-v3-accepted-but-the-site-still-blocks) if a v3 token is accepted but the site still treats the request as suspicious.
159
+
160
+ ---
161
+
162
+ ## 6. Turnstile widget
163
+
164
+ ### How do I recognize this captcha on a page?
165
+
166
+ An element with class `cf-turnstile` and a `data-sitekey` attribute, or a call to `turnstile.render(container, { sitekey })`. Rendered inline in a form, usually as a small "Verify you are human" checkbox or spinner.
167
+
168
+ ### What do I read off the page?
169
+
170
+ `data-sitekey`, the page URL, and `data-action` if the page sets one.
171
+
172
+ ### What call do I make?
173
+
174
+ ```json
175
+ {
176
+ "sitekey": "0x4AAAAAAA...",
177
+ "url": "https://example.com"
178
+ }
179
+ ```
180
+
181
+ ### Where does the answer go?
182
+
183
+ `code` goes in a hidden input named `cf-turnstile-response` (Turnstile creates this for you inside the widget). **Submit it with the returned `userAgent` as the request's User-Agent** — Cloudflare binds the token to the solving User-Agent and rejects a mismatch.
184
+
185
+ ---
186
+
187
+ ## 7. Turnstile challenge page
188
+
189
+ ### How do I recognize this captcha on a page?
190
+
191
+ A full-page Cloudflare interstitial — "Checking your browser...", "Verifying you are human..." — served instead of the page you requested, rather than a widget embedded in a form you're filling out.
192
+
193
+ ### What do I read off the page?
194
+
195
+ The sitekey as usual, plus `cData` and `chlPageData` values embedded in the page's inline script or a JSON config blob (field names and exact location vary by Cloudflare's challenge version — search the page source for `cData` and `chlPageData`).
196
+
197
+ ### What call do I make?
198
+
199
+ ```json
200
+ {
201
+ "sitekey": "0x4AAAAAAA...",
202
+ "url": "https://example.com/challenge",
203
+ "action": "managed",
204
+ "cdata": "0=abc123...",
205
+ "pagedata": "3fH...pagedata"
206
+ }
207
+ ```
208
+
209
+ ### Where does the answer go?
210
+
211
+ Same `cf-turnstile-response` field as the widget case, submitted with the returned `userAgent`. Challenge pages are checked at least as strictly as embedded widgets — a mismatched User-Agent here is the most common way a correct-looking token still gets rejected.
212
+
213
+ ---
214
+
215
+ ## 8. GeeTest v3
216
+
217
+ ### How do I recognize this captcha on a page?
218
+
219
+ A slide-puzzle widget, typically inside a container whose id or class mentions "geetest", or a call to `initGeetest({ gt, challenge, ... }, callback)` in the page's scripts.
220
+
221
+ ### What do I read off the page?
222
+
223
+ Unlike a sitekey, `gt` and `challenge` are not static page attributes — the page itself fetches them from an endpoint (often something like `.../register.php` or a `gettype`/`get.php` request) that returns `{"gt": "...", "challenge": "..."}`. Find that request in DevTools → Network, or read the values out of the `initGeetest({ gt, challenge })` call after the page has run it.
224
+
225
+ **`gt` and `challenge` must be fetched immediately before solving.** `gt` is static per site and can be reused, but `challenge` is single-use and expires in about a minute — a value copied earlier or cached is already dead by the time you call the tool.
226
+
227
+ ### What call do I make?
228
+
229
+ ```json
230
+ {
231
+ "gt": "81388ea1fc187e0c335c0a8907ff2625",
232
+ "challenge": "7cf6a8b1a2c34d5e6f7089abcdef0123",
233
+ "url": "https://example.com/login"
234
+ }
235
+ ```
236
+
237
+ If the site loads GeeTest from a non-default domain, add `api_server`, e.g. `"api-na.geetest.com"`.
238
+
239
+ ### Where does the answer go?
240
+
241
+ A three-field post-back: `challenge`, `validate`, and `seccode` from the response map to `geetest_challenge`, `geetest_validate`, and `geetest_seccode` respectively, submitted under those exact names exactly as the site's own front-end would. Sending only `validate` is the most common reason an otherwise-correct solve is rejected — all three fields are required.
242
+
243
+ ---
244
+
245
+ ## 9. Using a proxy
246
+
247
+ Solving through the same IP you will submit from generally improves acceptance for reCAPTCHA, Turnstile, and GeeTest. All three tools accept an optional `proxy` object:
248
+
249
+ ```json
250
+ {
251
+ "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
252
+ "url": "https://example.com/login",
253
+ "proxy": { "type": "HTTPS", "uri": "user:pass@1.2.3.4:3128" }
254
+ }
255
+ ```
256
+
257
+ ```json
258
+ {
259
+ "sitekey": "0x4AAAAAAA...",
260
+ "url": "https://example.com",
261
+ "proxy": { "type": "HTTP", "uri": "1.2.3.4:3128" }
262
+ }
263
+ ```
264
+
265
+ ```json
266
+ {
267
+ "gt": "81388ea1fc187e0c335c0a8907ff2625",
268
+ "challenge": "7cf6a8b1a2c34d5e6f7089abcdef0123",
269
+ "url": "https://example.com/login",
270
+ "proxy": { "type": "SOCKS5", "uri": "1.2.3.4:1080" }
271
+ }
272
+ ```
273
+
274
+ `type` must be one of `HTTP`, `HTTPS`, `SOCKS5`, or `SOCKS5H` — CapSkip maps only these four, and anything else (including `SOCKS4`) is rejected. `uri` may be a bare `host:port` or carry credentials as `login:password@host:port`.
275
+
276
+ **`capskip_solve_image_captcha` does not accept a `proxy` argument.** CapSkip does not support proxying image-captcha solves, and passing one is rejected as an unrecognized key rather than silently ignored.
277
+
278
+ ---
279
+
280
+ ### Where to go next
281
+
282
+ - [API Reference](API_REFERENCE.md) — every tool, parameter, and return shape
283
+ - [Getting Started](GETTING_STARTED.md) — installation and client setup
284
+ - [Troubleshooting](TROUBLESHOOTING.md) — fixes for common errors
@@ -0,0 +1,19 @@
1
+ # Claude Code
2
+
3
+ Add the server from the command line:
4
+
5
+ ```bash
6
+ claude mcp add capskip -- npx -y capskip-mcp
7
+ ```
8
+
9
+ With a custom port:
10
+
11
+ ```bash
12
+ claude mcp add capskip --env CAPSKIP_PORT=9000 -- npx -y capskip-mcp
13
+ ```
14
+
15
+ Confirm it is connected:
16
+
17
+ ```bash
18
+ claude mcp list
19
+ ```