Live web access for CLI coding agents β 8 providers, one command, automatic failover.
Quick Start Β· The SKILL Β· One-Shot Install Β· Per-Agent Setup Β· Providers Β· Commands Β· FAQ
seek is a tool for coding agents, not for humans.
You install it once. Claude Code, Cline, OpenCode, Antigravity CLI β your agent calls it on every web lookup. You never typeseekagain.
Your coding agent needs the current version of a library. The docs that changed last week. A breaking API update that happened after its training cutoff. Without real web access, it hallucinates from stale data.
So you hand it a search provider key β and then it rate-limits. Or expires. Or the agent stalls mid-task, waiting on a 401 it doesn't know how to recover from.
seek fixes this. It sits in front of 7 search/fetch/crawl providers and fails over silently. Your agent calls seek search. If Tavily is rate-limited, Exa answers. If Exa is down, Firecrawl answers. The agent sees a result, never an error.
seek search "rust async runtimes 2026"
β
ββ tavily β 401 (key expired) β next
ββ exa β 429 (rate limited) β next
ββ firecrawl β 200 β β result
The agent never knows. It called seek search. It got an answer. It kept working.
Step 1 β Install seek (one time, choose one)
# Install script β Linux / macOS
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/install.sh | sh
# install-release (ir)
ir get https://github.com/Rishang/seek
# mise
mise use -g github:Rishang/seekStep 2 β Add your provider keys
seek config init # interactive form β paste in your API keysYou need at least one key from any of the 7 supported providers. Free tiers work.
Step 3 β Wire it into your agent (easiest: just ask your agent to do it)
# Claude Code β run in terminal (one-shot; needs shell access)
claude -p "install seek from https://github.com/Rishang/seek and register its web-fetch skill" \
--permission-mode acceptEdits
# OpenCode β run in terminal
opencode run "install seek and wire it as an MCP server β ref https://github.com/Rishang/seek"
# Antigravity CLI (agy) β run in terminal (one-shot; needs shell access)
agy -p "install seek from https://github.com/Rishang/seek and configure it as an MCP server" \
--dangerously-skip-permissions
# Cline / Cursor / any MCP agent β paste in chat (no shell wrapper):
# install seek from https://github.com/Rishang/seek and add it as an MCP server
# Pi β native pi-package with auto-install
pi install git:github.com/Rishang/seekThe agent reads this README, runs the install, and wires itself up. You just supply the API keys.
β Need to do it manually? See per-agent setup.
skills/SKILL.md is a plain Markdown file you drop into your agent's skills folder. The agent reads it once and learns everything β what commands to run, when to stop, how to stay cheap. No prompting, no wrapping, no custom code required.
The file has a metadata header that agents use to discover and load it:
name: web-fetch
description: Search the web and fetch full page content via seek
(firecrawl/tavily/brave/spider). Use for research,
fact-checking, documentation lookups, or any task
requiring current web information.
seek search -o csv "<query>"
# output: title,url,snippet,published_date (one row per result)
The snippet is substantial β often several sentences, not a teaser. For many lookups the snippet already is the answer.
Step 1 β Search
seek search -o csv "<query>" β read snippets + URLs
Step 2 β Decide
Snippets answer the objective?
YES β STOP. Answer from snippets. Don't fetch.
NO β fetch the single most relevant URL.
Step 3 β Fetch (only if needed)
seek fetch "<url>" β full page as markdown
Step 4 β Stop the moment the objective is met.
First page missed β fetch the next best ONCE, then re-decide.
Never fetch a second URL "to be thorough."
The SKILL also teaches the agent smarter paths when search isn't needed:
Have the exact URL?
seek fetch "https://<host>/<path>"
# Done. No search round-trip.Know the doc site domain but not the path?
# Guess the conventional structure first (Mintlify/Docusaurus pattern)
seek fetch "https://docs.example.com/<topic>/overview"
# Real content? Done β the page's own nav exposes every sibling URL.Know the domain but not the structure?
# Fetch the index and grep β one piped command
seek fetch "https://<host>/llms.txt" | rg "<keyword>" | head -20
# Hit β fetch that URL
# Miss β fall back to seek searchIf
llms.txtreturns "omitted" / "truncated" / "pages omitted" β skip the grep, go straight toseek search.
These guards are baked in so the agent never burns your token budget:
| Rule | Why |
|---|---|
| Snippets before fetches | Every fetch is a full page of tokens |
| One page at a time | Never batch-fetch; read before getting the next |
Pipe llms.txt through rg, never dump it raw |
Indexes can be enormous |
No seek crawl unless explicitly asked |
Crawl pulls many pages β for lookups, one search + one fetch is enough |
Empty fetch β one retry max, then fall back to seek search |
Never loop fetches |
| Not for APIs or local files | Use curl / bash / read instead |
| SKILL (Markdown file) | MCP Server (seek mcp) |
|
|---|---|---|
| How the agent gets it | Reads a .md file from its skills dir |
Registered as a stdio MCP server |
| Token efficiency | Agent follows the built-in loop + guards | Agent decides when/how to call tools |
| Works with | Claude Code, Kilo Code, any skills-dir agent (incl. Pi addon) | Cline, Cursor, OpenCode, Antigravity CLI, any MCP agent |
| Setup | Drop one file | Add one JSON block |
| Recommended for | Claude Code users | Everyone else |
Both use the same seek binary, same providers, same failover underneath.
This is the fastest path. You don't need to manually copy files or edit configs. Run one command in your terminal, or paste a prompt into your agent's chat. It reads this README, runs the install, drops the skill file, and reports back. You only need to supply your provider API keys afterwards (seek config init).
claude -p "install seek from https://github.com/Rishang/seek and register its web-fetch skill so you can search the web in future tasks" \
--permission-mode acceptEditsOr start an interactive session with the same prompt: claude "install seek β¦".
Claude reads the README, runs the install script, and copies SKILL.md into ~/.claude/skills/web-fetch/ automatically.
opencode run "install seek and wire it as an MCP server β ref https://github.com/Rishang/seek/blob/main/README.md"In the Cline chat panel:
install seek from https://github.com/Rishang/seek and add it as an MCP server to my Cline config
In Cursor's composer:
install seek (https://github.com/Rishang/seek) and register it as an MCP server in my .cursor/mcp.json
agy -p "install seek from https://github.com/Rishang/seek and configure it as an MCP server" \
--dangerously-skip-permissionsOr start an interactive session with the same prompt: agy -i "install seek β¦".
If you use Pi as your agent harness, register the skill (Pi's native integration β no MCP needed):
pi -p "install seek from https://github.com/Rishang/seek and register its web-fetch skill so you can search the web in future tasks"Or start an interactive session: pi "install seek β¦".
The pattern is always the same β point the agent at this README and tell it what to do (in chat, no shell wrapper):
install seek from https://github.com/Rishang/seek and wire it up so you can search the web
Any agent that can read a URL and run shell commands can set itself up.
Prefer to wire it up yourself? Here are the exact steps per agent.
The Skill is the native integration for Claude Code. Drop it in once; Claude reads it on every session.
# Global (all projects)
mkdir -p ~/.claude/skills/web-fetch
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/skills/SKILL.md \
-o ~/.claude/skills/web-fetch/SKILL.md
# Project-only
mkdir -p .claude/skills/web-fetch
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/skills/SKILL.md \
-o .claude/skills/web-fetch/SKILL.mdThat's it. No config file, no restart. Claude picks up the skill on the next session.
seek ships as a native pi package. One install β extension + skill, everything wired automatically.
pi install git:github.com/Rishang/seekWhat you get:
- Auto-install extension β on session start, checks if
seekis on PATH. If not, prompts for one-click install (downloads the right binary for your OS/arch from GitHub releases). Non-interactive mode shows the manual install command. /seek-installcommand β manual (re)install anytime.web-fetchskill β registered automatically viaresources_discover. Invoke with/skill:web-fetchor let Pi load it when relevant.
Manual fallback β drop the skill file directly:
# Global (all projects)
mkdir -p ~/.pi/agent/skills/web-fetch
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/skills/SKILL.md \
-o ~/.pi/agent/skills/web-fetch/SKILL.md
# Project-only
mkdir -p .pi/skills/web-fetch
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/skills/SKILL.md \
-o .pi/skills/web-fetch/SKILL.mdAdd to ~/.config/opencode/config.json (or your project's opencode.json):
{
"mcp": {
"seek": {
"command": "seek",
"args": ["mcp", "--token", "${SEEK_AUTH_TOKEN}"]
}
}
}Open the Cline MCP settings (gear icon β MCP Servers) and add:
{
"seek": {
"command": "seek",
"args": ["mcp", "--token", "${SEEK_AUTH_TOKEN}"],
"disabled": false
}
}Or edit ~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json directly.
Create or edit ~/.cursor/mcp.json:
{
"mcpServers": {
"seek": {
"command": "seek",
"args": ["mcp", "--token", "${SEEK_AUTH_TOKEN}"]
}
}
}Restart Cursor. seek will appear in the available tools list.
Add to ~/.gemini/antigravity-cli/mcp_config.json (or .agents/mcp_config.json in your project):
{
"mcpServers": {
"seek": {
"command": "seek",
"args": ["mcp", "--token", "${SEEK_AUTH_TOKEN}"]
}
}
}Use /mcp inside agy to verify the server is connected.
The MCP config block is the same for every agent that speaks MCP (JSON-RPC 2.0 over stdio):
{
"mcpServers": {
"seek": {
"command": "seek",
"args": ["mcp"]
}
}
}seek mcp exposes three tools β search, fetch, crawl β with the same provider failover as the CLI. The agent sees tools, not providers.
seek serve --addr 127.0.0.1:8787 --token "$SEEK_AUTH_TOKEN"curl -s localhost:8787/search \
-H "Authorization: Bearer $TOKEN" \
-d '{"query": "latest golang release notes"}'
curl -s localhost:8787/fetch \
-H "Authorization: Bearer $TOKEN" \
-d '{"url": "https://go.dev/doc/devel/release", "format": "markdown"}'Swagger UI at GET /docs Β· OpenAPI spec at GET /openapi.json Β· Liveness at GET /healthz
β οΈ Without--token, the API is unauthenticated β anyone who can reach the port can spend your provider keys. Always set a token, or bind to loopback only.
| Hardcode one SDK | seek | |
|---|---|---|
| Provider goes down | Task fails | Silent failover to next provider |
| Rate limit hit | Task fails | Silent failover to next provider |
| Key expires | Task fails | Silent failover to next provider |
| Add a new provider | Code changes | Add one key to config |
| Agent integration | Custom glue code per agent | One skill file or seek mcp |
| Token efficiency | Raw HTML response | CSV snippets by default |
| Output format | Provider-specific | Normalized across all providers |
8 providers, one interface. Configure one or all β auto uses whatever has a key.
| Provider | search | fetch | crawl | Key env var |
|---|---|---|---|---|
| firecrawl | β | β | β | FIRECRAWL_API_KEY |
| tavily | β | β | β | TAVILY_API_KEY |
| spider.cloud | β | β | β | SPIDER_API_KEY |
| exa | β | β | β | EXA_API_KEY |
| perplexity | β | β | β | PERPLEXITY_API_KEY |
| brave | β | β | β | BRAVE_API_KEY |
| webcrawlerapi | β | β | β | WEBCRAWLERAPI_API_KEY |
| lightpanda | β | β | β | LIGHTPANDA_API_KEY |
firecrawl and lightpanda are self-hostable β set a custom host via seek config init --host name=url to point at your own instance. An env var always overrides a stored key.
Auto priority order: tavily β exa β firecrawl β spider.cloud β webcrawlerapi β lightpanda β brave β perplexity. Reorder in config.yaml to change preference; index 0 wins. perplexity is last by default since its search quality is more variable for general queries.
| Command | What it does |
|---|---|
seek search <query> |
Web search with auto-failover across providers |
seek fetch <url> |
Fetch a page as markdown, html, or json |
seek crawl <url> |
Crawl a site and return its pages |
seek mcp |
Start MCP server over stdio (JSON-RPC 2.0) |
seek serve |
Start HTTP API with Swagger at /docs |
seek config init |
Configure providers and API keys (interactive or --yes for scripting) |
seek config view |
Show current config and which keys are set |
seek version |
Print the seek version |
Global: -v, --verbose β prints debug logs including each failover, HTTP request, and MCP message to stderr.
| Command | Flags |
|---|---|
search |
-p/--provider, --start DD/MM/YYYY, --end DD/MM/YYYY, --range N, -o json|csv, --no-cache |
fetch |
-p/--provider, -f/--format markdown|html|json, --no-cache |
crawl |
-p/--provider, -o json|csv, --no-cache |
serve |
--addr host:port (default 127.0.0.1:8787), --token |
mcp |
--token |
config init |
--search, --fetch, --crawl, --format, --ttl <days>, --key name=value, --host name=url, -y/--yes |
Settings live in ~/.seek/config.yaml. API keys live in ~/.seek/provider.yaml (written 0600 β never committed, never logged).
# ~/.seek/config.yaml
config:
search:
provider: auto
fetch:
provider: auto
cache:
enabled: true
ttl: 1296000 # 15 days in seconds
store: sqlite
options:
output_format: markdown
crawl:
provider: firecrawl
providers:
priority: # index 0 = highest priority
- tavily
- exa
- firecrawl
- spider.cloud
- webcrawlerapi
- lightpanda
- braveNon-interactive setup (great for CI or dotfiles):
seek config init --key firecrawl=fc-xxx --key tavily=tvly-xxx --yesfetch and crawl results cache locally in SQLite. search always hits live. Bypass per-request with --no-cache.
| Variable | Effect |
|---|---|
<PROVIDER>_API_KEY |
Override stored key for that provider |
SEEK_AUTH_TOKEN |
Shared auth token for seek serve and seek mcp (or use --token per command) |
SEEK_CONFIG |
Path to config.yaml (default ~/.seek/config.yaml) |
SEEK_PROVIDERS |
Path to provider.yaml (default ~/.seek/provider.yaml) |
SEEK_CACHE=off |
Disable all caching globally |
SEEK_CACHE_DB |
Relocate the SQLite cache file |
SEEK_CACHE_TTL |
Global TTL override (Go duration, e.g. 72h) |
All methods drop a seek binary on your PATH.
# Pi native package (extension + skill, auto-install)
pi install git:github.com/Rishang/seek
# Install script β Linux / macOS
curl -fsSL https://raw.githubusercontent.com/Rishang/seek/main/install.sh | sh
# Pin a version or install dir
curl -fsSL .../install.sh | SEEK_VERSION=v0.1.0 SEEK_BIN_DIR=~/.local/bin sh
# mise
mise use -g github:Rishang/seek # latest
mise use -g github:Rishang/seek@0.1.0 # pinned
# install-release (ir)
ir get https://github.com/Rishang/seek
# ubi
ubi --project Rishang/seek --in ~/.local/bin
# From source (Go 1.25+)
git clone https://github.com/rishang/seek && cd seek
task build # or: cd src && go build -o ../bin/seek .
# Docker (busybox-based, ~9 MB)
docker pull rishang/seek
docker run -it --entrypoint sh rishang/seek # shell into the imageSupported targets: Linux and macOS (amd64 / arm64), Windows .zip β Releases
task build # build bin/seek
task test # go test ./...
task vet # go vet ./...
task lint # golangci-lint
task run -- search "query"All Go source lives in src/. Run task with no arguments to list every available task.
Contributions are welcome β open an issue to discuss before a large PR.
Which provider does auto pick?
The first one in providers.priority that supports the operation (search/fetch/crawl) and has a key configured. Reorder the list in config.yaml to change preference.
What if a provider isn't in my priority list?
It's still tried β appended after the listed ones. A typo in the list never silently drops a usable provider.
Do I need all 8 providers?
No. One key is enough. auto works with whatever it finds. More keys = more resilience.
Where do my API keys go?
~/.seek/provider.yaml with 0600 permissions. Never in config.yaml. Set env vars to override stored keys at runtime.
Can I self-host the search backend?
Yes β firecrawl and lightpanda are self-hostable. Set a custom host via seek config init --host firecrawl=http://your-host.
Is seek useful without an agent?
It works fine from the CLI, but the design is optimized for agents β CSV output, token-efficient snippets, skill files, MCP server. For human use, the provider UIs are probably friendlier.
MIT β Rishang