diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0735b4d..818f32f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -103,13 +103,40 @@ jobs: - name: Build run: npm run build - name: Publish (idempotent) + # The `else` branch is wrapped because npm reports "you are not the + # trusted publisher for this package" as a 404 on the PUT: + # + # npm error 404 Not Found - PUT https://registry.npmjs.org/captchakraken-mcp + # npm error 404 The requested resource 'captchakraken-mcp@0.1.1' could + # npm error 404 not be found or you do not have permission to access it. + # + # Which reads as "the package does not exist" — and it plainly does, at + # 0.1.0, published by hand in July. That wording cost a real diagnosis on + # 2026-08-23: `captchakraken` published in the same run, from the same + # workflow, with the same OIDC, so the obvious readings (bad auth, broken + # release) were all wrong. The one true reading is the narrowest one, and + # npm will not say it. + # + # Trusted publishers are scoped to ONE package name (see the header), so + # a package first published by hand has no entry until someone adds it. + # Say so, and keep failing. run: | VER=$(node -p "require('./package.json').version") if npm view "captchakraken-mcp@$VER" version >/dev/null 2>&1; then echo "captchakraken-mcp@$VER already published — skipping." - else - npm publish --access public --provenance + exit 0 + fi + if npm publish --access public --provenance; then + exit 0 + fi + if npm view captchakraken-mcp version >/dev/null 2>&1; then + echo "::error::captchakraken-mcp EXISTS on npm ($(npm view captchakraken-mcp version)) \ + but this workflow is not its trusted publisher, which npm reports as a 404 on the PUT. \ + Fix: npmjs.com -> captchakraken-mcp -> Settings -> Trusted Publisher -> GitHub Actions, \ + repository JWriter20/CaptchaKraken, workflow publish.yml. The captchakraken entry does \ + NOT cover this package. Then re-run this job." fi + exit 1 publish-pypi: name: Publish PyPI (captchakraken) diff --git a/docs/assets/logo-card.png b/docs/assets/logo-card.png new file mode 100644 index 0000000..bb2cfec Binary files /dev/null and b/docs/assets/logo-card.png differ diff --git a/js/README.md b/js/README.md index f297709..fcbf9af 100644 --- a/js/README.md +++ b/js/README.md @@ -1,9 +1,20 @@ -# captchakraken +

+ CaptchaKraken +

