Skip to main content

searchts

A keyless web reader for AI agents. It reads the page, or it tells your agent plainly that it can't.

When Claude, Cursor or another agent fetches a web page, it often comes back with nothing: a bot wall, a page that only fills in after JavaScript runs, or a block for not looking like a browser. searchts is the reader your agent calls instead. It's open source and free, needs no API key, and works as an MCP server, a CLI or a Python library.

CI PyPI Python Downloads License: MIT

A Claude agent's fetch hits a 403 bot wall, so it routes through searchts, reads the page, and answers the question
▶ Watch the full 1-minute demo

Why it exists

I built searchts because Claude kept running into walls when I asked it to read the web for me. The trigger was a Devpost hackathon page and its terms: the page wasn't even walled, and Claude still couldn't read it.

The first versions, which I built with Claude, failed the other way. When they couldn't get a page, they handed back whatever they got, and the agent summarised a loading screen as if it were the article. So searchts has one rule above the rest: return the real page, or fail loudly and say why. It never hands your agent a fake read.

What it does

  • Reads pages your agent's own fetch can't: browser-fingerprint checks, JavaScript-only pages and some bot walls
  • Fails loudly on the walls it can't pass (login walls, DataDome, some Cloudflare setups) and says which tier failed and why
  • Reads complete ChatGPT / Claude / Gemini / Grok / Poe / DeepSeek / Perplexity / Copilot shared conversations
  • Works with Claude, Codex, and MCP agents
  • Extracts clean Markdown, ready to feed a model
  • Says when a page has more than it returned (a next page, a feed, folded text) and rebuilds search results and feeds the extractor mangles
  • Searches the web without API keys
  • Downloads a page's assets (images, fonts, palette)
  • Transcribes videos, subtitles-first

Why it's free

Paid unlockers mostly charge for pools of residential IP addresses. searchts doesn't need one: the fetch and browser tiers run on your machine, from your own connection, at personal volume. The one hosted tier, Jina Reader, is free and can be turned off. That gets it past fingerprint checks and JavaScript-only pages. It doesn't get past every wall, and the scorecard shows which ones it can't.

The unlocker

searchts reads any URL through an escalating ladder and stops at the first tier that returns real content:

  1. curl_cffi: a fetch that impersonates a real Chrome's TLS/JA3 and HTTP2 fingerprint. Beats user-agent and fingerprint filters. Fast, local, private.
  2. Jina Reader: a JavaScript-rendering relay (r.jina.ai), for pages that only fill in content after running JS. Default on — the target URL is sent to Jina's servers on this rung. Opt out with SEARCHTS_NO_JINA=1 or config jina: false (local curl + stealth only).
  3. stealth browser: an undetected headless Chromium (patchright), launched lazily only when the cheaper tiers fail, for live JS / Cloudflare managed challenges.

If no tier comes back with real content, an optional human-in-the-loop step opens a real browser so you can clear the page once and continue. That covers interactive CAPTCHAs and soft walls alike: a login page served as HTTP 200 is not a challenge, but it is still a page only a human gets past. Block detection is phrase-based (not vendor-name based), so legitimate pages that merely embed a bot-sensor script are not falsely rejected. Content is extracted to clean Markdown with trafilatura.

What it won't do. searchts isn't a wall-bypass service. Pages behind a login (LinkedIn, X), DataDome and some Cloudflare setups fail loudly, with the reason. It won't route your traffic through paid residential proxies or a keyed commercial unlocker by default, and a release never claims a site reads until it does.

