Files
ccs/docs/websearch.md
T

202 lines
7.6 KiB
Markdown

# 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:
- [`src/utils/websearch/mcp-installer.ts`](../src/utils/websearch/mcp-installer.ts)
- [`src/utils/websearch/claude-tool-args.ts`](../src/utils/websearch/claude-tool-args.ts)
- [`src/dispatcher/flows/settings-flow.ts`](../src/dispatcher/flows/settings-flow.ts)
- [`lib/mcp/ccs-websearch-server.cjs`](../lib/mcp/ccs-websearch-server.cjs)
## 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`](../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`](../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`.
```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`](../src/config/schemas/websearch.ts), and
defaults are in
[`src/config/schemas/unified-config.ts`](../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`](../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/utils/websearch/),
[`tests/unit/hooks/`](../tests/unit/hooks/), and
[`tests/unit/targets/settings-profile-websearch-launch.test.ts`](../tests/unit/targets/settings-profile-websearch-launch.test.ts).