-The TypeScript browser driver for [CaptchaKraken](https://github.com/JWriter20/CaptchaKraken). -Hand it a Playwright/Puppeteer `Page`; it finds the captcha, reads the grid with -a fine-tuned **Qwen3.5-9B** vision model on **vLLM**, clicks human-like, and -verifies through to a token. +

captchakraken

+ +

+ A captcha solver for browser automation.
+ The TypeScript driver for CaptchaKraken. +

+ +Hand it a Playwright or Puppeteer `Page`. It finds the captcha, reads the whole +puzzle with a fine-tuned **Qwen3.5-9B** vision model, and clicks, drags, slides +or types human-like through to a token. + +Run the model on **your own hardware**, or point it at the **hosted API** and run +nothing at all. > Full docs — demo videos, accuracy, self-hosting — live in the main repo > **[CaptchaKraken](https://github.com/JWriter20/CaptchaKraken)**. @@ -15,9 +26,9 @@ npm install captchakraken ``` The package bundles the Python engine (`captchakraken`) and, on `postinstall`, -creates a local venv with its lightweight core deps so grid detection + the vLLM -planner work out of the box. It ships **no browser** — bring your own -Playwright-compatible launcher. +creates a local venv with its lightweight core deps, so tile detection and the +inference client work out of the box. It ships **no browser** — bring your own +Playwright-compatible launcher (camoufox and patchright both work). - Skip the Python bootstrap: `CAPTCHA_KRAKEN_SKIP_PYTHON_SETUP=1` - To **self-host** the model, run the repo's `setup.sh` (installs vLLM + weights). @@ -37,6 +48,22 @@ claude mcp add captchakraken -- npx -y captchakraken-mcp `create_api_key` writes the key and the endpoint to `~/.captchakraken/credentials`, which the client reads on its own — **no environment variables needed**. +## What it solves + +| Vendor | Puzzles | +|---|---| +| **reCAPTCHA** | 3×3 and 4×4 image grids, including the dynamic re-deal | +| **hCaptcha** | Image grids, click, drag, connect-the-path, tetris-fit, animated | +| **GeeTest** v3 + v4 | Slide, icon, nine, svg, gobang, iconcrush | +| **NetEase Yidun** | Jigsaw, picture-click, icon-click | +| **Tencent, Lemin, Prosopo** | Slide, cropped-image and grid flows | +| **BotDetect, MTCaptcha, Yandex** | Distorted text — read and typed, not clicked | +| **Cloudflare Turnstile** | Via the checkbox flow (free on the hosted API) | + +**44 puzzle types**, driven end to end in CI against generated fixtures on both +the TypeScript and Python ports. Animated challenges are recorded, sliced into +keyframes and answered with the frame the action belongs to. + ## Usage ```typescript @@ -49,7 +76,7 @@ await page.goto('https://www.google.com/recaptcha/api2/demo'); // Reads VLLM_BASE_URL + CAPTCHA_KRAKEN_API_KEY from the environment. const solver = new CaptchaKrakenSolver(); -await solver.solve(page); // detect → solve grid → click → verify +await solver.solve(page); // detect → read → act → verify await browser.close(); ``` diff --git a/js/package.json b/js/package.json index 3c86b4b..eead524 100644 --- a/js/package.json +++ b/js/package.json @@ -1,7 +1,7 @@ { "name": "captchakraken", - "version": "2.6.0", - "description": "Browser-agnostic Playwright/Puppeteer captcha solver. Detects the captcha, reads the grid with a fine-tuned Qwen3.5-9B vision model on vLLM, and clicks through to a token.", + "version": "2.6.1", + "description": "Captcha solver for Playwright and Puppeteer. Finds the captcha, reads the puzzle with a fine-tuned Qwen3.5-9B vision model, and clicks, drags, slides or types through to a token — reCAPTCHA, hCaptcha, GeeTest, NetEase Yidun, Tencent, Lemin, Prosopo, Turnstile and distorted text. Hosted API or self-hosted.", "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ @@ -25,11 +25,19 @@ }, "keywords": [ "captcha", + "captcha-solver", "recaptcha", "hcaptcha", + "geetest", + "turnstile", + "yidun", + "tencent-captcha", "playwright", "puppeteer", - "automation", + "camoufox", + "browser-automation", + "scraping", + "anti-bot", "vllm", "qwen" ], diff --git a/mcp/README.md b/mcp/README.md index 5283ad7..a3842c7 100644 --- a/mcp/README.md +++ b/mcp/README.md @@ -1,8 +1,15 @@ -# captchakraken-mcp +

+ CaptchaKraken +

-The CaptchaKraken account, driven from an MCP client. It signs you in through -GitHub, mints and revokes API keys for the solving endpoint, and reads back what -you have spent. +

captchakraken-mcp

+ +

+ The CaptchaKraken account, driven from an MCP client. +

+ +It signs you in through GitHub, mints and revokes API keys for the solving +endpoint, and reads back what you have spent. **It does not solve captchas.** The key it mints is what does that, against the OpenAI-compatible endpoint at `api.captchakraken.com/v1`. diff --git a/mcp/package.json b/mcp/package.json index 1a2f431..5c8ac42 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -1,7 +1,7 @@ { "name": "captchakraken-mcp", - "version": "0.1.1", - "description": "MCP server for CaptchaKraken: sign in with GitHub, mint API keys for the Abyss model, and read your usage and spending.", + "version": "0.1.2", + "description": "MCP server for the CaptchaKraken account: sign in with GitHub, mint and revoke API keys for the captcha-solving endpoint, and read your usage and balance. Writes the key to disk so the solver needs no environment variables.", "type": "module", "author": "Jake Writer", "license": "SEE LICENSE IN LICENSE", @@ -25,7 +25,10 @@ "mcp", "model-context-protocol", "captcha", - "captchakraken" + "captchakraken", + "claude", + "api-keys", + "llm-tools" ], "bugs": { "url": "https://github.com/JWriter20/CaptchaKraken/issues" diff --git a/python/README.md b/python/README.md index 05f9fb7..524f23a 100644 --- a/python/README.md +++ b/python/README.md @@ -1,14 +1,42 @@ -# captchakraken +

+ CaptchaKraken +

-The Python engine + CLI behind [CaptchaKraken](https://github.com/JWriter20/CaptchaKraken): -OpenCV grid detection + a fine-tuned **Qwen3.5-9B** vision LoRA served on -**vLLM**. Given a screenshot of a captcha grid, it locates the tiles and returns -the click plan. Ships the `captchakraken` command. +

captchakraken

+ +

+ A captcha solver for browser automation.
+ The Python engine and CLI behind CaptchaKraken. +

+ +OpenCV tile detection plus a fine-tuned **Qwen3.5-9B** vision model. Give it a +screenshot of a captcha and it returns the plan to solve it — which tiles to +select, where to click, what to drag, how far to slide, or what text to type. +Ships the `captchakraken` command. + +Run the model on **your own hardware**, or point it at the **hosted API** and run +nothing at all. > For demo videos, accuracy numbers, the browser driver, and the full > self-hosting guide, see the main repo > **[CaptchaKraken](https://github.com/JWriter20/CaptchaKraken)**. +## What it solves + +| Vendor | Puzzles | +|---|---| +| **reCAPTCHA** | 3×3 and 4×4 image grids, including the dynamic re-deal | +| **hCaptcha** | Image grids, click, drag, connect-the-path, tetris-fit, animated | +| **GeeTest** v3 + v4 | Slide, icon, nine, svg, gobang, iconcrush | +| **NetEase Yidun** | Jigsaw, picture-click, icon-click | +| **Tencent, Lemin, Prosopo** | Slide, cropped-image and grid flows | +| **BotDetect, MTCaptcha, Yandex** | Distorted text — read and typed, not clicked | +| **Cloudflare Turnstile** | Via the checkbox flow (free on the hosted API) | + +**44 puzzle types**, driven end to end in CI against generated fixtures on both +the TypeScript and Python ports. Animated challenges are recorded, sliced into +keyframes and answered with the frame the action belongs to. + ## Install ```bash diff --git a/python/pyproject.toml b/python/pyproject.toml index 7104cba..682aeb8 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -4,8 +4,8 @@ build-backend = "hatchling.build" [project] name = "captchakraken" -version = "2.6.0" -description = "Self-hosted captcha solver: OpenCV grid detection + a fine-tuned Qwen3.5-9B vision LoRA served on vLLM." +version = "2.6.1" +description = "Captcha-solving engine and CLI: OpenCV grid detection plus a fine-tuned Qwen3.5-9B vision model, for image grids, click and drag puzzles, sliders, distorted text and animated challenges. Hosted API or self-hosted on vLLM." readme = "README.md" requires-python = ">=3.10" # Source-available, NOT GPL. The CaptchaKraken Source-Available License permits @@ -14,12 +14,26 @@ requires-python = ">=3.10" # — see LICENSE. (GPL-3.0 would wrongly permit all three.) license = { file = "LICENSE" } authors = [{ name = "Jake Writer" }] -keywords = ["captcha", "recaptcha", "hcaptcha", "vllm", "qwen", "computer-vision", "automation"] +keywords = [ + "captcha", "captcha-solver", "recaptcha", "hcaptcha", "geetest", "turnstile", + "yidun", "tencent-captcha", "playwright", "browser-automation", "scraping", + "anti-bot", "vllm", "qwen", "computer-vision", "ocr", +] classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Scientific/Engineering :: Image Recognition", + "Topic :: Internet :: WWW/HTTP :: Browsers", + "Topic :: Software Development :: Testing", "License :: Other/Proprietary License", + "Typing :: Typed", ] # Core = the lightweight CLIENT: OpenCV grid detection + the HTTP planner that @@ -55,8 +69,11 @@ dev = [ captchakraken = "captchakraken.cli:main" [project.urls] -Homepage = "https://github.com/JWriter20/CaptchaKraken" +Homepage = "https://captchakraken.com" +Documentation = "https://github.com/JWriter20/CaptchaKraken#readme" +Source = "https://github.com/JWriter20/CaptchaKraken" Issues = "https://github.com/JWriter20/CaptchaKraken/issues" +Changelog = "https://github.com/JWriter20/CaptchaKraken/blob/main/CHANGELOG.md" [tool.hatch.build.targets.wheel] packages = ["src/captchakraken"]