Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

CapMonster CAPTCHA Solver

v1.0.0

Solve CAPTCHAs (reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, image CAPTCHAs) using CapMonster Cloud API. Use when browser automation encounters CAPTCHA c...

0· 767·0 current·0 all-time
byEason Chen@easonc13

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for easonc13/capmonster.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "CapMonster CAPTCHA Solver" (easonc13/capmonster) from ClawHub.
Skill page: https://clawhub.ai/easonc13/capmonster
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Canonical install target

openclaw skills install easonc13/capmonster

ClawHub CLI

Package manager switcher

npx clawhub@latest install capmonster
Security Scan
VirusTotalVirusTotal
Suspicious
View report →
OpenClawOpenClaw
Suspicious
medium confidence
!
Purpose & Capability
The SKILL.md and included scripts clearly require a CapMonster API key (CAPMONSTER_API_KEY) to call https://api.capmonster.cloud, but the registry metadata lists no required environment variables or primary credential. That omission is inconsistent: a networked CAPTCHA-solving skill legitimately needs that API key.
Instruction Scope
Instructions stay within the expected scope (detect CAPTCHA in page DOM, extract sitekey, call CapMonster API, poll for solution, inject token). They do not instruct reading arbitrary host files or unrelated credentials. However, SKILL.md includes absolute local example paths (e.g. '/Users/eason/clawd/tools/capmonster-cloud') and references a Python client file that is not present in the bundle, which is a mismatch and could lead to the agent attempting to read local paths or fail at runtime.
Install Mechanism
There is no install spec (instruction-only), which avoids arbitrary remote downloads (low risk). But the package does include code files (JS and shell) even though no install is declared. The shell script and curl examples rely on common tools (curl, jq) — the registry declares no required binaries, so runtime dependency metadata is incomplete.
!
Credentials
Only one external credential (CapMonster API key) is needed for the described functionality, which would be proportional — but the metadata fails to declare it. Also, examples/samples embed a local sys.path insertion and reference a 'tools/capmonster-cloud/capmonster_api.py' Python client that isn't included; this mismatch increases the chance the agent will try to access unexpected local paths or that the user will mistakenly expose other files while trying to satisfy examples.
Persistence & Privilege
The skill does not request permanent or always-on presence and uses normal agent-invocation defaults. It does not attempt to modify other skills or system-wide config. No elevated persistence or privileges are requested.
What to consider before installing
This package appears to do what it claims (solve CAPTCHAs via CapMonster), but metadata and examples are inconsistent. Before installing or using it: 1) Expect to provide a CAPMONSTER_API_KEY — verify the skill metadata is updated to declare this as the primary credential. 2) Confirm required binaries (curl, jq, a JS-capable browser automation runtime, and optionally Python if you want the client) exist on the host; the registry currently lists none. 3) Inspect or remove absolute local-path examples (e.g., '/Users/eason/...') to avoid accidental local file access. 4) Note the Python client referenced in docs isn't bundled — either obtain the client from a trusted source or use only the provided scripts. 5) Consider legal/ethical implications: automated CAPTCHA solving may violate terms of service for target sites. 6) For safety, run first in an isolated environment and do not provide any other credentials. If the publisher can correct the metadata (declare CAPMONSTER_API_KEY as a required env/primary credential and list required binaries), confidence in coherence would rise.

Like a lobster shell, security has layers — review code before you run it.

latestvk97ctrwwqnyfbf68akdqevab6d816pkq
767downloads
0stars
1versions
Updated 3h ago
v1.0.0
MIT-0

CapMonster Cloud CAPTCHA Solver

Solve CAPTCHAs programmatically via CapMonster Cloud API during browser automation.

API Info

  • Base URL: https://api.capmonster.cloud
  • API Key: ${CAPMONSTER_API_KEY}
  • Docs: https://docs.capmonster.cloud/
  • Python Client: tools/capmonster-cloud/capmonster_api.py

Pricing (per 1000 solves)

TypePriceAvg Time
reCAPTCHA v2$0.6010-30s
reCAPTCHA v3$0.905-15s
hCaptcha$1.5010-30s
Cloudflare Turnstile$1.205-15s
Image CAPTCHA$0.042-5s

