Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Binary file added docs/assets/logo-card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 36 additions & 9 deletions js/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
# captchakraken
<p align="center">
<img src="https://raw.githubusercontent.com/JWriter20/CaptchaKraken/main/docs/assets/logo-card.png" alt="CaptchaKraken" width="128" height="128">
</p>

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.
<h1 align="center">captchakraken</h1>

<p align="center">
<b>A captcha solver for browser automation.</b><br>
The TypeScript driver for <a href="https://github.com/JWriter20/CaptchaKraken">CaptchaKraken</a>.
</p>

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)**.
Expand All @@ -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).
Expand All @@ -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
Expand All @@ -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();
```
Expand Down
14 changes: 11 additions & 3 deletions js/package.json
Original file line number Diff line number Diff line change
@@ -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": [
Expand All @@ -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"
],
Expand Down
15 changes: 11 additions & 4 deletions mcp/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# captchakraken-mcp
<p align="center">
<img src="https://raw.githubusercontent.com/JWriter20/CaptchaKraken/main/docs/assets/logo-card.png" alt="CaptchaKraken" width="128" height="128">
</p>

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.
<h1 align="center">captchakraken-mcp</h1>

<p align="center">
<b>The CaptchaKraken account, driven from an MCP client.</b>
</p>

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`.
Expand Down
9 changes: 6 additions & 3 deletions mcp/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -25,7 +25,10 @@
"mcp",
"model-context-protocol",
"captcha",
"captchakraken"
"captchakraken",
"claude",
"api-keys",
"llm-tools"
],
"bugs": {
"url": "https://github.com/JWriter20/CaptchaKraken/issues"
Expand Down
38 changes: 33 additions & 5 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
# captchakraken
<p align="center">
<img src="https://raw.githubusercontent.com/JWriter20/CaptchaKraken/main/docs/assets/logo-card.png" alt="CaptchaKraken" width="128" height="128">
</p>

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.
<h1 align="center">captchakraken</h1>

<p align="center">
<b>A captcha solver for browser automation.</b><br>
The Python engine and CLI behind <a href="https://github.com/JWriter20/CaptchaKraken">CaptchaKraken</a>.
</p>

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
Expand Down
25 changes: 21 additions & 4 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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"]
Expand Down
Loading