Skip to main content
ChatCLI includes three native web tools β€” @webfetch, @websearch and @wikipedia β€” that allow the agent to search the internet, fetch web pages and look things up on Wikipedia without depending on external MCP servers.
Web tools are native ChatCLI tools, automatically available in agent and coder modes. No MCP server configuration is required to use them.

@webfetch

Fetches a URL, strips the HTML, and returns the clean text content. Ideal for reading documentation, articles, READMEs, and any web page.

How It Works

1

HTTP request

ChatCLI makes a GET request to the provided URL with standard browser headers.
2

HTML parsing

The received HTML is parsed using golang.org/x/net/html, extracting only the text content.
3

Cleanup

Script, style, navigation tags and non-text elements are removed. The resulting text is cleaned and formatted.
4

Return

The text content is returned to the agent as the tool call result.

Usage

The LLM invokes @webfetch automatically when it needs to access content from a URL. You can also request it explicitly:

Argument Formats

Example

@webfetch respects redirects (up to 10), timeouts (30s), and returns clear errors for inaccessible URLs or SSL issues.

Filters for large payloads

Endpoints like Prometheus /metrics, configuration dumps or long listings can easily exceed tens of thousands of characters. @webfetch accepts a set of parameters that perform line-level filtering before truncation, so the useful part is not discarded: Example β€” filter Prometheus by metric prefix:
Example β€” page within the filtered payload:
Example β€” save everything to the scratch dir and read slices on demand:
Response:
The agent can then issue a read_file against the absolute path returned, choosing the exact line range that matters.
save_to_file always confines writes to CHATCLI_AGENT_TMPDIR. If save_path is an absolute path or contains .., only filepath.Base is used and the write is validated to ensure the result stays within the scratch dir.

Smart auto-save

When the LLM calls @webfetch without filter, exclude, range or an explicit save_to_file, and the returned body exceeds the auto-save threshold, ChatCLI automatically promotes the call to save_to_file=true. This shields the context from giant pages without requiring the model to know the body size in advance. Default: bodies above 10,000 bytes (configurable via CHATCLI_WEBFETCH_AUTOSAVE_BYTES) trigger the auto-save. The inline result is a compact preview (~5,000 chars), and the response opens with an explicit marker:
To disable or loosen auto-save β€” e.g. offline batches where the agent needs the whole body inline β€” raise the threshold:
On a per-call basis, passing any filter (even .*), explicit from_line/to_line, or save_to_file=false disables the automatic promotion.
See Token Efficiency for the full rationale behind this default.

Rendering JavaScript pages (SPA)

Pages that build their content client-side (SPAs, JS-rendered tables) return an empty β€œshell” on a static fetch β€” <div id="root"> plus bundles, no actual content. @webfetch solves this with an escalation chain:
1

Static fetch

Always the first step. Server-rendered pages stop here β€” zero extra cost.
2

JS-shell detection

