Skip to content

WebFetchTool / WebSearchTool: Cline account's network tools

源码版本v4.0.10

Responsibilities

These two handlers are Cline's network-egress tools. Both implement IFullyManagedTool, and both require before execution that the provider is cline, the user has enabled the clineWebToolsEnabled setting, and the corresponding feature flag is on (WebFetch class:20-21, WebSearch class:21-22). The essential difference from BrowserToolHandler is that the browser tool uses a local or remote Chrome to fetch pages directly, whereas these two tools send HTTP requests to Cline's official API, letting the Cline server do the fetching or searching and then returning the result to the model.

  • WebFetchToolHandler (ClineDefaultTool.WEB_FETCH): the model supplies a URL and a prompt; the tool POSTs both to ${apiBaseUrl}/api/v1/search/webfetch, and the server uses the prompt to extract content from the URL and returns a text result (webfetch axios:150).
  • WebSearchToolHandler (ClineDefaultTool.WEB_SEARCH): the model supplies a query and optional allowed_domains/blocked_domains allow/blacklist (mutually exclusive); the tool POSTs to /api/v1/search/websearch and returns a set of {title, url} results (websearch axios:174).

The output of both tools is not shown to the user directly; it is only stuffed back into userMessageContent as a tool result for the next LLM turn. They need no local resources (filesystem, terminal, browser) — they are purely network egress, so operationIsLocatedInWorkspace: false.

Design motivation

  • Server-side proxy instead of local fetch: in many scenarios Cline runs in restricted environments where direct internet access is unavailable; the server-side proxy unifies authentication, rate limiting, and fetch logic (JavaScript rendering, anti-crawl bypass), and the client only sends requests (webfetch request:150-166).
  • Three gates: the provider must be cline, the user setting clineWebToolsEnabled must be on, and the feature flag must be enabled; failing any one returns toolError("Cline web tools are currently disabled.") directly, not letting the model continue (feature flag gate:55-59).
  • 15-second timeout: both tools use a 15-second axios timeout to prevent long-tail requests from stalling the whole turn (timeout:163).
  • Domain allow/blacklist mutual exclusion: web_search validates that allowed_domains and blocked_domains are not supplied together; on violation mistake++ + toolError (mutual exclusivity:75-78).
  • Streaming partial-array parsing: parsePartialArrayString can extract already-complete elements even when streaming emits incomplete JSON like ["a", "b", so the domain list can be displayed during the partial-block phase (parsePartialArrayString:71-72).
  • Explicit auth errors: when the auth token cannot be obtained, it throws CLINE_ACCOUNT_AUTH_ERROR_MESSAGE telling the user to log in to their Cline account, rather than sending a 401 to the model (auth check:146-148).

Key files

Data flow

The flows of the two handlers are nearly identical; using WebFetchToolHandler as the example, the core is the POST to the Cline API after approval:

typescript
// apps/vscode/src/core/task/tools/handlers/WebFetchToolHandler.ts
const baseUrl = ClineEnv.config().apiBaseUrl
const authToken = await AuthService.getInstance().getAuthToken()
if (!authToken) {
    throw new Error(CLINE_ACCOUNT_AUTH_ERROR_MESSAGE)
}

const response = await axios.post(
    `${baseUrl}/api/v1/search/webfetch`,
    { Url: url, Prompt: prompt },
    {
        headers: {
            Authorization: `Bearer ${authToken}`,
            "Content-Type": "application/json",
            "X-Task-ID": config.ulid || "",
            ...(await buildClineExtraHeaders()),
        },
        timeout: 15000,
        ...getAxiosSettings(),
    },
)
const result = response.data.data.result
return formatResponse.toolResult(result)

buildClineExtraHeaders() adds extra tracing headers, and getAxiosSettings() injects user-configured proxy/CA settings into axios. The response shape is { data: { result: "..." } } (note axios adds an extra data wrapper); the inner field is extracted and wrapped with formatResponse.toolResult as the tool result for the LLM.

WebSearchToolHandler has one extra step for result formatting:

typescript
// apps/vscode/src/core/task/tools/handlers/WebSearchToolHandler.ts
const data = response.data.data
const results = data.results || []
let resultText = `Search completed (${resultCount} results found)`
if (results.length > 0) {
    resultText += ":\n\n"
    results.forEach((result, index) => {
        resultText += `${index + 1}. ${result.title}\n   ${result.url}\n\n`
    })
}
return formatResponse.toolResult(resultText)

allowed_domains / blocked_domains are only included in the request body when non-empty; the mutual-exclusion check rejects with mistake++ and toolError directly without sending a request.

Boundaries and failure modes

  • Three gates unmet: provider is not cline, the user has turned off web tools setting, or the feature flag is off — any of these returns a disabled toolError directly without incrementing mistake (feature flag gate:55-59).
  • Not logged in: when AuthService.getInstance().getAuthToken() returns empty, throws CLINE_ACCOUNT_AUTH_ERROR_MESSAGE, which the catch turns into Error fetching web content: ... (auth check:146-148).
  • Domain allow/blacklist both given: when web_search is given both allowed_domains and blocked_domains, mistake++ + toolError intercepts directly (mutual exclusivity:75-78).
  • PreToolUse hook cancellation: when the hook throws PreToolUseHookCancellationError, returns toolDenied and sends no request (PreToolUse hook:131-140).
  • Request failure fallback: axios errors or non-200 server responses are wrapped in the catch as Error fetching web content: ... / Error performing web search: ..., not propagated to the Task, letting the model see the error (error catch:173-175).
  • Timeout: 15-second axios timeout; long-tail requests are cut off and go through the error catch (timeout:163).
  • Empty results: when web_search returns 0 results, returns Search completed (0 results found) with no following lines (empty results:193-199).

Summary

WebFetch and WebSearch are the two handlers Cline uses to do network fetching/searching through its own server-side proxy. They share the same gate (provider=cline + setting + flag), the same approval/hook flow, and the same 15-second timeout. WebFetch returns the text extracted by the server using the prompt; WebSearch returns a structured {title, url} list concatenated into text in 1./2./3. format. Neither tool writes to disk or opens a browser — they are purely network egress.

To dig deeper, continue with:

  • Browser tools (local fetching): /cap-tools/browser
  • File and command tools: /cap-tools/file-ops
  • Tool scheduling chain: /agent-loop/task-class

See official docs: Cline 文档 · README