Share links from AI chat apps are a special kind of hard: the conversation never appears in the page HTML as extractable text, so generic readers (and most AI agents' built-in fetch) return an empty shell or a fragment cut off mid-chat. searchts read recognizes these URLs and decodes each provider's own data channel instead, returning the complete conversation as role-labeled Markdown — keyless, no login:

Provider Share URL How it's read
ChatGPT chatgpt.com/share/…, chatgpt.com/s/… turbo-stream payload embedded in the page
Claude claude.ai/share/… keyless snapshot API (behind Cloudflare)
Gemini gemini.google.com/share/… keyless batchexecute RPC
Grok grok.com/share/…, x.com/i/grok/share/… keyless share-links API
Poe poe.com/s/… __NEXT_DATA__ payload embedded in the page
DeepSeek chat.deepseek.com/share/… stealth render, scrolled to the end
Perplexity perplexity.ai/search/…, perplexity.ai/page/… stealth render, scrolled to the end
Copilot copilot.microsoft.com/shares/…, …/shares/pages/… stealth render, scrolled to the end

The first five need no browser. The last three are JavaScript shells with nothing in the initial HTML, so those reuse the stealth tier: wait for the conversation to render, auto-scroll until the page height stops changing (list virtualization will otherwise truncate a long chat), then expand the collapsed sections before reading. The benchmark currently covers the five that read without a browser and passes all five; the three that need one are not in it yet.

ChatGPT issues two shapes: /share/<uuid> for a whole conversation, and the newer /s/<prefix>_<id> short links for a single shared turn (t_ thread, m_ message, dr_ deep research, cd_ Codex). Both are read.

Each provider is a drop-in plugin module (searchts/share_extractors/); if a provider changes its format, extraction falls back to the normal unlocker ladder instead of failing.

Install

Keep it (global isolated CLI, MCP extra included):

pipx install "searchts[mcp]"

Try it without installing (one-shot, copy-paste):

uvx --from "searchts[mcp]" searchts <verb>

venv / packaging only (not the recommended path for the CLI):

python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install "searchts[mcp]"

Stealth browser (installs into the same env as the running CLI). With uvx or uv tool, put browser in the spec itself, for example uvx --from "searchts[mcp,browser]", in every command you use, the MCP one included. Only Chromium is shared between environments:

searchts install --browser

Quickstart

searchts read https://en.wikipedia.org/wiki/Ada_Lovelace   # fetch a page as clean Markdown
searchts search "open source vector db"    # multi-provider web search (keyless by default)
searchts transcribe https://youtu.be/...   # transcript of a YouTube/TikTok/Instagram/Reddit video
searchts grab https://example.com          # download a page's assets + extract palette/fonts
searchts get https://example.com/logo.png  # download one asset (image/PDF/font/file)
searchts doctor                            # see what is configured and working

read flags: --json, --backend <tier>, --human (hand off a CAPTCHA or login wall to a real browser), --scrub (redact injection). search flags: -n <count>, --json, --provider <name>. Content goes to stdout (pipeable); status to stderr. grab flags: --out <dir>, --kinds <images,icons,css,fonts,svg>, --read (also save page.md), --max <n>, --json.

Use it from your AI agent

Add searchts to your agent in one line - as an MCP server, or as a Claude Code slash command:

Installing searchts as an MCP server with claude mcp add, or as a Claude Code slash command with searchts skill install

Two ways, both one command:

# 1) MCP: always-on read_url + web_search + fetch_asset + grab_site + get_status + transcribe
# Try / no install / Claude cannot see PATH:
claude mcp add searchts -- uvx --from "searchts[mcp]" searchts mcp serve
# Keep (after pipx install "searchts[mcp]"):
#   claude mcp add searchts -- searchts mcp serve
# Desktop / Cursor JSON: `searchts mcp install`  (or uvx the same serve command)
# First read: Wikipedia shows more than example.com, which is one short paragraph.

# 2) Slash command: type /searchts <url-or-query> in Claude Code
searchts skill install        # writes ~/.claude/commands/searchts.md

See the MCP server reference for all six tools (read_url, web_search, fetch_asset, grab_site, get_status, transcribe), their inputs and outputs, and when to use each.

Features

  • Escalating open-source unlocker: curl_cffi, then Jina Reader, then a stealth browser.
  • Multi-provider search with rank fusion: DuckDuckGo (keyless default), plus SearXNG, Exa, Brave, and Tavily when configured; results merged with reciprocal rank fusion and de-duplicated.
  • Video transcription: yt-dlp audio plus Whisper for YouTube, TikTok, Instagram, and Reddit videos.
  • Asset + design grabber: searchts grab <url> downloads a page's images/icons/css/fonts and extracts a color palette plus the fonts in use; searchts get <url> pulls a single asset. Both go through the same escalating unlock ladder, so they work on fingerprint-gated CDNs, not just open ones.
  • Prompt-injection scrubbing: strips invisible/bidi characters, flags injection indicators, optional redaction, so untrusted page content is safer to feed a model.
  • Per-domain backend memory: remembers which tier worked per domain and tries it first (SEARCHTS_NO_MEMORY=1 to disable).
  • Jina opt-out: the JS-render relay is on by default; SEARCHTS_NO_JINA=1 (or jina: false in ~/.searchts config) skips it so URLs never hit r.jina.ai.
  • Surfaces: a CLI, an MCP server (read_url, web_search, fetch_asset, grab_site, get_status, transcribe), and a Python library.

Use as a library

from searchts import unlocker
r = unlocker.fetch("https://example.com")
print(r.backend, r.status, r.text)

from searchts.search import search
for hit in search("open source vector db", max_results=5):
    print(hit.title, hit.url)

Does it actually work?

Rather than take our word for it, searchts ships a reproducible two-suite benchmark: it runs the unlocker over two page sets and reports how many it read — keyless — and which tier carried each.

  • Smoke — a small public page set (control, open docs, AI-chat share links). A regression canary, not evidence about hard bot-walls.
  • Walled — real vendors that restrict bots (Reddit, LinkedIn login wall, a Cloudflare/DataDome-class site, X, Booking). A short body under the unlocker's minimum-content threshold is a fail, not a pass; expected walled failures are reported honestly, not papered over with 100%.

These two are reported separately on purpose — the smoke number is not "does it work on walls." See benchmarks/README.md.

python -m benchmarks.run                       # both suites, print a scorecard
python -m benchmarks.run --suite walled       # the real walled pass rate only
python -m benchmarks.run --out docs/          # write docs/scorecard.md + results.json

Latest run: docs/scorecard.md. Add your own targets — see benchmarks/README.md.

The numbers only mean something from a residential connection: a datacenter IP (or a VPN that reshapes your TLS fingerprint) blocks the fast curl_cffi tier more than a real user sees.

How it works, and its limits

  • It runs from your own residential IP at personal volume, which is why it needs no paid proxy pool. It is a personal-grade research tool, not a mass-scraping system.
  • Interactive CAPTCHAs (DataDome / Turnstile press-and-hold) and login walls are the honest ceiling. Use --human for those.
  • Some platforms (notably Instagram, and YouTube in 2026) may need your browser cookies or fail intermittently; that is platform-side.
  • Anti-bot systems evolve; this is an arms race and the techniques may need occasional updates. Respect each site's terms of service and use responsibly.

Configuration

Search works with no keys (DuckDuckGo). Everything else is optional, via searchts configure or a .env (see .env.example):

  • Search providers: Exa, Brave, Tavily API keys, or a self-hosted SEARXNG_URL, for more and better results.
  • Transcription: a Groq or OpenAI (Whisper) key, plus ffmpeg and yt-dlp. Login-gated video: searchts transcribe URL --cookies-from-browser chrome (opt-in; never used by read).
  • GitHub token for higher rate limits.

Run searchts doctor to check what is configured and working.

Optional integrations

The core is read / search / transcribe. Every searchts read goes through unlocker.fetch — there is no per-platform router. searchts doctor only probes whether optional CLIs (gh, twitter-cli, opencli, mcporter) are on PATH and authenticated. Presence is not a claim that searchts reads those sites through those CLIs.

Roadmap

See ROADMAP.md for where searchts is headed — and what's deliberately out of scope.

Credits

searchts builds on and extends Agent-Reach (MIT), reusing its channel, installer, and diagnostics architecture. The escalating open-source unlocker, multi-provider search with rank fusion, prompt-injection scrubbing, per-domain backend memory, the human-in-the-loop CAPTCHA flow, the video transcript channels, the read_url / web_search MCP tools, and the read / search CLI commands are additions in searchts. Thanks to the original authors.

License

MIT. See LICENSE. Original portions Copyright (c) 2025 Agent Eyes; modifications and additions Copyright (c) 2026 capad-xyz.


Built by capad. Questions or feedback: open an issue or email oss@capad.fyi.

Fun fact: "searchts" doesn't officially abbreviate anything. Off the record, it stands for "search this shit".

Metadata

Release files for searchts 0.13.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for searchts 0.13.1
File Size Uploaded
searchts-0.13.1.tar.gz 2.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for searchts 0.13.1
File Interpreter ABI Platform
searchts-0.13.1-py3-none-any.whl Python 3 none any Details

Total release size: 2.3 MB

Release files / searchts-0.13.1.tar.gz

Download URL searchts-0.13.1.tar.gz
Size 2.1 MB
Tags Source
SHA-256 checksum
How to use checksums
4d5f0b87701e99b2187bf49813dd1ad00ffa22d7531b47b67a304d147a23f323
BLAKE2b-256 checksum
How to use checksums
de8ec0d7651c9f80a1c1e4d23619fb9d07fcee6f8830c3f09d0bf1b26fa7bbf4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / searchts-0.13.1-py3-none-any.whl

Download URL searchts-0.13.1-py3-none-any.whl
Size 193.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
da6bd8520005fe59bd84629654253a509b14968bfeee67d709de9bed6e47761e
BLAKE2b-256 checksum
How to use checksums
fce9b7076f1d84d1a745296ac6cbd6f058857730571e291ff784c9e4606676d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.13.1 This release

2 release files

0.12.0

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page