Quick Reference

Check Balance

curl -s -X POST https://api.capmonster.cloud/getBalance \
  -H "Content-Type: application/json" \
  -d '{"clientKey": "${CAPMONSTER_API_KEY}"}' | jq .balance

Using Python Client

import sys
sys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')
from capmonster_api import CapMonsterClient

client = CapMonsterClient("${CAPMONSTER_API_KEY}")

# Check balance
print(f"Balance: ${client.get_balance()}")

# Solve reCAPTCHA v2
token = client.solve_recaptcha_v2(
    website_url="https://example.com/page-with-captcha",
    website_key="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
)

Complete Workflow: Browser Automation + CAPTCHA Solving

Step 1: Detect CAPTCHA on Page

Take a browser snapshot and check for CAPTCHA indicators:

// Via browser action=act evaluate
browser action=act profile=chrome request={
  "kind": "evaluate",
  "fn": "(() => {
    const indicators = {
      recaptchaV2: !!document.querySelector('.g-recaptcha, [data-sitekey], iframe[src*=\"recaptcha\"]'),
      recaptchaV3: !!document.querySelector('script[src*=\"recaptcha/api.js?render=\"]'),
      hcaptcha: !!document.querySelector('.h-captcha, [data-hcaptcha-sitekey], iframe[src*=\"hcaptcha\"]'),
      turnstile: !!document.querySelector('.cf-turnstile, [data-sitekey], iframe[src*=\"turnstile\"]')
    };
    return JSON.stringify(indicators);
  })()"
}

Step 2: Extract Site Key

reCAPTCHA v2:

// Option A: From data-sitekey attribute
document.querySelector('[data-sitekey]')?.dataset.sitekey

// Option B: From iframe src
document.querySelector('iframe[src*="recaptcha"]')?.src.match(/k=([^&]+)/)?.[1]

// Option C: From grecaptcha object
window.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey

reCAPTCHA v3:

// From script src
document.querySelector('script[src*="recaptcha/api.js?render="]')?.src.match(/render=([^&]+)/)?.[1]

// Or from grecaptcha config
window.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey

hCaptcha:

document.querySelector('[data-hcaptcha-sitekey], .h-captcha[data-sitekey]')?.dataset.sitekey ||
document.querySelector('[data-hcaptcha-sitekey]')?.getAttribute('data-hcaptcha-sitekey')

Cloudflare Turnstile:

document.querySelector('.cf-turnstile[data-sitekey], [data-turnstile-sitekey]')?.dataset.sitekey

Step 3: Submit to CapMonster API

Using curl (shell):

# Create task
TASK_ID=$(curl -s -X POST https://api.capmonster.cloud/createTask \
  -H "Content-Type: application/json" \
  -d '{
    "clientKey": "${CAPMONSTER_API_KEY}",
    "task": {
      "type": "RecaptchaV2TaskProxyless",
      "websiteURL": "https://scholar.google.com/",
      "websiteKey": "SITEKEY_HERE"
    }
  }' | jq -r .taskId)

echo "Task ID: $TASK_ID"

Using Python:

import sys
sys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')
from capmonster_api import CapMonsterClient

client = CapMonsterClient("${CAPMONSTER_API_KEY}")

# For reCAPTCHA v2
token = client.solve_recaptcha_v2(
    website_url="https://scholar.google.com/",
    website_key="EXTRACTED_SITEKEY"
)

# For reCAPTCHA v3
token = client.solve_recaptcha_v3(
    website_url="https://example.com/",
    website_key="EXTRACTED_SITEKEY",
    min_score=0.7,
    page_action="submit"  # Check page source for action name
)

# For hCaptcha
token = client.solve_hcaptcha(
    website_url="https://example.com/",
    website_key="EXTRACTED_SITEKEY"
)

# For Turnstile
token = client.solve_turnstile(
    website_url="https://example.com/",
    website_key="EXTRACTED_SITEKEY"
)

Step 4: Poll for Solution

Using curl:

