{
  "markdown": "<div align=\"center\">\n\n# Agent Web Search\n\n<!-- mcp-name: io.github.JerryLiu369/agent-web-search -->\n\n**Agent-native web search for AI agents — aggregating model-native search and agent search providers, not traditional search engines.**\n\n**English** | [简体中文](https://github.com/JerryLiu369/agent-web-search/blob/main/README.zh-CN.md)\n\n[![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)\n[![PyPI](https://img.shields.io/pypi/v/agent-web-search-mcp.svg)](https://pypi.org/project/agent-web-search-mcp/)\n[![CI](https://github.com/JerryLiu369/agent-web-search/actions/workflows/ci.yml/badge.svg)](https://github.com/JerryLiu369/agent-web-search/actions/workflows/ci.yml)\n[![MCP 2.x](https://img.shields.io/badge/MCP-2.x-6C47FF)](https://modelcontextprotocol.io/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\n<p><strong>One-click remote MCP</strong></p>\n\n<p>\n  <a href=\"https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FJerryLiu369%2Fagent-web-search&amp;env=AGENT_WEB_SEARCH_AUTH_TOKEN\"><img alt=\"Deploy with Vercel\" src=\"https://vercel.com/button\" height=\"34\"></a>\n  <a href=\"https://railway.com/new/template?template=https%3A%2F%2Fgithub.com%2FJerryLiu369%2Fagent-web-search&amp;envs=AGENT_WEB_SEARCH_AUTH_TOKEN\"><img alt=\"Deploy on Railway\" src=\"https://railway.com/button.svg\" height=\"34\"></a>\n  <a href=\"https://render.com/deploy?repo=https://github.com/JerryLiu369/agent-web-search\"><img alt=\"Deploy to Render\" src=\"https://render.com/images/deploy-to-render-button.svg\" height=\"34\"></a>\n  <a href=\"https://zeabur.com/templates/8MQZG0?referralCode=JerryLiu369\"><img alt=\"Deploy on Zeabur\" src=\"https://zeabur.com/button.svg\" height=\"34\"></a>\n</p>\n\nWorks with **Codex CLI**, **Claude Code**, **OpenCode**, **Hermes**, ordinary\nshell scripts, Python applications, and remote Streamable HTTP MCP clients.\n\n[Use with an agent](#use-with-an-agent) · [Providers](#providers) ·\n[Shared interface](#shared-request-and-response) · [Configuration](#configuration) ·\n[Other interfaces](#other-interfaces) · [Troubleshooting](#troubleshooting) ·\n[Architecture](ARCHITECTURE.md) · [Development](#development)\n\n</div>\n\n---\n\nAgent Web Search gives an agent two ways to reach the same provider-neutral\nsearch core: a native MCP tool, or a CLI taught through a standard Agent Skill.\n\nThis is not a Google/Bing/Baidu metasearch wrapper. Traditional search\naggregation fans a keyword query out to conventional engines and merges their\nresult pages. Agent Web Search instead aggregates search capabilities built for\nagents: model-native web grounding, agent-oriented search APIs, and context-ready\nsources that accept natural-language questions and return answers, citations, or\nstructured evidence in forms an agent can use directly. DDGS is the only\nconventional search backend in the current provider set.\n\n```text\nNatural-language question\n             │\n             ▼\n        SearchEngine\n       ┌─────┼──────────────┐\n       ▼     ▼              ▼\n     DDGS  Model providers  Agent search providers\n           ARK · Gemini     Exa · Parallel · Brave\n           Grok · DeepSeek  Perplexity · Tavily · You.com\n           Codex Alpha      Zhipu Web Search\n           Zhipu Chat\n```\n\n## Why Agent Web Search\n\nTraditional search aggregation (Google/Bing/Baidu wrappers, scraped SERPs)\nsends a keyword query to conventional engines and merges result pages. Agent\nWeb Search instead aggregates **search capabilities built for agents**: one\ntool call returns structured, citation-ready evidence — or, through\nmodel-native grounding providers, a synthesized answer with explicit\ncitations. A [measured benchmark](docs/benchmark-2026-09-06.md) shows the\npractical difference: on a natural-language Chinese query asking for official\nsources, conventional SERP backends returned no government-domain results in\nthe top 5, while the grounding provider returned the 海关总署 figures with a\nworking citation.\n\n- **Agent-native by design.** The primary interface is a complete natural-language\n  question, not a thin keyword fan-out to Google, Bing, or Baidu.\n- **Model-native search backends.** ARK, Gemini, Grok, DeepSeek, Zhipu Chat\n  Search, and Codex Alpha can combine web retrieval with model-generated\n  synthesis and explicit citations.\n- **Agent search providers.** Exa, Parallel, Brave, Perplexity, Tavily, You.com,\n  and Zhipu Web Search expose search APIs intended to provide structured,\n  citation-friendly, or context-ready evidence to downstream agents.\n- **One provider-neutral contract.** Every backend is available through the same\n  MCP tool, CLI, Python API, and normalized `results`; model-backed providers may\n  also return an `answer`.\n- **Independent providers.** Selected providers run concurrently, and one\n  provider's failure never discards another provider's successful result.\n- **DDGS remains a simple fallback.** DDGS is the only conventional search\n  backend; it requires no API key and keeps the project usable without paid\n  provider credentials. Exa and Parallel are also keyless by default.\n- **No telemetry, no shared secrets.** Provider keys stay in runtime\n  environment variables; there is no shared API-key service.\n\n## Providers\n\nThe provider list is intentionally split by the kind of search capability it\nprovides. Only DDGS is a conventional search backend; the other two groups are\nbuilt around model-native grounding or agent-facing search services.\n\n> **Free, keyless defaults:** DDGS, Exa, and Parallel all work without an API\n> key. Exa and Parallel automatically use their free MCP transports until a\n> paid API key is provided.\n\n### Traditional search backend\n\n| Provider | Website | Search backend | API key | Enabled by default |\n| --- | --- | --- | --- | :---: |\n| **DDGS** | [DuckDuckGo](https://duckduckgo.com) | Conventional DuckDuckGo search | **Free · no key required** | Yes |\n\n### Model providers\n\nThese providers use a model-native search or grounding surface. Their responses\ncan include a model-generated answer together with citations or other explicit\nsearch evidence.\n\n| Provider | Website | Model-native search surface | API key | Enabled by default |\n| --- | --- | --- | --- | :---: |\n| **ARK** | [Volcengine Ark](https://www.volcengine.com/product/ark) | Responses API with Doubao web-search grounding | `ARK_API_KEY` | No |\n| **Codex Alpha** (experimental) | Alpha Search-compatible gateway | Model-backed Alpha Search surface | `AGENT_WEB_SEARCH_CODEX_ALPHA_API_KEY` | No |\n| **DeepSeek** | [DeepSeek API](https://api-docs.deepseek.com/) | Anthropic Messages API with native web search | `DEEPSEEK_API_KEY` | No |\n| **Gemini** | [Google AI](https://ai.google.dev/gemini-api/docs/google-search) | Gemini Google Search grounding | `GEMINI_API_KEY` | No |\n| **Grok** | [xAI](https://docs.x.ai/docs/guides/tools/overview) | xAI web search and X Search | `XAI_API_KEY` | No |\n| **Zhipu Chat Search** | [Zhipu AI](https://open.bigmodel.cn/) | GLM Chat Completions with native web search | `ZHIPU_CHAT_SEARCH_API_KEY` | No |\n\n### Agent search providers\n\nThese providers expose search services for agent consumption: natural-language\nqueries, structured source rows, high-signal excerpts, or citation-friendly\nmetadata rather than a conventional search-page experience.\n\n| Provider | Website | Agent-facing search surface | API key | Enabled by default |\n| --- | --- | --- | --- | :---: |\n| **Exa** | [Exa](https://exa.ai) | Semantic Search API or free MCP fallback | **Free without key** · optional `EXA_API_KEY` | Yes |\n| **Parallel** | [Parallel](https://parallel.ai) | Context-oriented search API or free MCP | **Free without key** · optional `PARALLEL_API_KEY` | Yes |\n| **Brave** | [Brave Search](https://brave.com/search/api/) | Structured Web Search API | `BRAVE_SEARCH_API_KEY` | No |\n| **Perplexity** | [Perplexity API](https://www.perplexity.ai/api-platform) | Native structured Search API | `PERPLEXITY_API_KEY` | No |\n| **Tavily** | [Tavily](https://tavily.com) | Agent-oriented Search API | `TAVILY_API_KEY` | No |\n| **You.com** | [You.com API](https://you.com/platform/api) | Unified web and news Search API | `YDC_API_KEY` | No |\n| **Zhipu Web Search** | [Zhipu AI](https://open.bigmodel.cn/) | Standalone structured Web Search API | `ZHIPU_WEB_SEARCH_API_KEY` | No |\n\nThe provider architecture is intentionally open: another search-capable\nbackend can be added without changing the MCP, Hermes, CLI, or Python-facing\ninterfaces.\n\n## Use with an agent\n\n**Requirements:** Python 3.10+. The default providers — DDGS, Exa, and\nParallel — need no API key. Choose one integration shape for your agent; both\nuse the same package and search engine. The PyPI package installs both\n`agent-web-search-mcp` and `agent-web-search` commands.\n\n### Option 1: MCP\n\nChoose MCP when the agent supports tool servers and you want typed discovery,\nprotocol-level errors, or remote access. The same `agent-web-search-mcp`\ncommand supports local stdio and stateless Streamable HTTP.\n\n#### Local stdio MCP\n\nInstall the package once:\n\n```bash\n# Recommended isolated installation\npipx install agent-web-search-mcp\n\n# Or install into the active Python environment\npython -m pip install agent-web-search-mcp\n```\n\nThen configure the MCP client to launch `agent-web-search-mcp`:\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-web-search\": {\n      \"command\": \"agent-web-search-mcp\",\n      \"args\": []\n    }\n  }\n}\n```\n\nIf `uvx` is already available, a client can run the package without a\npersistent install by using command `uvx` with args `[\"agent-web-search-mcp\"]`.\n\n<details>\n<summary><strong>Codex CLI, Claude Code, and OpenCode examples</strong></summary>\n\n```bash\n# Codex CLI\ncodex mcp add agent-web-search -- agent-web-search-mcp\n\n# Claude Code\nclaude mcp add agent-web-search -- agent-web-search-mcp\n```\n\nOpenCode:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"agent-web-search\": {\n      \"type\": \"local\",\n      \"command\": [\"agent-web-search-mcp\"],\n      \"enabled\": true\n    }\n  }\n}\n```\n\n</details>\n\n#### Remote MCP over HTTPS\n\nUse one of the deployment buttons at the top of this README, or run the same\nserver yourself:\n\n```bash\npython -c \"import secrets; print(secrets.token_urlsafe(32))\"\nexport AGENT_WEB_SEARCH_AUTH_TOKEN=\"replace-with-the-generated-token\"\nagent-web-search-mcp --transport http\n```\n\nThe server exposes authenticated `POST /mcp` and public `GET /healthz`. A\nremote MCP client connects like this:\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-web-search\": {\n      \"url\": \"https://your-deployment.example/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer your-deployment-token\"\n      }\n    }\n  }\n}\n```\n\nEvery public deployment must set `AGENT_WEB_SEARCH_AUTH_TOKEN` to at least 32\ncharacters. The server is stateless and does not create `MCP-Session-Id` values.\n\n### Option 2: CLI + Skill\n\nChoose this shape when the agent already has shell access and supports Agent\nSkills. The Skill teaches the agent how to invoke the CLI, select controls,\ninterpret `results`, and handle structured failures; no MCP configuration is\nneeded.\n\n1. Install the CLI:\n\n   ```bash\n   pipx install agent-web-search-mcp\n   # Or: python -m pip install agent-web-search-mcp\n   ```\n\n2. Install the included [`agent-web-search` Skill](https://github.com/JerryLiu369/agent-web-search/tree/main/skills/agent-web-search):\n\n   ```bash\n   npx skills add JerryLiu369/agent-web-search --skill agent-web-search\n   ```\n\n   If the agent does not use the `skills` installer, copy\n   `skills/agent-web-search` into that client's Skills directory.\n\n3. Verify the CLI, then let the agent search:\n\n   ```bash\n   agent-web-search --version\n   agent-web-search \"What changed in the latest OpenAI Codex CLI?\"\n   ```\n\nThe CLI writes one JSON document to stdout on success. If every provider fails,\nit writes the shared `all_providers_failed` JSON to stderr and exits with status\n1, so shell-capable agents can distinguish a real failure from empty results.\n\n| CLI option | MCP argument | Values | Default |\n| --- | --- | --- |\n| positional `QUERY` | `query` | 1–4,000 character natural-language question | required |\n| `--provider` (repeatable) | `providers` | enabled provider names | all enabled |\n| `--max-results` | `max_results` | 1–20 | `10` |\n| `--time-range` | `time_range` | `d`, `w`, `m`, `y` | — |\n| `--grok-search-mode` | `grok_search_mode` | `web_search`, `x_search`, `both` | `web_search` |\n\n<details>\n<summary><strong>Install the latest development version from GitHub</strong></summary>\n\n```bash\npipx install 'git+https://github.com/JerryLiu369/agent-web-search.git'\n```\n\n</details>\n\n> [!IMPORTANT]\n> Do not place API keys in shell history, source code, Git commits, screenshots,\n> or checked-in MCP configuration. Supply them through server-side or local\n> environment variables.\n\n## Shared request and response\n\nMCP exposes one tool named `web_search`; the CLI maps to the same inputs.\n\n| Argument | Type | Required | Default | Description |\n| --- | --- | :---: | --- | --- |\n| `query` | string, 1–4,000 characters | Yes | — | Complete natural-language search question |\n| `max_results` | integer, 1–20 | No | `10` | Desired maximum number of results |\n| `time_range` | `d`, `w`, `m`, `y` | No | — | Past day, week, month, or year |\n| `providers` | string array | No | All enabled | Narrow the request to enabled providers |\n| `grok_search_mode` | `web_search`, `x_search`, `both` | No | `web_search` | Available only when Grok is enabled |\n\nExample call:\n\n```json\n{\n  \"query\": \"GPU kernel generation papers from the past month\",\n  \"max_results\": 5,\n  \"time_range\": \"m\",\n  \"providers\": [\"ddgs\", \"exa\"]\n}\n```\n\nProvider selection has two levels:\n\n1. `AGENT_WEB_SEARCH_PROVIDERS` defines the provider set when the process starts.\n2. The request-level `providers` argument may narrow that set, but cannot enable\n   a provider that was disabled at startup.\n\n### Response format\n\nEach selected provider that succeeds appears under `providers`; failed\nproviders are omitted:\n\n```json\n{\n  \"query\": \"GPU kernel generation papers from the past month\",\n  \"providers\": {\n    \"ddgs\": {\n      \"results\": [\n        {\n          \"title\": \"Example result\",\n          \"url\": \"https://example.com/paper\",\n          \"description\": \"Excerpt of the matching page\",\n          \"published_at\": \"2026-08-02\"\n        }\n      ]\n    }\n  }\n}\n```\n\n| Field | Meaning |\n| --- | --- |\n| `answer` | Provider-generated prose answer, when the backend produces one; omitted otherwise |\n| `results` | Result rows: `title`, `url`, `description`, plus optional `published_at` and `author` |\n\nIf every selected provider fails, MCP returns a tool error. The CLI writes the\nsame payload to stderr and exits with status 1. Both use the stable code\n`all_providers_failed` and include per-provider diagnostics:\n\n```json\n{\n  \"error\": {\n    \"code\": \"all_providers_failed\",\n    \"message\": \"All enabled search providers failed. Check provider configuration, credentials, quotas, and network access.\",\n    \"provider_errors\": {\n      \"ddgs\": \"RuntimeError: rate limited\"\n    }\n  },\n  \"query\": \"GPU kernel generation papers from the past month\"\n}\n```\n\n## Python API\n\nThe CLI, MCP servers, and Hermes plugin are thin wrappers around\n`agent_web_search.SearchEngine`, which is the public Python API.\n`SearchRequest` accepts the same fields as the MCP tool arguments:\n\n```python\nfrom agent_web_search import SearchEngine, SearchRequest\n\nengine = SearchEngine()  # reads AGENT_WEB_SEARCH_* variables at construction\n\nresponse = engine.search(\n    SearchRequest(query=\"latest MCP spec changes\", max_results=5, time_range=\"m\")\n)\n\nfor name, provider in response.providers.items():\n    print(f\"{name}: searched={provider.searched}, results={len(provider.results)}\")\n\nif response.all_providers_failed:\n    print(response.failed_provider_errors)\n```\n\n## Configuration\n\nConfiguration is read from environment variables when the CLI, MCP server, or\nHermes plugin starts. Restart the process after changing provider settings.\nSee [.env.example](.env.example) for a commented template of every variable.\n\n### General settings\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `AGENT_WEB_SEARCH_PROVIDERS` | `ddgs,exa,parallel` | Comma-separated startup-enabled provider set |\n| `AGENT_WEB_SEARCH_TIMEOUT` | `60` | Socket timeout for a single upstream HTTP call. Multi-step providers multiply it: keyless Parallel makes up to 3 calls (worst case 3×), ARK may append a continuation call (worst case 2×), so the whole search can take up to `3 ×` this value |\n\nExample:\n\n```bash\nexport AGENT_WEB_SEARCH_PROVIDERS=\"ddgs,exa,brave\"\nexport AGENT_WEB_SEARCH_TIMEOUT=\"30\"\n```\n\n```powershell\n$env:AGENT_WEB_SEARCH_PROVIDERS = \"ddgs,exa,brave\"\n$env:AGENT_WEB_SEARCH_TIMEOUT = \"30\"\n```\n\n### HTTP transport settings\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `AGENT_WEB_SEARCH_MCP_TRANSPORT` | `stdio` | `stdio` or `http`; `--transport` may override it |\n| `AGENT_WEB_SEARCH_HTTP_HOST` | `0.0.0.0` | HTTP bind host for container deployments |\n| `AGENT_WEB_SEARCH_HTTP_PORT` | `PORT` or `8000` | HTTP bind port; explicit value overrides platform `PORT` |\n| `AGENT_WEB_SEARCH_AUTH_TOKEN` | — | Required HTTP Bearer Token, at least 32 characters |\n| `AGENT_WEB_SEARCH_ALLOW_ANONYMOUS` | `false` | Explicitly disables HTTP auth for trusted/demo environments |\n| `AGENT_WEB_SEARCH_HTTP_ALLOWED_HOSTS` | — | Optional comma-separated Host allowlist |\n| `AGENT_WEB_SEARCH_HTTP_ALLOWED_ORIGINS` | — | Optional comma-separated Origin allowlist; requires allowed hosts |\n| `AGENT_WEB_SEARCH_HTTP_LOG_LEVEL` | `info` | Uvicorn log level for the container server |\n\nHTTP settings remain environment-only; the deployment files do not introduce\na second application configuration format.\n\n### Provider settings\n\nProvider-specific settings below include the credential and model controls for\nall providers. The supported-provider overview above is grouped by capability;\nthis section is the detailed configuration reference.\n\n#### 1. DDGS\n\nDDGS uses DuckDuckGo and requires no API key or provider-specific environment\nvariables. The `ddgs` Python dependency is installed with the package.\n\n#### 2. Exa\n\nExa supports both paid and keyless modes.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `EXA_API_KEY` | No | Uses the paid Search API when present |\n| `EXA_MCP_URL` | No | Overrides the free MCP endpoint when no API key is set |\n\nWithout `EXA_API_KEY`, Exa falls back to its free MCP endpoint on a best-effort\nbasis. The paid API generally provides higher quota and reliability.\n\n#### 3. Parallel\n\nParallel returns information-dense excerpts ranked for LLM context. One\n`parallel` provider automatically selects its transport:\n\n- Without a key, it uses Parallel's free Search MCP.\n- With `PARALLEL_API_KEY`, it uses the paid Search REST API.\n\nBoth transports map `excerpts` into the common result description, so the\ncalling agent does not need to distinguish `parallel-free` from `parallel`.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `PARALLEL_API_KEY` | No | Enables the paid API; omit it to use the free MCP |\n\nParallel is enabled by default and its key is optional.\n\n#### 4. ARK (Recommended)\n\nVolcengine ARK uses model-backed search grounding through the Responses API.\nAdd `ark` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `ARK_API_KEY` | Yes | One key, or multiple comma/newline-separated keys |\n| `AGENT_WEB_SEARCH_ARK_MODELS` | No | Comma/newline-separated ARK model IDs |\n\nOne model stays fixed; multiple models are selected round-robin for successive\nrequests. When multiple ARK keys are configured, a key is selected per request.\n\n<details>\n<summary><strong>Optional Volcengine collaboration rewards information</strong></summary>\n\nAgent Web Search does not require participation in a rewards program. ARK users\nmay optionally review the official\n[Volcengine Collaboration Rewards Program](https://www.volcengine.com/docs/82379/1391869?lang=zh).\nQuota, supported models, validity periods, and data-authorization terms can\nchange. Check the official terms before opting in. Participation is not\nrequired to use Agent Web Search.\n\n</details>\n\n#### 5. Brave\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `BRAVE_SEARCH_API_KEY` | Yes | Brave Web Search API credential |\n\nAdd `brave` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\n\n#### 6. Gemini\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `GEMINI_API_KEY` | Yes | Google AI API credential |\n| `AGENT_WEB_SEARCH_GEMINI_MODELS` | No | Comma/newline-separated Gemini model IDs |\n\nGemini maps common result and time controls into best-effort prompt\nconstraints. One configured model stays fixed; multiple models are selected\nround-robin for successive requests.\n\n#### 7. Grok\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `XAI_API_KEY` | Yes | xAI API credential |\n| `AGENT_WEB_SEARCH_GROK_MODELS` | No | Comma/newline-separated Grok model IDs |\n\nOne configured model stays fixed; multiple models are selected round-robin for\nsuccessive requests.\n\nWhen Grok is enabled, the public tool schema adds `grok_search_mode`:\n\n- `web_search` searches the web.\n- `x_search` searches X with native date filters when available.\n- `both` exposes both server-side tools in one request and lets Grok choose; it\n  does not issue two independent model requests.\n\n#### 8. Codex Alpha (experimental)\n\nThe `codex_alpha` provider uses only a gateway API key and a complete endpoint\nimplementing `/v1/alpha/search`; it does not handle Codex OAuth tokens. Set the\nendpoint, key, and optional model, then add `codex_alpha` to\n`AGENT_WEB_SEARCH_PROVIDERS`:\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `AGENT_WEB_SEARCH_CODEX_ALPHA_ENDPOINT` | Yes | Complete Alpha Search endpoint URL |\n| `AGENT_WEB_SEARCH_CODEX_ALPHA_API_KEY` | Yes | Gateway Bearer API key |\n| `AGENT_WEB_SEARCH_CODEX_ALPHA_MODEL` | No | Model ID, default `gpt-5.6-luna` |\n\nThe provider sends a normal `search_query` command and returns standard web\nsearch results.\n\n#### 9. DeepSeek\n\nDeepSeek uses the official Anthropic-compatible Messages API and the native\n`web_search_20250305` server tool. It preserves the final model-generated text\nand maps only explicit `web_search_result` blocks into normalized results. A\nvalid response may therefore have an `answer` with an empty `results` list.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `DEEPSEEK_API_KEY` | Yes | DeepSeek API credential |\n| `AGENT_WEB_SEARCH_DEEPSEEK_BASE_URL` | No | Anthropic API base URL; defaults to `https://api.deepseek.com/anthropic` |\n| `AGENT_WEB_SEARCH_DEEPSEEK_MODELS` | No | Comma/newline-separated model IDs; defaults to `deepseek-v4-flash` |\n\nAdd `deepseek` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key. The\nprovider appends `/v1/messages` to the configured base URL. Multiple models are\nselected round-robin for successive requests.\n\n#### 10. Perplexity\n\nThis provider uses Perplexity's native structured Search API. It returns result\nrows rather than a Sonar-generated prose answer; OpenRouter compatibility is\nintentionally outside this provider's scope.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `PERPLEXITY_API_KEY` | Yes | Perplexity Search API credential |\n\nAdd `perplexity` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\n\n#### 11. Tavily\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `TAVILY_API_KEY` | Yes | Tavily Search API credential |\n\nAdd `tavily` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\n\n#### 12. You.com\n\nYou.com returns unified web and news sections. Agent Web Search merges both,\ndeduplicates URLs, and applies `max_results` to the combined result list.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `YDC_API_KEY` | Yes | You.com Search API credential |\n\nAdd `you` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\n\n#### 13. Zhipu Web Search\n\nZhipu Web Search uses the China standalone Web Search API and returns\nstructured search rows. It is a separate Provider from Zhipu Chat Search; the\nimplementation does not fall back between the two surfaces.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `ZHIPU_WEB_SEARCH_API_KEY` | Yes | Zhipu Web Search API credential |\n| `AGENT_WEB_SEARCH_ZHIPU_WEB_SEARCH_BASE_URL` | No | China API base URL; defaults to `https://open.bigmodel.cn` |\n\nAdd `zhipu_web_search` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\nThe Provider appends `/api/paas/v4/web_search` to the configured base URL.\n\n#### 14. Zhipu Chat Search\n\nZhipu Chat Search uses the China GLM Chat Completions API with native web\nsearch. It returns the model answer plus only explicit top-level search rows;\nURLs mentioned in answer prose are not treated as citations. It is a separate\nProvider from Zhipu Web Search and has no API/Chat fallback.\n\n| Variable | Required | Purpose |\n| --- | :---: | --- |\n| `ZHIPU_CHAT_SEARCH_API_KEY` | Yes | Zhipu Chat Search API credential |\n| `AGENT_WEB_SEARCH_ZHIPU_CHAT_BASE_URL` | No | China API base URL; defaults to `https://open.bigmodel.cn` |\n| `AGENT_WEB_SEARCH_ZHIPU_CHAT_MODELS` | No | Comma/newline-separated GLM model IDs; defaults to `glm-5.3-flash` |\n\nAdd `zhipu_chat_search` to `AGENT_WEB_SEARCH_PROVIDERS` after providing the key.\nThe Provider appends `/api/paas/v4/chat/completions` to the configured base URL.\nMultiple configured models are selected round-robin for successive requests.\n\n### Common search controls\n\nEach provider maps the shared controls to its native API when possible and\nignores unsupported controls.\n\n| Provider | `max_results` | `time_range` |\n| --- | --- | --- |\n| DDGS | Native `max_results` | Native `timelimit` |\n| Exa | Native result count | Native publish date |\n| Parallel | REST: native `max_results`; keyless MCP: client-side truncation (`results[:max_results]`) | Ignored |\n| ARK | Native `limit` | Prompt constraint |\n| Brave | Native `count` | Native `freshness` |\n| Gemini | Prompt constraint | Prompt constraint |\n| Grok | Prompt constraint | Prompt; X Search also uses native dates |\n| Codex Alpha | Local result truncation | Ignored |\n| DeepSeek | Local search-result truncation | Prompt constraint |\n| Perplexity | Native `max_results` | Native recency filter |\n| Tavily | Native `max_results` | Native `time_range` |\n| You.com | Native `count`, combined cap | Native `freshness` |\n| Zhipu Web Search | Native `count`, local deduplication and cap | Native recency filter |\n| Zhipu Chat Search | Native `count`, local deduplication and cap | Native recency filter |\n\nPrompt-based controls are best-effort and are not strict guarantees.\n\n## Other interfaces\n\n### Native Hermes plugin\n\nInstall the native plugin directly from GitHub:\n\n```bash\npip install 'ddgs>=9.0'\nhermes plugins install JerryLiu369/agent-web-search --no-enable\nhermes plugins enable agent-web-search --allow-tool-override\n```\n\nThe plugin intentionally replaces Hermes' built-in `web_search` tool, so the\nexplicit `--allow-tool-override` grant is required. Start a new Hermes session\nafter enabling it; restart the gateway when using a messaging channel.\n\nHermes can also connect through its generic MCP integration instead of the\nnative plugin.\n\n## Troubleshooting\n\n- **`all_providers_failed`** — every selected provider errored. MCP marks the\n  call as an error; the CLI writes diagnostics to stderr and exits 1. Check\n  keys, quotas, and network access. A single retry may help a transient limit.\n- **`agent-web-search` is not found** — install the PyPI package with `pipx` or\n  `pip`, then start a new shell so its scripts directory is on `PATH`.\n- **HTTP 401 `invalid_token`** — the `Authorization: Bearer …` header must\n  match `AGENT_WEB_SEARCH_AUTH_TOKEN`, which must be at least 32 characters.\n- **A provider is missing from a response** — failed providers are omitted\n  from successful responses. The Python API exposes the reasons in\n  `response.failed_provider_errors`.\n- **Provider changes have no effect** — provider settings are read once at\n  startup; restart the CLI, MCP server, or Hermes plugin after changing them.\n- **MCP client times out before the tool returns** —\n  `AGENT_WEB_SEARCH_TIMEOUT` bounds a single upstream HTTP call, not the\n  whole search. Keyless Parallel issues up to 3 calls and ARK may append a\n  continuation request, so the worst case is `3 × AGENT_WEB_SEARCH_TIMEOUT`;\n  configure your MCP client's tool timeout accordingly.\n\n## Development\n\nUsing [`uv`](https://docs.astral.sh/uv/) keeps the development environment\nisolated and reproducible:\n\n```bash\ngit clone https://github.com/JerryLiu369/agent-web-search.git\ncd agent-web-search\nuv venv\nuv pip install -e '.[dev]'\nuv run pytest -q\nuv run ruff check .\n```\n\n<details>\n<summary><strong>Standard venv + pip alternative</strong></summary>\n\n```bash\npython -m venv .venv\n# Linux/macOS: source .venv/bin/activate\n# Windows PowerShell: .venv\\Scripts\\Activate.ps1\npython -m pip install -e '.[dev]'\npytest -q\nruff check .\n```\n\n</details>\n\n[ARCHITECTURE.md](ARCHITECTURE.md) is the design source of truth, and\n[AGENTS.md](AGENTS.md) lists the non-negotiable invariants. Read both before\nchanging transports, configuration, authentication, deployment, providers, or\ntool schemas, keep stdio and HTTP behavior identical, and keep `pytest` and\n`ruff` green in the same change.\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 29434,
  "sha": "c0d7c01fad710d2d73deb14b52f6dc07219c909083cc898636adcdc4ae2d5d2a",
  "repo_slug": "jerryliu369/agent-web-search",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_jerryliu369_agent_web_search_f1dd2d58/readme"
}