cc-websearch
A Claude Code plugin providing WebSearch and WebFetch skills as a drop-in replacement for Claude Code's built-in tools. Powered by DuckDuckGo (no API keys required). Zero configuration for basic use.
- WebSearch -- Search the web using DuckDuckGo, returning structured XML results
- WebFetch -- Fetch a web page, extract its main content, and convert to markdown
No API keys, no accounts, no subscriptions. Install the plugin and start searching.
Quick Install
# Local development:
claude --plugin-dir /path/to/cc-websearch
# From GitHub release (requires packaged .zip):
claude --plugin-url https://github.com/your-org/cc-websearch/releases/download/v1.0/plugin.zip
Compiled scripts are shipped in git (built via esbuild), so the plugin works immediately after install -- no build step is needed.
Usage
Both skills accept JSON input on stdin and write results to stdout. Errors and diagnostic messages are written to stderr.
WebSearch
Pipe a JSON object with a query field:
echo '{"query":"latest ECMAScript specification"}' | node "${CLAUDE_PLUGIN_ROOT}/skills/websearch/scripts/websearch.cjs"
The script produces <search_results> XML on stdout:
<search_results>
<result>
<title>ECMAScript 2024 specification finalized</title>
<url>https://example.com/ecmascript-2024</url>
<snippet>ECMAScript 2024, the 15th edition, adds new array grouping, Promise.withResolvers, and RegExp v flag.</snippet>
</result>
</search_results>
Optional fields:
allowed_domains (string[]): Only return results from these domains
blocked_domains (string[]): Exclude results from these domains
allowed_domains and blocked_domains cannot be used together.
WebFetch
Pipe a JSON object with a url and prompt field:
echo '{"url":"https://example.com/article","prompt":"Summarize this article"}' | node "${CLAUDE_PLUGIN_ROOT}/skills/webfetch/scripts/webfetch.cjs"
The script fetches the page, extracts the main content using Mozilla's Readability library, converts it to markdown, and writes the result to stdout.
The prompt field describes what the user wants to know about the page. The script does not answer the prompt -- it returns the page content so the calling agent can answer.
Configuration
Configuration is optional. By default the plugin works with sensible defaults.
Config file
Create ~/.config/websearch/config.json:
{
"retry": {
"maxRetries": 4,
"baseDelay": 1000,
"maxDelay": 16000,
"timeout": 30000
},
"logging": {
"level": "info"
}
}
See .env.example at the project root for a complete template with all options documented.
Options
| Key | Type | Default | Description |
|---|
retry.maxRetries | integer (0+) | 4 | Maximum retry attempts |
retry.baseDelay | integer ms (0+) | 1000 | Initial backoff delay |
retry.maxDelay | integer ms (0+) | 16000 | Maximum backoff delay |
retry.timeout | integer ms (0+) | 30000 | Request timeout |
logging.level | "debug" | "info" | "warn" | "error" | "info" | Logging verbosity |
Environment variable overrides
Each config option has a corresponding environment variable that takes precedence over the config file:
| Environment variable | Overrides |
|---|
WEBSEARCH_RETRY_MAX_RETRIES | retry.maxRetries |
WEBSEARCH_RETRY_BASE_DELAY | retry.baseDelay |
WEBSEARCH_RETRY_MAX_DELAY | retry.maxDelay |
WEBSEARCH_RETRY_TIMEOUT | retry.timeout |
WEBSEARCH_LOGGING_LEVEL | logging.level |
Precedence (highest to lowest):
- Environment variable
- Config file value
- Hardcoded default
Feature Comparison
WebSearch
| Feature | Built-in WebSearch | cc-websearch WebSearch |
|---|
| Search provider | Claude internal | DuckDuckGo (HTML scraping) |
| API key required | No | No |
query | Supported | Supported |
allowed_domains | Supported | Supported |
blocked_domains | Supported | Supported |
| Output format | <search_results> XML | <search_results> XML |
| Result fields | title, url, snippet | title, url, snippet |
| Domain filter limit | Neither required | Cannot use both simultaneously |
WebFetch