# Poll until ready (max 120 seconds)
for i in {1..60}; do
  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \
    -H "Content-Type: application/json" \
    -d "{\"clientKey\": \"${CAPMONSTER_API_KEY}\", \"taskId\": $TASK_ID}")
  
  STATUS=$(echo "$RESULT" | jq -r .status)
  
  if [ "$STATUS" = "ready" ]; then
    TOKEN=$(echo "$RESULT" | jq -r '.solution.gRecaptchaResponse // .solution.token')
    echo "Token: $TOKEN"
    break
  fi
  
  echo "Status: $STATUS, waiting..."
  sleep 2
done

The Python client handles polling automatically with solve_and_wait().

Step 5: Inject Solution into Page

reCAPTCHA v2/v3:

// Via browser evaluate
browser action=act profile=chrome request={
  "kind": "evaluate",
  "fn": "(() => {
    const token = 'CAPMONSTER_TOKEN_HERE';
    
    // Method 1: Set textarea value (most common)
    const textarea = document.querySelector('#g-recaptcha-response, [name=\"g-recaptcha-response\"]');
    if (textarea) {
      textarea.value = token;
      textarea.style.display = 'block';  // Some sites hide it
    }
    
    // Method 2: Also set any iframe response
    document.querySelectorAll('iframe[src*=\"recaptcha\"]').forEach(iframe => {
      try {
        const doc = iframe.contentDocument || iframe.contentWindow.document;
        const ta = doc.querySelector('#g-recaptcha-response');
        if (ta) ta.value = token;
      } catch(e) {}
    });
    
    // Method 3: Trigger callback if exists
    if (typeof ___grecaptcha_cfg !== 'undefined') {
      const clients = ___grecaptcha_cfg.clients;
      for (let cid in clients) {
        const client = clients[cid];
        // Find callback
        const callback = client?.Y?.Y?.callback || client?.Y?.callback;
        if (typeof callback === 'function') {
          callback(token);
        }
      }
    }
    
    return 'Token injected';
  })()"
}

hCaptcha:

browser action=act profile=chrome request={
  "kind": "evaluate",
  "fn": "(() => {
    const token = 'CAPMONSTER_TOKEN_HERE';
    
    // Set response textarea
    const textarea = document.querySelector('[name=\"h-captcha-response\"], [name=\"g-recaptcha-response\"]');
    if (textarea) textarea.value = token;
    
    // Trigger callback
    if (typeof hcaptcha !== 'undefined') {
      // Find widget ID
      const widget = document.querySelector('.h-captcha');
      const widgetId = widget?.dataset.hcaptchaWidgetId || 0;
      // Some sites have custom callbacks
    }
    
    return 'hCaptcha token injected';
  })()"
}

Cloudflare Turnstile:

browser action=act profile=chrome request={
  "kind": "evaluate",
  "fn": "(() => {
    const token = 'CAPMONSTER_TOKEN_HERE';
    
    // Set the hidden input
    const input = document.querySelector('[name=\"cf-turnstile-response\"]');
    if (input) input.value = token;
    
    // Also set any callback data attribute
    const container = document.querySelector('.cf-turnstile');
    if (container && container.dataset.callback) {
      const callbackName = container.dataset.callback;
      if (typeof window[callbackName] === 'function') {
        window[callbackName](token);
      }
    }
    
    return 'Turnstile token injected';
  })()"
}

Step 6: Submit the Form

After injecting the token, submit the form:

// Click submit button
browser action=act profile=chrome request={"kind":"click","ref":"submit button ref"}

// Or trigger form submission
browser action=act profile=chrome request={
  "kind": "evaluate",
  "fn": "document.querySelector('form').submit()"
}

Google Scholar Specific

Google Scholar uses invisible reCAPTCHA v2 that triggers on suspicious activity.

Detection

// Check if blocked
const isBlocked = document.body.textContent.includes('unusual traffic') ||
                  document.body.textContent.includes('我們的系統') ||
                  !!document.querySelector('iframe[src*="recaptcha"]');

Extract Site Key

// Scholar's recaptcha iframe
const iframe = document.querySelector('iframe[src*="recaptcha"]');
const sitekey = iframe?.src.match(/k=([^&]+)/)?.[1];
// Usually: 6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b

Solve and Submit

import sys
sys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')
from capmonster_api import CapMonsterClient

client = CapMonsterClient("${CAPMONSTER_API_KEY}")

