Files
ccs/docs/websearch.md
T

7.6 KiB

WebSearch Configuration Guide

CCS provides a local WebSearch MCP tool for managed Claude launches that use a third-party provider. Native Claude sessions keep Anthropic's native search behavior.

Launch Contract

For a third-party Claude launch, CCS:

  1. suppresses the native WebSearch tool because the third-party backend cannot execute it;
  2. when WebSearch is enabled, adds a short steering prompt that prefers the CCS MCP WebSearch tool;
  3. when WebSearch is enabled, installs the managed MCP server and adds the ccs-websearch entry to the applicable Claude configuration;
  4. searches enabled and ready providers in deterministic order.

Enabled launches fail closed if the MCP runtime or configuration cannot be prepared. This prevents a launch where native search is suppressed but the managed replacement is missing. When websearch.enabled is false, CCS skips MCP provisioning but still suppresses native WebSearch for third-party profiles; the model can use ordinary network or shell tools when allowed.

Claude subcommands that reject session flags are passed through without WebSearch argument injection.

Implementation sources:

Provider Order, Runtime Eligibility, and Dashboard Status

The managed runtime tries eligible providers sequentially:

  1. Exa
  2. Tavily
  3. Brave Search
  4. SearXNG
  5. DuckDuckGo
  6. Antigravity CLI
  7. Gemini CLI compatibility fallback
  8. OpenCode
  9. Grok CLI

The first successful provider wins. Temporarily failing providers can enter a bounded cooldown and be skipped on later calls. Runtime attempt eligibility is defined in lib/hooks/websearch-transformer.cjs; do not duplicate that list in other architecture docs.

The transformer and dashboard answer related but different questions:

Provider Transformer attempts when Dashboard reports available when
Exa Enabled and EXA_API_KEY is present. Enabled and the key is available through the active process or enabled Global Env.
Tavily Enabled and TAVILY_API_KEY is present. Enabled and the key is available through the active process or enabled Global Env.
Brave Search Enabled and BRAVE_API_KEY is present. Enabled and the key is available through the active process or enabled Global Env.
SearXNG Enabled and a base URL is present. Enabled with a valid normalized base URL.
DuckDuckGo Enabled. Enabled.
Antigravity Enabled and the agy executable is available. Enabled and the CLI is installed.
Gemini compatibility Enabled and the gemini executable is available. Enabled, installed, and authenticated.
OpenCode Enabled and the opencode executable is available. Enabled and the CLI is installed.
Grok Enabled and the grok executable is available. Enabled, installed, and GROK_API_KEY is available.

DuckDuckGo is the default zero-setup provider. API-backed and CLI fallback providers are disabled by default. Dashboard availability and setup guidance are computed separately by src/utils/websearch/status.ts; they do not change the transformer's attempt predicate.

Configuration

Use ccs config and open Settings → WebSearch, or edit the websearch section in the unified CCS configuration:

The runtime schema supports Antigravity through providers.agy; the current dashboard editor does not expose that provider, so configure it in config.yaml.

websearch:
  enabled: true
  providers:
    exa:
      enabled: false
      max_results: 5
    tavily:
      enabled: false
      max_results: 5
    brave:
      enabled: false
      max_results: 5
    searxng:
      enabled: false
      url: ""
      max_results: 5
    duckduckgo:
      enabled: true
      max_results: 5
    agy:
      enabled: false
      model: gemini-2.5-flash
      timeout: 90
    gemini:
      enabled: false
      model: gemini-2.5-flash
      timeout: 55
    opencode:
      enabled: false
      model: opencode/grok-code
      timeout: 90
    grok:
      enabled: false
      timeout: 55

The schema is src/config/schemas/websearch.ts, and defaults are in src/config/schemas/unified-config.ts. Deprecated top-level WebSearch fields remain load-compatible but must not be used for new configuration.

SearXNG URL

Configure the instance base URL, for example https://search.example.invalid. Do not include /search, credentials, query parameters, or a URL fragment. CCS normalizes the base and calls the JSON search endpoint.

Dashboard-managed API keys

The dashboard stores supported provider keys in global_env. They are available to WebSearch only when global environment injection is enabled. Shell-provided environment values remain supported. Never place real keys in documentation, tests, or committed configuration.

Managed Files

In the default user layout, CCS manages:

  • ~/.claude.json → mcpServers.ccs-websearch
  • ~/.ccs/mcp/ccs-websearch-server.cjs
  • ~/.ccs/hooks/websearch-transformer.cjs

CCS installation and test paths can differ because configuration helpers honor the active CCS and Claude home locations. Provisioning uses a lock and preserves unrelated MCP server entries. Malformed Claude configuration is not overwritten.

Runtime Environment

src/utils/websearch/hook-env.ts converts the resolved configuration into runtime environment values. Provider API keys remain environment inputs; boolean and limit variables describe provider selection.

Operational overrides:

Variable Effect
CCS_DEBUG Enables verbose diagnostics and WebSearch trace collection.
CCS_WEBSEARCH_TRACE Enables WebSearch JSONL trace collection.
CCS_WEBSEARCH_TRACE_FILE Requests a trace path within an allowed CCS log, system temporary, or /var/log boundary.

An unsafe trace-file override is ignored. Trace writes are best effort and do not change launch or search results.

Diagnostics

By default, trace records are written under ~/.ccs/logs/websearch-trace.jsonl. They correlate launch preparation, MCP exposure, tool calls, provider attempts, provider success/failure, and session summaries.

Normal trace metadata uses a query fingerprint and length instead of the raw query. Provider-failure records can also include error detail returned by a provider implementation, including HTTP response excerpts or CLI stderr. That provider-generated detail is not guaranteed to exclude query text or other sensitive content unless the implementation redacts it. Treat the trace file as sensitive operational data.

For delegated/headless sessions, a likely-bypass summary means the tool was exposed but no WebSearch call occurred and another allowed tool path was used.

When search is unavailable:

  1. confirm websearch.enabled and at least one provider are enabled;
  2. check readiness in the dashboard;
  3. verify API keys or the SearXNG base URL without printing secrets;
  4. enable CCS_WEBSEARCH_TRACE=1 for one launch;
  5. inspect provider attempt and cooldown events.

Focused coverage lives under tests/unit/utils/websearch/, tests/unit/hooks/, and tests/unit/targets/settings-profile-websearch-launch.test.ts.