Skip to content

WebFetchTool / WebSearchTool:Cline アカウントのネットワークツール

源码版本v4.0.10

役割

この二つの handler は Cline のネットワーク出口ツールで、どちらも IFullyManagedTool を実装し、実行前に provider が cline で、ユーザーが clineWebToolsEnabled 設定を有効にし、対応する feature flag が有効であることを要求する(WebFetch class:20-21,WebSearch class:21-22)。BrowserToolHandler との本質的な違いは:ブラウザツールはローカルまたはリモート Chrome で直接ページを抓むのに対し、この二つのツールは HTTP リクエストを Cline 公式 API に送り、Cline サーバー側に抓取や検索を行わせ、結果をモデルに返す点である。

  • WebFetchToolHandler(ClineDefaultTool.WEB_FETCH):モデルが URL と prompt を与えると、ツールはこの二つを ${apiBaseUrl}/api/v1/search/webfetch に POST し、サーバー側が prompt を使って URL の内容を抽出しテキスト結果を返す(webfetch axios:150).
  • WebSearchToolHandler(ClineDefaultTool.WEB_SEARCH):モデルが query とオプションの allowed_domains/blocked_domains 白黒リスト(互いに排他)を与えると、ツールは /api/v1/search/websearch に POST し、{title, url} の結果セットを返す(websearch axios:174).

この二つのツールの出力はユーザーに直接表示されず、tool result として userMessageContent に詰め込まれ、次のラウンドの LLM に渡るだけである。ローカルリソース(ファイルシステム、terminal、ブラウザ)を必要とせず、純粋なネットワーク出口なので operationIsLocatedInWorkspace: false である。

設計動機

  • ローカル抓取ではなくサーバー代理:多くの場面で Cline は制限された環境で走り、外網への直結が通じない。サーバー代理で認証・レート制限・抓取ロジック(JavaScript レンダリング、アンチクロール回避)を統一し、クライアントはリクエストを送るだけにする(webfetch request:150-166)。
  • 三重ゲート:provider が cline であること、ユーザー設定の clineWebToolsEnabled、feature flag が有効であること。いずれかを満たさなければ toolError("Cline web tools are currently disabled.") を返し、モデルを先に進めない(feature flag gate:55-59)。
  • 15 秒タイムアウト:両ツールとも 15 秒の axios タイムアウトを使い、長いテールのリクエストがラウンド全体を引きずり込まないようにする(timeout:163)。
  • ドメイン白黒リストの排他:web_search は allowed_domainsblocked_domains を同時に指定できないことを検証し、違反時は mistake++ + toolError とする(mutual exclusivity:75-78)。
  • ストリーミング部分配列解析:parsePartialArrayString はストリーミングで ["a", "b" のような不完全な JSON が来ても既に完成している要素を抽出でき、partial block 段階でドメインリストを表示できる(parsePartialArrayString:71-72).
  • 認証エラーの明確化:auth token が取れない時は CLINE_ACCOUNT_AUTH_ERROR_MESSAGE を投げ、ユーザーに Cline アカウントへログインするよう促し、401 をモデルに返さない(auth check:146-148).

主要ファイル

  • WebFetch class:20name = ClineDefaultTool.WEB_FETCH
  • handlePartialBlock:27 — ストリーミング中は「Fetching URL: ...」プレースホルダーを一回 say するだけで、ブロックしない。
  • execute:44 — 主流程:gate → パラメータ検証 → 承認 → hook → axios POST → result 返却。
  • feature flag gate:55-59 — provider !== "cline" または設定/flag のいずれかが false なら直接 toolError。
  • approval flow:81-128shouldAutoApproveTool が say か ask かを決める。
  • axios POST webfetch:143-166 — baseUrl + authToken を取得し、POST /api/v1/search/webfetch、body は {Url, Prompt}、header に X-Task-ID を付ける。
  • WebSearch class:21name = ClineDefaultTool.WEB_SEARCH
  • domain parse + mutex:70-78parsePartialArrayString でドメイン配列を解析 + 排他検証。
  • axios POST websearch:150-183 — POST /api/v1/search/websearch。body は配列が空でない場合のみ対応フィールドを付ける。
  • format results:188-200{title, url}[]1. title\n url\n\n のテキスト形式に組み立てる。
  • CLINE_ACCOUNT_AUTH_ERROR_MESSAGE — 認証エラーの統一プロンプトテキスト。
  • AuthServicegetInstance().getAuthToken() で現在のアカウントトークンを取得。

データフロー

二つの handler の流れはほぼ同じ。WebFetchToolHandler を例にすると、核心は承認後に Cline API に POST すること:

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() は追加の追跡ヘッダーを付与し、getAxiosSettings() は axios にプロキシ/CA などのユーザー設定を注入する。レスポンス構造は { data: { result: "..." } }(axios が data のラップを自動で一段追加している点に注意)。直接取り出して formatResponse.toolResult で tool result に包んで LLM に返す。

WebSearchToolHandler は結果のフォーマットが一つ増える:

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 はリクエストボディでは非空の時のみ付ける。排他検証は mistake++ 後に直接 toolError で拒否し、リクエストは送らない。

境界と失敗

  • 三重ゲート未達成:provider が cline でない、ユーザーが web tools 設定をオフにしている、feature flag が閉じている場合、いずれか一つでも false なら直接 disabled toolError を返す。mistake は増えない(feature flag gate:55-59)。
  • 未ログイン:AuthService.getInstance().getAuthToken() が空を返す時、CLINE_ACCOUNT_AUTH_ERROR_MESSAGE を投げ、catch で Error fetching web content: ... に変換される(auth check:146-148)。
  • ドメイン白黒リスト同時指定:web_search で allowed_domainsblocked_domains を同時に与えた時、mistake++ + toolError で直接遮断する(mutual exclusivity:75-78)。
  • PreToolUse hook のキャンセル:hook が PreToolUseHookCancellationError を投げた時、toolDenied を返しリクエストは送らない(PreToolUse hook:131-140)。
  • リクエスト失敗のフォールバック:axios がエラーを投げる、またはサーバー側が 200 以外を返す時、catch で Error fetching web content: ... / Error performing web search: ... に包み、Task に投げずモデルにエラーを見せる(error catch:173-175)。
  • タイムアウト:15 秒の axios タイムアウト。長いテールのリクエストは切断され error catch に進む(timeout:163)。
  • 結果が空:web_search が 0 件を返す時は Search completed (0 results found) を返し、後続の行を付けない(empty results:193-199)。

まとめ

WebFetch と WebSearch は Cline が自前のサーバー代理でネットワーク抓取/検索を行う二つの handler で、同じ gate(provider=cline + setting + flag)、同じ承認/hook フロー、同じ 15 秒タイムアウトを共有する。WebFetch はサーバー側が prompt で抽出したテキストを返し、WebSearch は構造化された {title, url} リストを 1./2./3. の形式のテキストに組み立てて返す。両ツールともディスクに書かず、ブラウザを開かず、完全に純粋なネットワーク出口である。

さらに掘り下げるなら次へ:

  • ブラウザツール(ローカル抓取):/cap-tools/browser
  • ファイルとコマンドツール:/cap-tools/file-ops
  • ツール调度の経路:/agent-loop/task-class

公式資料:Cline 文档 · README