# Scholar's known sitekey (may change)
token = client.solve_recaptcha_v2(
    website_url="https://scholar.google.com/scholar?q=test",
    website_key="6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b"
)

print(f"Token: {token[:50]}...")

Then inject via browser automation.


Image CAPTCHA

For traditional image CAPTCHAs (text recognition):

import base64
import sys
sys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')
from capmonster_api import CapMonsterClient

client = CapMonsterClient("${CAPMONSTER_API_KEY}")

# From file
text = client.solve_image_captcha(image_path="/tmp/captcha.png")

# From base64
with open("/tmp/captcha.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()
text = client.solve_image_captcha(image_base64=b64)

print(f"CAPTCHA text: {text}")

All-in-One Shell Script

Save as solve-recaptcha.sh:

#!/bin/bash
# Usage: ./solve-recaptcha.sh <website_url> <sitekey>

API_KEY="${CAPMONSTER_API_KEY}"
WEBSITE_URL="$1"
SITEKEY="$2"

# Create task
echo "Creating task..."
RESPONSE=$(curl -s -X POST https://api.capmonster.cloud/createTask \
  -H "Content-Type: application/json" \
  -d "{
    \"clientKey\": \"$API_KEY\",
    \"task\": {
      \"type\": \"RecaptchaV2TaskProxyless\",
      \"websiteURL\": \"$WEBSITE_URL\",
      \"websiteKey\": \"$SITEKEY\"
    }
  }")

TASK_ID=$(echo "$RESPONSE" | jq -r .taskId)
ERROR_ID=$(echo "$RESPONSE" | jq -r .errorId)

if [ "$ERROR_ID" != "0" ]; then
  echo "Error: $(echo "$RESPONSE" | jq -r .errorDescription)"
  exit 1
fi

echo "Task ID: $TASK_ID"

# Poll for result
echo "Waiting for solution..."
for i in {1..60}; do
  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \
    -H "Content-Type: application/json" \
    -d "{\"clientKey\": \"$API_KEY\", \"taskId\": $TASK_ID}")
  
  STATUS=$(echo "$RESULT" | jq -r .status)
  
  if [ "$STATUS" = "ready" ]; then
    TOKEN=$(echo "$RESULT" | jq -r '.solution.gRecaptchaResponse')
    COST=$(echo "$RESULT" | jq -r '.cost')
    echo "✅ Solved! Cost: \$$COST"
    echo ""
    echo "TOKEN:"
    echo "$TOKEN"
    exit 0
  fi
  
  printf "."
  sleep 2
done

echo ""
echo "❌ Timeout after 120 seconds"
exit 1

Troubleshooting

Token Invalid / Expired

  • Tokens expire in ~2 minutes
  • Inject and submit immediately after receiving
  • Make sure websiteURL matches the actual page URL

ERROR_CAPTCHA_UNSOLVABLE

  • Retry 2-3 times
  • Check if sitekey is correct
  • Page may have additional protections

ERROR_RECAPTCHA_TIMEOUT

  • Network issue between CapMonster and target
  • Try again, or use proxy version (RecaptchaV2Task)

Token Injected but Form Fails

  • Site may validate token server-side with IP check
  • Try using proxy version with your IP
  • Some sites need callback to be triggered

Finding the Callback

// Check grecaptcha config for callback
JSON.stringify(___grecaptcha_cfg, (k, v) => typeof v === 'function' ? '[Function]' : v, 2)

// Or check data-callback attribute
document.querySelector('[data-callback]')?.dataset.callback

Best Practices

  1. Extract sitekey fresh - Don't hardcode, sites may rotate
  2. Use correct URL - Must match the page showing CAPTCHA
  3. Inject quickly - Tokens expire in ~120 seconds
  4. Check for v3 - Some sites use v3 (invisible), need pageAction
  5. Monitor balance - Set up low-balance alerts
  6. Retry on failure - CapMonster may fail occasionally

Cost Estimation

Use CaseCAPTCHAs/dayMonthly Cost
Light (research)10~$0.18
Medium (scraping)100~$1.80
Heavy (automation)1000~$18.00

Current balance is ~$10, good for ~16,000 reCAPTCHA v2 solves.

Comments

Loading comments...