Heuristics: thin extracted text + structural signals (empty #root/#app mount points, <noscript> warnings, framework markers β€” React, Next, Angular, Vue, Nuxt, Svelte, Gatsby, Remix, Flutter).
3

Headless render via CDP

A real Chromium renders the page (waits for load + DOM stability) and the settled DOM flows through the same extraction/filter/auto-save pipeline.
4

Browserless fallbacks

Without a browser, the embedded __NEXT_DATA__ state (Next.js) is recovered from the static HTML; as a last resort an honest note tells the model the fetch may be incomplete.
Browser discovery (in order): Chrome β†’ Chromium β†’ Edge β†’ Brave β†’ explicit path in CHATCLI_WEBFETCH_RENDER_BROWSER β†’ opt-in download of a pinned Chromium (~150 MB, once) with CHATCLI_WEBFETCH_RENDER_AUTOPROVISION=true. No API keys, no external services. Production posture: one shared browser per process (lazy launch, health-checked reuse, shutdown after 2 idle minutes), a circuit breaker (2 launch failures β†’ 5-minute pause), an incognito context per render (cookies never leak between sites) and SSRF enforced inside the browser β€” every sub-request the page fires is validated through CDP interception, mirroring the regular HTTP path guard. Rendered DOM capped at 10 MB.

@websearch

Performs a web search and returns results with title, URL and snippet. Supports two keyless backends by design β€” no third-party API key to register: DuckDuckGo (HTML scraping) is the zero-config default, and self-hosted SearxNG is preferred in corporate environments when you point to an internal instance.

Available backends

Fallback chain

For each query, ChatCLI builds an ordered chain of backends. If the first one fails or returns empty, the next one is tried automatically. Default order (CHATCLI_WEBSEARCH_PROVIDER unset or auto):
Explicit override to prefer SearxNG:
Result: the chain becomes searxng β†’ duckduckgo β†’ brave β†’ mojeek. The others remain as fallbacks if the SearxNG instance fails. The same applies to any provider: CHATCLI_WEBSEARCH_PROVIDER=brave moves Brave to the front and keeps the rest behind it.

Environment variables

/websearch command

Interactive manager for the preferred backend. Autocomplete available for subcommands and provider names. /websearch provider applies only to the current session. To persist, export the env in your shell or add it to .env.

Configuring self-hosted SearxNG

The SearxNG instance must have its JSON API enabled β€” it isn’t on by default. In the SearxNG settings.yml:
If you point SEARXNG_URL at an instance without JSON enabled, ChatCLI returns an actionable error instead of a cryptic decode failure:
The official searxng/searxng Docker Hub image boots in 30 seconds. In a corporate environment, a single container with internal ingress is enough β€” and it solves the β€œDDG blocked by the proxy” problem once and for all.

How it works internally

1

Chain selection

SelectSearchChain() reads CHATCLI_WEBSEARCH_PROVIDER and SEARXNG_URL, returns an ordered list of backends to try.
2

Sequential attempt

For each backend in the chain: call the search function. If results come back, stop and format. If it fails or returns zero, log the reason and advance to the next.
3

Formatting

Results become formatted text with via <provider> in the header, numbered with title + URL + snippet.

Argument Formats

Example

The (via DuckDuckGo) or (via SearxNG) header makes it clear which backend responded β€” useful for diagnosing why a query returned nothing (e.g. DDG served a CAPTCHA β†’ falls back to SearxNG).
Why keyless? ChatCLI is used in corporate environments where managing third-party API keys (Brave Search, Tavily, SerpAPI) creates operational friction β€” registration, rotation, approvals. Self-hosted SearxNG solves network lockdown without recurring cost; DuckDuckGo covers casual use without any config.

@wikipedia

Looks things up on Wikipedia keyless, via the public MediaWiki API: it searches for article titles matching a term, or reads the plain-text intro (summary) of a specific article. A natural companion to @websearch/@webfetch for quick fact-checking β€” no API key, no MCP server.

How It Works

Two modes:
  • search β€” takes a term and returns up to 5 matching article titles (the exact titles to pass to read).
  • read β€” takes the exact title of an article and returns its plain-text intro (no HTML, no markup).
The language is configurable via lang (default en; e.g. pt, es, fr). Values like pt-BR are normalized to pt.

Usage

The LLM invokes @wikipedia automatically when it needs a verifiable fact. The typical flow is: search for the term, then read the exact title returned.

Argument Formats

Example

@wikipedia is keyless and respects the MediaWiki API etiquette (identified User-Agent). For quick fact-checking it is cheaper and more direct than chaining @websearch + @webfetch.

Comparison


Availability

Web tools are available in the following modes:
In interactive chat mode, web tools are not available. You need to be in agent or coder mode for the LLM to invoke them as tool calls.

Next Steps

MCP Integration

Integrate additional web tools via MCP servers.

Agentic Plugins

See all tools available to the agent.