简体中文 | English
CLI-first, skill-driven web research for AI agents and terminal users. smart-search gives AI tools one reproducible command layer for live search, source discovery, page fetching, site mapping, provider diagnostics, and offline Deep Research planning.
smart-search is not an MCP server. It is a normal CLI that AI agents can call through a skill:
smart-search search "latest OpenAI Responses API changes" --format json
smart-search fetch "https://example.com/article" --format markdown
smart-search deep "Compare Responses API web_search with Chat Completions search" --format jsonThe current architecture has two layers:
| Layer | Responsibility |
|---|---|
| CLI executor | Runs deterministic commands, provider routing, fallback, JSON/Markdown output, local config, smoke/regression checks |
| Skill / AI orchestration | Infers user intent, chooses normal search vs Deep Research, executes planned CLI steps, writes final source-backed answers |
Default smart-search search stays fast and live. smart-search deep is the explicit offline Deep Research planner. It does not call providers, run doctor, or fetch pages by default; it emits a research_plan that an AI agent or user can execute step by step.
Stable channel:
npm install -g @konbakuyomu/smart-search@latest
smart-search --version
smart-search setupTest channel:
npm install -g @konbakuyomu/smart-search@next
smart-search --versionThe npm package creates an isolated Python runtime during install. You still use the single smart-search command.
Prerequisites:
- Node.js / npm.
- Python 3.10 or newer available as
python,python3, orpy -3on Windows.
- Configure providers:
smart-search setup
smart-search doctor --format json- If OpenAI-compatible
searchhangs or times out, generate the short troubleshooting report:
smart-search doctor --format markdown
smart-search diagnose openai-compatible --format markdown- Run a normal live search:
smart-search search "today's important AI news" --validation balanced --extra-sources 2 --format json- Fetch exact page evidence:
smart-search fetch "https://example.com/source" --format markdown --output evidence.md- Plan Deep Research:
smart-search deep "Deep research recent Bitcoin market movement" --budget standard --format json- Install the skill for AI tools when setup prompts you, or explicitly:
smart-search setup --non-interactive --install-skills codex,claude,cursor,hermesSkill installation writes the bundled smart-search-cli skill into user-level tool directories such as
~/.codex/skills, ~/.claude/skills, ~/.cursor/skills, and ~/.hermes/skills. It does not initialize
Trellis, hooks, agents, or commands. --skills-root PATH is only an advanced override for portable or test installs.
- After upgrading the CLI, refresh the installed global skill:
smart-search skills status --targets codex --format json
smart-search skills update --targets codex --format jsonsetup --install-skills remains available for first-time setup. For routine synchronization after package updates, use
skills status and skills update; they only inspect or overwrite the managed smart-search-cli files and do not change
provider keys or create Trellis/hooks/agents/commands.
| Capability | Main commands | Providers | Role |
|---|---|---|---|
main_search |
search |
xAI Responses, OpenAI-compatible Chat Completions | Broad answer generation and synthesis |
docs_search |
context7-library, context7-docs, exa-search |
Context7, Exa | Official docs, SDKs, APIs, framework/library evidence |
web_search |
zhipu-search, intent-routed reinforcement inside search |
Zhipu, Tavily, Firecrawl | Chinese, domestic, current, domain-filtered, or supplementary web discovery |
web_fetch |
fetch |
Jina Reader, Tavily, Firecrawl | Exact URL content extraction for evidence |
vertical_search |
anysearch-domains, anysearch-search, anysearch-extract, anysearch-batch |
AnySearch (experimental) | Acceptance testing for structured vertical domains such as CVE, finance, legal, academic, and code/docs |
site_map |
map |
Tavily | Site/documentation structure discovery |
deep_planner |
deep / dr |
Local planner only | Offline plan generation; no provider call by default |
Fallback is same-capability only:
| Capability | Fallback chain |
|---|---|
main_search |
xAI Responses -> OpenAI-compatible |
docs_search |
Context7 for library/API/docs intent; Exa for official domains, papers, product pages, and trusted-site discovery |
web_search |
Zhipu -> Tavily -> Firecrawl |
web_fetch |
Jina Reader -> Tavily -> Firecrawl |
AnySearch is intentionally not part of the web_search fallback chain and is not required by the standard minimum profile. Use its explicit commands for acceptance and boundary testing before promoting any vertical domain into a future route.
The CLI exposes observability fields such as routing_decision, provider_attempts, providers_used, fallback_used, primary_sources, extra_sources, and source_warning.
extra_sources are discovery candidates. For high-risk claims, news, policy, finance, health, selection decisions, and serious reviews, fetch key pages first and cite fetched text rather than treating a broad search answer as proof.
Routing rule of thumb: start with search for broad discovery and synthesis; use Zhipu for Chinese, domestic, policy, announcements, and current-news searches; use Context7 first for library/API/framework docs; use Exa for official domains, papers, product pages, trusted sites, and low-noise discovery; use Tavily/Firecrawl through search --extra-sources for horizontal candidates and through fetch for page evidence; use AnySearch only when you explicitly need experimental vertical-domain search.
Use normal search when you want a fast answer:
smart-search search "React useEffect cleanup docs" --format jsonUse Deep Research when you want planning, decomposition, cross-checking, or strict evidence:
smart-search deep "OpenAI Responses API web_search vs Chat Completions search: which should I use?" --budget deep --format json
smart-search dr "https://example.com/source" --format jsonDeep Research output includes:
mode="deep_research"andquery_mode="deep";intent_signals, such as recency, docs/API intent, known URL, claim risk, source authority, and cross-validation need;decomposition, with 1-6 subquestions depending on budget and difficulty;capability_plan, choosing from existing CLI blocks;steps[], each withtool,purpose,command,output_path, andsubquestion_id;evidence_policy="fetch_before_claim";gap_check, which fetches missing evidence or downgrades unsupported claims.usage_boundary, which explains thatsearchis live,deepis offline planning, and execution happens through planned commands.
Deep Research is not a fixed topic recipe system. Market research, product comparison, technical docs, news or policy, claim verification, and URL-first prompts are examples of user language, not required schema enums.
Allowed planned tools are:
search, exa-search, exa-similar, zhipu-search, context7-library, context7-docs, fetch, map
doctor is preflight, not a research step. smart-search deep itself is offline; live research starts when an agent or user executes steps[].command.
Good user-facing smoke prompts:
smart-search deep "深度搜索一下最近的比特币行情" --format json
smart-search deep "OpenAI Responses API web_search 和 Chat Completions 联网搜索怎么选" --budget deep --format json
smart-search deep "帮我核验这个说法是真是假:某某工具已经完全替代 Tavily 做 AI 搜索了" --format json
smart-search deep "https://example.com/source" --format jsonUse smart-search setup for normal configuration. Environment variables remain supported for CI and advanced users.
| Provider / route | Used for | Main config keys | Official docs | Key / dashboard |
|---|---|---|---|---|
| xAI Responses API | Primary live search with web_search,x_search tools |
XAI_API_KEY, XAI_API_URL, XAI_MODEL, XAI_TOOLS |
docs.x.ai | xAI API keys |
| OpenAI-compatible Chat Completions | Primary search through OpenAI or a compatible relay; no xAI search tools are sent here | OPENAI_COMPATIBLE_API_URL, OPENAI_COMPATIBLE_API_KEY, OPENAI_COMPATIBLE_MODEL, OPENAI_COMPATIBLE_STREAM |
OpenAI platform docs | OpenAI API keys or your relay provider |
| Exa | Low-noise official docs, API, paper, product, trusted-page discovery | EXA_API_KEY |
Exa docs | Exa API keys |
| Context7 | SDK, library, framework, and API documentation fallback | CONTEXT7_API_KEY, CONTEXT7_BASE_URL |
Context7 docs | Context7 |
| Zhipu Web Search API | Chinese, domestic, current, or domain-filtered web discovery | ZHIPU_API_KEY, ZHIPU_API_URL, ZHIPU_SEARCH_ENGINE |
Zhipu web search docs | Zhipu API keys |
| Jina Reader | Default URL fetch; anonymous basic mode works without a key, readerlm-v2 requires JINA_API_KEY and explicit JINA_RESPOND_WITH=readerlm-v2 |
JINA_API_KEY, JINA_READER_API_URL, JINA_RESPOND_WITH |
Jina Reader API | Jina API keys |
| Tavily | Extra web sources, URL fetch fallback, and site map | TAVILY_API_URL, TAVILY_API_KEY |
Tavily docs | Tavily app |
| Firecrawl | Fetch fallback and supplementary web sources | FIRECRAWL_API_URL, FIRECRAWL_API_KEY |
Firecrawl docs | Firecrawl API keys |
| AnySearch | Experimental vertical search acceptance surface; not a default fallback | ANYSEARCH_API_URL, ANYSEARCH_API_KEY, ANYSEARCH_TIMEOUT_SECONDS |
Provider documentation | AnySearch dashboard / provider console |
Important boundaries:
- xAI official live search uses the Responses API
/responsesroute throughXAI_*. Compatible relays and gateways use Chat Completions/chat/completionsthroughOPENAI_COMPATIBLE_*. OPENAI_COMPATIBLE_STREAM=trueorsmart-search search --streamsetsstream=trueonly for OpenAI-compatiblesearchand provider-sidefetchcalls. It is a relay compatibility switch for long requests and does not change xAI Responses behavior, URL description, or source ranking.- Legacy
SMART_SEARCH_API_URL,SMART_SEARCH_API_KEY,SMART_SEARCH_API_MODE,SMART_SEARCH_MODEL, andSMART_SEARCH_XAI_TOOLSare not supported config keys. UseXAI_*orOPENAI_COMPATIBLE_*explicitly. - Do not force xAI
web_search/x_searchtools or legacysearch_parametersinto the OpenAI-compatible Chat Completions route. - Zhipu support is the Web Search API route, not Zhipu Chat Completions
tools=[web_search], not Search Agent, and not the MCP Server. ZHIPU_SEARCH_ENGINEdefaults tosearch_std. Supported official values includesearch_std,search_pro,search_pro_sogou, andsearch_pro_quark; custom values remain allowed for future services.TAVILY_API_URLaffects Tavily only. It does not proxy Zhipu. For Tavily Hikari / pooled endpoints, usehttps://<host>/api/tavily; setup normalizes root-host or/mcpinputs to that REST base.FIRECRAWL_API_URLdefaults tohttps://api.firecrawl.dev/v2.
Jina Reader notes:
-
Basic
r.jina.aifetch works anonymously and is the default firstweb_fetchattempt. -
JINA_API_KEYraises Jina rate limits but does not automatically enable model-based conversion. -
JINA_RESPOND_WITH=readerlm-v2opts into ReaderLM-v2. This requiresJINA_API_KEY, can be slower and more costly, and is intended for explicit high-quality conversion experiments rather than default evidence fetching. -
AnySearch uses JSON-RPC 2.0
tools/callathttps://api.anysearch.com/mcpby default. It allows anonymous calls when no key is configured, but authenticated calls sendAuthorization: Bearer .... HTTP 200 responses withresult.isError=trueare treated as provider errors, not as successful evidence.
Non-interactive setup example:
smart-search setup --non-interactive `
--xai-api-key "your-xai-key" `
--xai-model "grok-4-fast" `
--openai-compatible-api-url "https://api.openai.com/v1" `
--openai-compatible-api-key "your-openai-or-relay-key" `
--openai-compatible-model "gpt-4.1" `
--openai-compatible-stream "false" `
--validation-level "balanced" `
--fallback-mode "auto" `
--minimum-profile "standard" `
--exa-key "your-exa-key" `
--context7-key "your-context7-key" `
--zhipu-key "your-zhipu-key" `
--zhipu-api-url "https://open.bigmodel.cn/api" `
--zhipu-search-engine "search_pro_sogou" `
--jina-reader-api-url "https://r.jina.ai" `
--jina-key "optional-jina-key" `
--jina-respond-with "" `
--tavily-api-url "https://api.tavily.com" `
--tavily-key "your-tavily-key" `
--firecrawl-api-url "https://api.firecrawl.dev/v2" `
--firecrawl-key "your-firecrawl-key"Minimum profile defaults to standard, requiring at least:
- one
main_searchprovider: xAI Responses or OpenAI-compatible; - one
docs_searchprovider: Exa or Context7; - one
web_fetchprovider: Jina Reader, Tavily, or Firecrawl. Jina Reader basic mode is available without an API key, soweb_fetchcan be satisfied by default unless you disable the standard minimum profile for experiments.
Missing required capabilities fail closed with a configuration error. Use SMART_SEARCH_MINIMUM_PROFILE=off only for local experiments.
Experimental AnySearch configuration is optional and does not satisfy or change the standard minimum profile:
smart-search setup --non-interactive --anysearch-api-url "https://api.anysearch.com/mcp" --anysearch-key "your-anysearch-key"
smart-search anysearch-domains security --format json
smart-search anysearch-search "CVE-2024-3094" --domain security.cve --max-results 3 --format json
smart-search anysearch-extract "https://example.com/source" --format json
smart-search anysearch-batch "AAPL" "RAG papers" --max-results 2 --format jsonFor vertical domains, the dotted shorthand security.cve is accepted by the CLI and sent to AnySearch as domain=security plus sub_domain=cve. You can also pass the split form explicitly with --domain security --sub-domain cve.
Local config path:
- Windows default:
%LOCALAPPDATA%\smart-search\config.json. - Linux/macOS default:
~/.config/smart-search/config.json. SMART_SEARCH_CONFIG_DIRis an advanced override for CI, containers, sandboxes, or portable installs.- Earlier Windows source builds defaulted to
~\.config\smart-search\config.json, while some installs were already pinned to%LOCALAPPDATA%\smart-searchthroughSMART_SEARCH_CONFIG_DIR. If the new Windows default file is missing but the old home config exists, Smart Search reads the old file aslegacy_windows_homeso upgrades do not lose configuration.doctorreports the active path, default path, old home path,SMART_SEARCH_CONFIG_DIR, and whether that override merely matches the current default.
Provider timeouts:
TAVILY_TIMEOUT_SECONDScontrols the Tavilydoctorconnectivity check timeout and defaults to30.ANYSEARCH_TIMEOUT_SECONDScontrols experimental AnySearch JSON-RPC calls and defaults to30.- Raise it for slower Tavily Hikari / pooled / community endpoints before treating the provider as unhealthy.
| Command | Alias | Purpose |
|---|---|---|
search |
s |
Fast live search and broad synthesis |
deep |
dr |
Offline Deep Research plan |
fetch |
f |
Fetch one URL as JSON, Markdown, or content |
map |
m |
Map a website structure |
exa-search |
exa, x |
Exa source discovery |
exa-similar |
xs |
Similar pages from one URL |
zhipu-search |
z, zp |
Zhipu Web Search API |
anysearch-domains |
as-domains |
Experimental AnySearch domain discovery |
anysearch-search |
as-search, as |
Experimental AnySearch vertical/general search |
anysearch-extract |
as-extract |
Experimental AnySearch URL extraction |
anysearch-batch |
as-batch |
Experimental AnySearch batch search, up to 5 queries |
context7-library |
c7, ctx7 |
Resolve Context7 library candidates |
context7-docs |
c7d, c7docs, ctx7-docs |
Fetch Context7 docs |
doctor |
d |
Masked config and connectivity check |
diagnose |
diag |
Focused OpenAI-compatible troubleshooting report |
setup |
init |
Interactive or scripted setup |
config |
cfg |
Local config read/write |
model |
mdl |
Show explicit provider model settings; use config set XAI_MODEL or OPENAI_COMPATIBLE_MODEL to change them |
smoke |
sm |
Provider routing smoke tests |
regression |
reg |
Offline regression checks |
Useful examples:
smart-search search "query" --validation balanced --extra-sources 3 --timeout 90 --format json --output result.json
smart-search search "query" --stream --format json
smart-search search "query" --no-stream --format json
smart-search search "nba report" --format content
smart-search exa-search "OpenAI Responses API documentation" --include-domains platform.openai.com developers.openai.com --num-results 5 --include-text --format json
smart-search context7-library "react" "hooks" --format json
smart-search context7-docs "/facebook/react" "useEffect cleanup" --format json
smart-search zhipu-search "today China AI news" --search-engine search_pro_sogou --count 5 --format json
smart-search anysearch-search "CVE-2024-3094" --domain security.cve --max-results 3 --format json
smart-search anysearch-extract "https://example.com/source" --format json
smart-search exa-similar "https://example.com/source" --num-results 5 --format json
smart-search fetch "https://example.com/source" --format markdown --output page.md
smart-search map "https://docs.example.com" --instructions "Find API reference pages" --max-depth 1 --limit 50 --format json
smart-search doctor --format markdown
smart-search diagnose openai-compatible --format markdown
smart-search smoke --mock --format json
smart-search regressionUse JSON for agents and scripts:
smart-search search "query" --format json
smart-search doctor --format jsonUse Markdown for human-readable reports, detailed diagnostics, source lists, and fetched page text:
smart-search doctor --format markdown
smart-search diagnose openai-compatible --format markdown
smart-search smoke --mock --format markdown
smart-search exa-search "OpenAI Responses API documentation" --format markdown
smart-search fetch "https://example.com" --format markdownUse content for compact terminal reading:
smart-search search "nba report" --format content
smart-search doctor --format contentcontent is intentionally brief. Use doctor --format markdown for general human troubleshooting, diagnose openai-compatible --format markdown for OpenAI-compatible search hangs/timeouts, and JSON formats for complete machine-readable contracts.
Save multi-source evidence under a stable folder:
smart-search exa-search "Reuters Iran Hormuz latest" --format json --output C:\tmp\smart-search-evidence\iran-hormuz\01-exa.json
smart-search fetch "https://example.com/source" --format markdown --output C:\tmp\smart-search-evidence\iran-hormuz\02-fetch.mdFor claim-level evidence:
- Discover candidate URLs with
search,exa-search,zhipu-search, orexa-similar. - Fetch exact URLs with
fetch. - Cite fetched text in the final answer.
- Unsupported key claims must be fetched or downgraded to unverified candidates.
If doctor reports config_error:
smart-search setup
smart-search config list --format json
smart-search doctor --format markdownIf OpenAI-compatible search hangs or times out after doctor passes:
smart-search doctor --format markdown
smart-search diagnose openai-compatible --format markdownThe diagnose report masks the API key and says whether the problem is missing config, the upstream/relay hanging on the real Smart Search prompt, or a stream/no-stream compatibility mismatch.
If search is slow:
- reduce
--extra-sources; - split broad questions into smaller queries;
- use
exa-searchorzhipu-searchfor source discovery, thenfetchkey pages.
If installed CLI health is uncertain:
smart-search --help
smart-search --version
smart-search regression
smart-search smoke --mock --format jsonOn Windows npm/mise installs, verify non-ASCII JSON piping:
smart-search deep "深度搜索一下最近的比特币行情" --format json | ConvertFrom-Json.\.venv\Scripts\python.exe -m compileall -q src tests
.\.venv\Scripts\python.exe -m pytest tests -q
.\.venv\Scripts\python.exe -m smart_search.cli regression
.\.venv\Scripts\python.exe -m smart_search.cli smoke --mock --format json
npm test
npm pack --dry-runThis stable patch release moves the tested 0.1.13-beta.4 CLI and bundled skill contract into npm latest.
- Fixes GitHub issue #7: npm
latestnow includes thesmart-search skillscommand expected by the newer installedsmart-search-cliskill. smart-search skills statusreports whether installed user-level skills are missing, stale, up to date, or contain extra files without writing anything.smart-search skills updaterefreshes only the managed bundledsmart-search-clifiles for selected AI-tool targets after a CLI upgrade.smart-search diagnose openai-compatible --format markdownproduces a focused, copy-pasteable troubleshooting report for OpenAI-compatible search hangs/timeouts.- Docs/API routing now prefers Context7 for library/framework documentation and keeps Exa for official domains, papers, product pages, and trusted-site discovery.
- README, bundled skill assets, release notes, and tests now document and verify the exact stable package behavior.
Stable releases use Git tags and npm latest:
git tag v0.1.14
git push origin v0.1.14Test releases use npm prereleases and do not move latest. A push to main publishes the next <package.json version>-beta.N version under npm dist-tag next; N resets for each stable base version. To avoid publishing an unwanted beta for a stable bump, the chore(release): bump version to X.Y.Z branch commit is skipped by the workflow and the matching vX.Y.Z tag publishes npm latest. For example, after 0.1.10-beta.1 and 0.1.10-beta.2, the next main publish is 0.1.10-beta.3.
GitHub Actions also supports manual backfill for historical test builds through workflow_dispatch. Use an explicit target_ref plus an exact version such as 0.1.9-beta.1, and publish it with a non-latest tag such as backfill. npm versions are immutable: old *-dev.* packages cannot be renamed in place, only superseded by new *-beta.N packages and optionally deprecated later with npm owner credentials.
Stable GitHub releases read optional body text from .github/releases/vX.Y.Z.md and append npm package, dist-tag, and workflow-run metadata automatically. Add that file before tagging a stable version so the GitHub Release page explains what changed instead of only listing package metadata.
Release closeout checklist:
- Verify the registry and tags before changing anything:
npm view @konbakuyomu/smart-search versions --json,npm view @konbakuyomu/smart-search dist-tags --json, andgh release list --repo konbakuyomu/smartsearch --limit 100. - For historical beta backfill, publish the replacement
*-beta.Npackage through Actions withcreate_github_release=falseif the workflow token cannot create releases, then create the missing GitHub prerelease locally withgh release create vX.Y.Z-beta.N --target <commit> --prerelease --latest=false. - Treat npm
E409during parallel backfills as a registry concurrency failure, not a version-design failure. Re-run the affected version serially after checking whether the package already exists. - Do a machine-readable gap check: expected beta versions minus npm versions must be empty, and expected
v*beta*releases minus GitHub prereleases must be empty. - Install the selected test build explicitly, for example
mise use -g "npm:@konbakuyomu/smart-search@0.1.10-beta.3" -y --pin, then runmise reshim,where.exe smart-search,smart-search --version,smart-search regression,smart-search smoke --mock --format json, and a non-ASCII JSON pipe such assmart-search deep "深度搜索一下最近的比特币行情" --format json | ConvertFrom-Json.
MIT