by Johell1NS
A skill for AI agents: search the web with SearXNG, browse with Camofox, bypass protections with CloakBrowser. Self-hosted, free, unlimited.
# Add to your Claude Code skills
git clone https://github.com/Johell1NS/browser-searchGuides for using ai agents skills like browser-search.
browser-search is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by Johell1NS. A skill for AI agents: search the web with SearXNG, browse with Camofox, bypass protections with CloakBrowser. Self-hosted, free, unlimited. It has 62 GitHub stars.
browser-search's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/Johell1NS/browser-search" and add it to your Claude Code skills directory (see the Installation section above). browser-search ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
browser-search is primarily written in JavaScript. It is open-source under Johell1NS on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh browser-search against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
Web search and browsing for AI agents. Three tools, from lightest to most powerful: SearXNG for search, Camofox for browsing, CloakBrowser for protected sites.
| Tool | When to use | How |
|---|---|---|
| SearXNG (Docker, :8080) | Multi-source search, find URLs/info | exec + curl on :8080/search |
| Camofox (Docker, :9377) | JS-heavy pages, scraping, navigation | exec + curl on :9377 (REST API) |
| CloakBrowser (npm) | When Camofox gets blocked | exec + node <skill_dir>/scripts/cloak/cloak-fetch.mjs |
When this skill is active, it operates as a Deep Research engine:
Docker container on localhost:8080. Always the first choice for any search.
Commands:
Direct call to SearXNG REST API via curl. JSON output.
# Simple search
exec curl -s "http://localhost:8080/search?format=json&q=<query>"
# With language and category
exec curl -s "http://localhost:8080/search?format=json&q=<query>&language=en&categories=news"
# With time range (day, week, month, year)
exec curl -s "http://localhost:8080/search?format=json&q=<query>&time_range=month"
# Specific engines
exec curl -s "http://localhost:8080/search?format=json&q=<query>&engines=google,wikipedia"
# Image search
exec curl -s "http://localhost:8080/search?format=json&q=<query>&categories=images"
# Pagination
exec curl -s "http://localhost:8080/search?format=json&q=<query>&pageno=2"
# Health check
exec curl -s -o /dev/null -w "%{http_code}" "http://localhost:8080/search?format=json&q=health"
For specific engines, check the engine field in results and pass names with &engines=name1,name2.
Language strategy:
| Situation | --language |
|---|---|
| Query matches content language, general/cultural | that locale |
| Query matches content language, technical topic | en |
| Query in English | en |
| Fallback if preferred locale returns 0 results | en |
Note: If SearXNG results are already exhaustive, Camofox and CloakBrowser are not needed. Stop here.
Troubleshooting — container down:
cd <searxng-dir> && docker compose up -d
Docker container on localhost:9377. Official interface: REST API over HTTP.
Full OpenAPI spec: http://localhost:9377/docs (Swagger UI) or http://localhost:9377/openapi.json (raw).
Constants for all commands:
USER_ID="opencode-bot"
SESSION_KEY="default"
API_KEY="${CAMOFOX_API_KEY}"
The API key (Bearer) is required for POST /evaluate, POST /sessions/{userId}/cookies, DELETE /sessions/{userId}, GET /sessions/{userId}/traces, DELETE /sessions/{userId}/traces/{filename}, and POST /pressure/cleanup. POST /stop requires x-admin-key header (see below). Other endpoints work without auth.
General pattern:
POST /tabs → get tabId (+ initial snapshot)DELETE /tabs/{tabId}TabId persistence: Always keep the
tabIdbetween commands. Camofox commands must never run in isolation: create a tab, use thetabIdfor all subsequent operations, then close it.⚠️ Stale refs: After every interaction (click, scroll, navigate), refs (
e1,e2...) are regenerated. Always take a fresh snapshot before using a ref.404 error: If a command returns 404, the tab may have expired or been closed. Recreate it with
POST /tabsand resume.
# 1. Create tab and navigate → returns { tabId, url } (snapshot separate)
exec curl -s -X POST "http://localhost:9377/tabs" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"sessionKey\":\"$SESSION_KEY\",\"url\":\"<url>\"}"
# 2. Snapshot (accessibility tree with refs e1, e2, ...)
exec curl -s "http://localhost:9377/tabs/<tabId>/snapshot?userId=$USER_ID"
# Options: &includeScreenshot=true | &offset=N (pagination)
# 3. Evaluate (arbitrary JavaScript — for HTML tables, <code>, <pre>, non-ARIA divs)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/evaluate" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $API_KEY" \
-d "{\"userId\":\"$USER_ID\",\"expression\":\"<js-expression>\"}"
# 4. Click (by ref e1, e2... or CSS selector)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/click" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"ref\":\"<ref>\"}"
# 5. Type (with optional clear and submit)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/type" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"ref\":\"<ref>\",\"text\":\"<text>\"}"
# 6. Scroll (direction: down/up/left/right, optional amount in px)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/scroll" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"direction\":\"down\"}"
# 7. Navigate (URL or search macro)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/navigate" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"url\":\"<new-url>\"}"
# 8. Extract (structured data via JSON Schema + x-ref)
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/extract" \
-H 'Content-Type: application/json' \
-d "{\"userId\":\"$USER_ID\",\"schema\":{\"type\":\"object\",\"properties\":{\"field\":{\"x-ref\":\"e1\"}}}}"
# 9. Close tab
exec curl -s -X DELETE "http://localhost:9377/tabs/<tabId>?userId=$USER_ID"
# 10. Destroy session (closes all tabs — requires API key)
exec curl -s -X DELETE "http://localhost:9377/sessions/$USER_ID" \
-H "Authorization: Bearer $API_KEY"
# 11. Health check
exec curl -s "http://localhost:9377/health"
# 12. Screenshot (⚠️ returns raw PNG binary, not JSON — save to file)
exec curl -s -o /tmp/camofox_screenshot.png "http://localhost:9377/tabs/<tabId>/screenshot?userId=$USER_ID"
# 13. Stop browser (⚠️ requires CAMOFOX_ADMIN_KEY env var + x-admin-key header)
exec curl -s -X POST "http://localhost:9377/stop" \
-H 'Content-Type: application/json' \
-H "x-admin-key: $CAMOFOX_ADMIN_KEY" \
-d '{}'
Other endpoints: back, forward, refresh, press, wait, viewport, links, images, screenshot, downloads, stats, start, stop, tabs/group/{id}, sessions/{userId}/cookies, sessions/{userId}/traces, sessions/{userId}/traces/{filename}. All documented with params and body in the OpenAPI spec at http://localhost:9377/docs. Consult it when needed.
⚠️ /screenshot returns raw PNG binary (not base64 JSON) — save to file with curl -s -o file.png then read it. Don't try to parse as JSON.
Firefox's accessibility tree (snapshot) does NOT expose: HTML tables without ARIA roles, <code>, <pre>, generic divs.
Decision flow:
Always start with snapshot. If it's rich in textual content and refs are usable, you're good.
Discard the snapshot if it's dominated by iframes, ad links, cookie banners, or the noise/content ratio is unfavorable. In that case go directly to evaluate.
evaluate is the main path for extracting structured data from any page. Strategy:
document.title) to verify the page loaded.document.querySelector("h1")?.textContent).
document.querySelector(':contains(...)') causes 500 because :contains is not standard CSS. Arrow functions and :has work fine. Use standard CSS selectors.On dynamic pages (SPA, lazy content, infinite scroll): after creating the tab, use POST /tabs/{tabId}/wait on a known selector (e.g. h1) or POST /tabs/{tabId}/scroll to trigger loading before evaluating.
Readability for articles (blogs, news, Wikipedia, docs):
Use evaluate + Readability.js (Mozilla, scripts/camofox/Readability.js) to extract clean article text, removing nav, sidebar, ads, footer. ~70% token savings vs snapshot. For SEARCH/LIST pages, use snapshot instead.
On lazy-loading pages: scroll before Readability.
Command:
# Read Readability.js, build ~94KB JSON payload and inject
python3 -c "
import json
js = open('<skill_dir>/scripts/camofox/Readability.js').read()
expr = js + '; var a = new Readability(document.cloneNode(true)).parse(); JSON.stringify({title: a?.title, text: a?.textContent, excerpt: a?.excerpt, length: a?.length})'
json.dump({'userId': '$USER_ID', 'expression': expr}, open('/tmp/rb_article.json', 'w'))
"
exec curl -s -X POST "http://localhost:9377/tabs/<tabId>/evaluate" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $API_KEY" \
-d @/tmp/rb_article.json
# Output: { ok: true, result: "...{title, text, excerpt, length}..." }
# If result is null → fallback to snapshot. Otherwise use text.
Use with POST /tabs/{tabId}/navigate passing macro and query:
| Macro | Site |
|---|---|
@google_search |
|
@youtube_search |
YouTube |
@amazon_search |
Amazon |
@reddit_search |
|
@reddit_subreddit |
Subreddit |
@wikipedia_search |
Wikipedia |
@yelp_search |
Yelp |
@spotify_search |
Spotify |
@netflix_search |
Netflix |
@linkedin_search |
|
@twitter_search |
Twitter/X |
@instagram_search |
|
@tiktok_search |
TikTok |
@twitch_search |
Twitch |
# 1. Create tab
exec curl -s -X POST "http://localhost:9377/tabs" \
-H 'Content-Type: application/json' \
-d '{"userId":"opencode-bot","sessionKey":"default","url":"https://example.com"}'
# → {"tabId":"abc123","url":"https://example.com/"}
# 2. Snapshot (understand structure and refs)
exec curl -s "http://localhost:9377/tabs/abc123/snapshot?userId=opencode-bot"
# 3. If snapshot is sparse → evaluate for raw HTML
exec curl -s -X POST "http://localhost:9377/tabs/abc123/evaluate" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $CAMOFOX_API_KEY" \
-d '{"userId":"opencode-bot","expression":"document.querySelector(\"main\")?.innerHTML || document.body.innerHTML"}'
# 4. Interact: scroll, click, type...
exec curl -s -X POST "http://localhost:9377/tabs/abc123/scroll" \
-H 'Content-Type: application/json' \
-d '{"userId":"opencode-bot","direction":"down","amount":500}'
# 5. After each interaction, take new snapshot (refs change!)
exec curl -s "http://localhost:9377/tabs/abc123/snapshot?userId=opencode-bot"
# 6. Click and new snapshot
exec curl -s -X POST "http://localhost:9377/tabs/abc123/click" \
-H 'Content-Type: application/json' \
-d '{"userId":"opencode-bot","ref":"e3"}'
exec curl -s "http://localhost:9377/tabs/abc123/snapshot?userId=opencode-bot"
# 7. Structured extract
exec curl -s -X POST "http://localhost:9377/tabs/abc123/extract" \
-H 'Content-Type: application/json' \
-d '{"userId":"opencode-bot","schema":{"type":"object","properties":{"title":{"x-ref":"e1"}}}}'
# 8. Close tab
exec curl -s -X DELETE "http://localhost:9377/tabs/abc123?userId=opencode-bot"
# 9. (Optional) Cleanup session (requires API key)
exec curl -s -X DELETE "http://localhost:9377/sessions/opencode-bot" \
-H "Authorization: Bearer $CAMOFOX_API_KEY"
Troubleshooting — container down:
docker start camofox-browser
# If doesn't exist:
docker run -d --name camofox-browser --restart unless-stopped \
-p 9377:9377 \
-e CAMOFOX_API_KEY=<your-api-key> \
-e CAMOFOX_ADMIN_KEY=<your-admin-key> \
camofox-browser:latest
For sites with Cloudflare, Akamai, Kasada, DataDome, or when Camofox gets blocked.
Uses launch() from the npm package cloakbrowser.
Script: <skill_dir>/scripts/cloak/cloak-fetch.mjs
# Simple (markdown output)
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://example.com"
# Text only (no markdown header)
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://example.com" --format text
# Raw HTML
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://example.com" --format html
# With scroll for lazy loading (eBay, Amazon, reviews)
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://ebay.com/..." --scroll
# Automatic challenge detection (Cloudflare, Akamai, DataDome...)
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://protected-site.com"
# Proxy + geoip for sites that block datacenter IPs
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://..." --proxy "socks5://user:pass@proxy:1080" --geoip
# Deterministic fingerprint
exec node <skill_dir>/scripts/cloak/cloak-fetch.mjs "https://..." --seed 12345 --platform windows
# Screenshot (⚠️ writes PNG file — breaks read-only rule)
exec node <skill_dir>/scripts/cloak/cloak-script.mjs --script "<skill_dir>/scripts/cloak/scripts/screenshot.mjs"
When click, login, multi-step, or custom data extraction is needed:
exec node <skill_dir>/scripts/cloak/cloak-script.mjs \
--script "<skill_dir>/scripts/cloak/scripts/<your-script>.mjs" \
--proxy "socks5://..." --seed 12345
Full guide: <skill_dir>/scripts/cloak/guida-fetch.md
Initial setup and diagnostics for SearXNG and Camofox. See <skill_dir>/docker/setup.md when needed.
A skill for AI agents. OpenCode, Claude Code, Cursor, OpenClaw and beyond. Search the web with SearXNG, browse with Camofox, bypass protections with CloakBrowser. All self-hosted, free, unlimited.
browser-search is a SKILL — an instruction set for AI agents like OpenCode, Claude Code, Cursor, OpenClaw and others. It teaches your agent how to search and browse the web using three orchestrated open source tools.
The problem? The web is hostile to automation. Cloudflare, Akamai, DataDome and other anti-bot systems block simple requests. Modern sites use heavy JavaScript, lazy loading, and client-side rendering. One single solution is not enough.
browser-search orchestrates three open source tools into a single
search and browsing system designed for AI agents. Each tool has its role,
orchestrated by the skill with escalation logic, automatic selection,
and ready-to-use integration:
The typical flow: the agent first searches with SearXNG, then browses the results with Camofox (or CloakBrowser if the site is protected).
100% free, self-hosted, unlimited. No API keys to buy, no subscriptions, no rate limits. Everything runs on your machine, Docker and npm. Unlimited usage, zero cost.
Lightweight, runs anywhere. Built and tested on a Raspberry Pi — if it runs there, it runs everywhere. Minimal resource consumption, no heavy infrastructure needed, runs 24/7 on low-power hardware.
Search + browse in one kit. No manual integration needed. Searching and browsing are two distinct phases, both covered.
Automatic navigation escalation. If Camofox gets blocked by Cloudflare/Akamai, the agent automatically switches to CloakBrowser.
Smart performance. SearXNG for the search phase (milliseconds). Camofox and CloakBrowser are only used to browse the sites that actually need it.
Automatic agent choice. The AI agent decides which tool to use: SearXNG for initial search, Camofox for browsing, CloakBrowser if the site is protected. Zero human intervention.
Deep Research mode. The skill instructs the agent to go beyond superficial answers: explore multiple angles, cross-verify sources, cover every aspect, and never cut corners.
Fully customizable. The SKILL.md is plain text. You can edit the core rules, add your own, remove what you don't need. Adapt it to your workflow, your team, your standards.
Native stealth. CloakBrowser automatically detects Cloudflare, Akamai, DataDome, Imperva, PerimeterX, and DDoS-Guard challenges, and waits for them to resolve before extracting content.
Works with any agent. The SKILL.md is written for OpenCode, but the logic is identical for any AI agent. Same README, same package.json, everything works everywhere. Just ask your agent how to convert the skill for its environment.
┌─────────────────────────────────────────────────────────┐
│ browser-search │
│ │
│ ┌──────────────┐ │
│ │ Search │ │
│ │ │ │
│ │ SearXNG │ search engines → URLs │
│ │ (Docker) │ JSON results, fast │
│ │ :8080 │ │
│ └──────────────┘ │
│ │ │
│ │ results ready → to browse │
│ ↓ │
│ ┌─────────────────────────────────────┐ │
│ │ Browsing │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Camofox │ browser + REST │ │
│ │ │ (Docker) │ JS, click, eval │ │
│ │ │ :9377 │ │ │
│ │ └──────┬───────┘ │ │
│ │ │ │ │
│ │ │ if blocked │ │
│ │ ↓ │ │
│ │ ┌──────────────┐ │ │
│ │ │ CloakBrowser │ stealth Chromium │ │
│ │ │ (npm) │ anti-bot, proxy │ │
│ │ └──────────────┘ │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Docker container on localhost:8080. Metasearch engine that queries
Google, Wikipedia, Bing, DuckDuckGo and many others simultaneously.
JSON output with titles, snippets, and URLs.
Example:
curl -s "http://localhost:8080/search?format=json&q=largest+llm+benchmark+2026"
The agent now has a list of URLs to visit and autonomously decides whether to browse them with Camofox or CloakBrowser based on the site.
Docker container on localhost:9377. Exposes a full Firefox browser
through a REST API. The agent can create tabs, navigate, click,
scroll, execute arbitrary JavaScript, and structure data.
Includes: Mozilla's Readability.js for extracting clean articles, removing nav, sidebar, and ads (~70% token savings).
Main commands:
# Create tab and navigate
curl -s -X POST "http://localhost:9377/tabs" \
-H 'Content-Type: application/json' \
-d '{"userId":"bot","url":"https://example.com"}'
# Read snapshot (accessibility tree)
curl -s "http://localhost:9377/tabs/<tabId>/snapshot?userId=bot"
# Execute JavaScript
curl -s -X POST "http://localhost:9377/tabs/<tabId>/evaluate" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $CAMOFOX_API_KEY" \
-d '{"userId":"bot","expression":"document.title"}'
npm package based on Playwright + cloakbrowser. Launches a Chromium
browser with advanced fingerprinting to bypass Cloudflare, Akamai,
DataDome and other anti-bot systems. Automatic challenge detection
with wait and retry.
Available scripts:
cloak-fetch.mjs — universal fetch with challenge detectioncloak-script.mjs — custom Playwright script executionExample:
node scripts/cloak/cloak-fetch.mjs "https://protected-site.com"
node scripts/cloak/cloak-fetch.mjs "https://protected-site.com" --proxy socks5://... --geoip
Because speed and stealth are a tradeoff, and the right tool depends on the site.
Camofox — fast, structured, persistent. Camofox wraps Camoufox (a C++-level Firefox fork) in a REST API with an always-warm browser. After a ~1-3s cold start, every request is near-instant. Its accessibility snapshots are ~90% smaller than raw HTML, with stable element refs (e1, e2, ...) for reliable interaction. It handles the ~90% of sites that don't use advanced anti-bot protection: articles, docs, search engines, standard web pages.
CloakBrowser — stealth, anti-bot, on-demand. CloakBrowser launches a fresh Chromium instance per request (~1-3s startup each time). It uses advanced fingerprinting, proxy support, geoip, and automatic challenge detection to bypass Cloudflare, Akamai, DataDome, Imperva, PerimeterX, and DDoS-Guard. It is the last resort for the ~10% of sites that block Camofox.
Real-world numbers:
| Tool | Cloudflare standard | Cloudflare Turnstile | DataDome |
|---|---|---|---|
| Camoufox (Camofox engine) | up to ~92% [¹] | ~65-78% [¹] | 60-75% [¹] |
| Playwright Stealth | ~70-80% [¹] | ~40-55% [¹] | ~30-50% [¹] |
Camofox handles the fast path. CloakBrowser handles the edge cases. Together they cover the entire web with no gaps. The agent decides which to use.
¹ "Camoufox Vs Playwright Stealth: Complete Comparison & Alternatives (2026)" — blog.send.win ² CloakBrowser README — github.com/cloakhq/cloakbrowser ³ camoufox-pi README (cold start comparison) — github.com/MonsieurBarti/camoufox-pi ⁴ Playwright issue #4345 (launch time variability) — github.com/microsoft/playwright/issues/4345
git clone https://github.com/johell1ns/browser-search
cd browser-search
npm install
Then start the Docker containers:
# SearXNG (follow the official guide)
# https://docs.searxng.org/admin/installation-docker.html
# Camofox
docker run -d --name camofox-browser --restart unless-stopped \
-p 9377:9377 \
-e CAMOFOX_API_KEY=your-key \
camofox-browser:latest
Ask your AI agent to handle the details. Each tool has its own integrated documentation.
| Variable | Required for | Default | |---