Skip to content

ClineToolSet:ツール定義とスキーマ変換

源码版本v4.0.10

役割

ClineToolSet は Cline が「ツール (tool)」という概念を三つの層で統一管理する中枢である。第一層は「登録」:各ツールはモデルファミリ (ModelFamily) ごとに ClineToolSpec を一つ登録し、Generic ファミリがフォールバックを担う(register:19)。第二層は「選択」:getEnabledTools が variant が宣言したツール id リスト + コンテキスト要件(contextRequirements)で現在有効化すべきツールをフィルタする(getEnabledTools:87)。第三層は「変換」:getNativeConverter が providerId に従って異なるコンバータを選び、ClineToolSpec を Anthropic Tool / OpenAI ChatCompletionTool / Google FunctionDeclaration に翻訳する(getNativeConverter:151).

出力には二つの経路がある:一つは「テキストパス」で、ツールスキーマを <tool_name>...<param>...</param></tool_name> 形式の XML セグメントに組み立ててシステム提示に詰め込む。これはネイティブの tool calling をサポートしないモデル向け(PromptBuilder.tool:146)。もう一つは「ネイティブパス」で、getNativeTools が変換後のスキーマ配列を createMessagetools パラメータとして ApiHandler に渡す(getNativeTools:170).

設計動機

  • デュアルスキーマ出口:同じ ClineToolSpec から XML テキストにもネイティブツールスキーマにも変換できる。Cline がサポートするモデルの中には native function calling をサポートするもの(Anthropic / OpenAI / Gemini)とそうでないもの(多くのローカルモデル)があり、後者はシステム提示に XML を詰め込んでモデルにフォーマットで出力させるしかない。
  • variant フォールバックチェーン:getToolByNameWithFallback はまず正確な family を探し、次に GENERIC、さらに全 variant を走査する(fallback:48)。あるツールが next-gen にしか登録されていなくても generic variant が使えることを保証する。
  • contextRequirements の動的フィルタ:ツールは contextRequirements: (ctx) => boolean を宣言できる。例えば browser_actionsupportsBrowserUse=true を要求し、コンテキストが満たさなければフィルタで落とす(ctx filter:101)。variant リストをハードコードするより柔軟である。
  • 動的 subagent ツール:getDynamicSubagentToolSpecs は実行時に AgentConfigLoader が読み込んだ subagent 設定に基づいて USE_SUBAGENTS ツールの複数バリアントを生成する(dynamic subagent:108)。subagent ごとに一つの名前を付ける。だからツールセットは静的ではない。
  • MCP ツールを toolset に統合:mcpToolToClineToolSpec は MCP server が露出する tools を ClineToolSpec 形式に変換する。id はすべて use_mcp_tool、name は serverUid__mcp__toolName(mcp name:238)。MCP ツールと組み込みツールを同じ仕組みで管理する。
  • name 長さのフォールバック:MCP ツールの name が 64 文字を超えたら直接 skip して登録しない(length check:243)。provider API が長すぎる tool name を拒否するためである。

主要ファイル

  • ClineToolSet class:8variants: Map<ModelFamily, Set<ClineToolSet>> という静的レジストリを持つ。
  • register:19 — 静的メソッド。インスタンスを生成して family ごとに Map に保存、同 id は重複排除する。
  • getToolByNameWithFallback:48 — 三段階検索:正確な family → GENERIC → 全表走査。
  • getToolsForVariantWithFallback:73 — id リストを一括で解決し、重複排除する。
  • getEnabledTools:87 — variant.tools リスト + contextRequirements でフィルタ。
  • getDynamicSubagentToolSpecs:108 — subagent が有効で subagent 実行中でない時、AgentConfigLoader から動的に USE_SUBAGENTS バリアントを生成する。
  • getEnabledToolSpecs:136 — 静的ツールと動的 subagent ツールをマージ。subagent 動的生成時は静的 USE_SUBAGENTS を削除する。
  • getNativeConverter:151 — providerId でコンバータを選ぶ:anthropic/bedrock/minimax → inputSchema、openai 互換 → functionDefinition、gemini → functionDeclarations。
  • getNativeTools:170 — variant.labels.use_native_tools === 1 かつ context.enableNativeToolCalls の時だけネイティブスキーマ配列を返す。
  • mcpToolToClineToolSpec:198 — MCP server の inputSchema を ClineToolSpec.parameters に翻訳し、enum / format などの追加フィールドを保持する。
  • ClineDefaultTool enum:8 — すべての組み込みツール id の列挙:execute_command / read_file / write_to_file / replace_in_file / search_files など。
  • ClineToolSpec:10 — ツール仕様型:id / name / description / parameters / contextRequirements。
  • toolSpecFunctionDefinition:52 — OpenAI ChatCompletionTool への変換。strict: falseadditionalProperties: false を持つ。
  • toolSpecInputSchema:145 — Anthropic Tool への変換。フィールド名は parameters ではなく input_schema
  • toolSpecFunctionDeclarations:243 — Google FunctionDeclaration への変換。type は STRING / NUMBER / BOOLEAN など大文字定数を使う。
  • registerClineToolSets:32 — 起動時にすべてのツール variants を一度に ClineToolSet に登録する。

データフロー

ツールは「登録」から「最終的に ApiHandler に使われる」までに四つのステップを経る:登録 → variant 宣言 → 有効化フィルタ → スキーマ変換。登録段階は PromptRegistry 構築時にトリガーされる:

typescript
// apps/vscode/src/core/prompts/system-prompt/tools/init.ts
export function registerClineToolSets(): void {
	const allToolVariants = [
		...access_mcp_resource_variants,
		...act_mode_respond_variants,
		// ...22 個のツールの variants 配列
		...apply_patch_variants,
	]

	allToolVariants.forEach((v) => {
		ClineToolSet.register(v)
	})
}

各ツールファイルは _variants 配列をエクスポートし、その中には異なる ModelFamily 向けに書かれた ClineToolSpec が入っている(allToolVariants:34). 登録後、variant 自身がどのツール id を使うかを宣言する:

typescript
// apps/vscode/src/core/prompts/system-prompt/variants/generic/config.ts
.tools(
	ClineDefaultTool.BASH,
	ClineDefaultTool.FILE_READ,
	ClineDefaultTool.FILE_NEW,
	ClineDefaultTool.FILE_EDIT,
	ClineDefaultTool.SEARCH,
	ClineDefaultTool.LIST_FILES,
	ClineDefaultTool.LIST_CODE_DEF,
	ClineDefaultTool.BROWSER,
	ClineDefaultTool.MCP_USE,
	ClineDefaultTool.MCP_ACCESS,
	ClineDefaultTool.ASK,
	ClineDefaultTool.ATTEMPT,
	ClineDefaultTool.PLAN_MODE,
	ClineDefaultTool.MCP_DOCS,
	ClineDefaultTool.TODO,
	ClineDefaultTool.GENERATE_EXPLANATION,
	ClineDefaultTool.USE_SKILL,
	ClineDefaultTool.USE_SUBAGENTS,
)

generic variant は 18 個のツール id を列挙する(generic tools:58)。getEnabledTools はこのリストを持って getToolByNameWithFallback で一つずつ解決し、さらに contextRequirements でフィルタする。最後にネイティブ tool calling に進む場合、コンバータが ClineToolSpec を対応 provider のスキーマに変換する:

typescript
// apps/vscode/src/core/prompts/system-prompt/spec.ts
export function toolSpecInputSchema(tool: ClineToolSpec, context: SystemPromptContext): AnthropicTool {
	// ...
	const toolInputSchema: AnthropicTool = {
		name: tool.name,
		description: replacer(tool.description, context),
		input_schema: {
			type: "object",
			properties,
			required,
		},
	}
	return toolInputSchema
}

replacer 関数は / / などのテンプレート変数を置換する(replacer:404)。だからツールの description にこれらのプレースホルダーを書いておき、実行時に context で埋めることができる。

境界と失敗

  • ツールの重複登録:同じ family + 同じ id は Set に重複して追加されない。コード内で明示的に some(t => t.config.id === config.id) をチェックする(dedup:25).
  • MCP ツール name が長すぎる:mcpToolName.length > 64 は直接 skip する(length check:243)。ツールセットに現れないため、モデルはこの MCP ツールを呼べない。
  • variant が tools を宣言していない:getEnabledToolsvariant.tools が空の時は空配列を返す(empty tools:89)。その variant は純テキスト対話で、ツールを一つも持たないことを意味する。
  • subagent のネスト:getDynamicSubagentToolSpecscontext.isSubagentRun が true の時は直接空を返す(subagent guard:109)。subagent がさらに subagent ツールを生成するのを避け、無限再帰を防ぐ。
  • use_native_tools label 未設定:getNativeTools はデフォルトで variant.labels.use_native_tools !== 1 の時は undefined を返す(label gate:175)。context.enableNativeToolCalls であっても効かず、variant が明示的に有効化しなければならない。
  • converter が例外を投げる:toolSpecInputSchema などのコンバータは tool.contextRequirements が満たされない時、"Tool X does not meet context requirements" を投げる(contextRequirements throw:55)。理論上は getEnabledTools が既にフィルタしているので、ここはフォールバックである。
  • MCP server.disabled:MCP ツール取得時にまず filter(s => s.disabled !== true) する(disabled filter:183)。無効化された server のツールはツールセットに一切入らない。

まとめ

ClineToolSet はツールの「中央レジストリ + セレクタ + スキーマ翻訳器」の三役である。キーとなる設計は、同じ ClineToolSpec が「テキスト XML セグメント」と「ネイティブツールスキーマ」の二つの出口を同時に持てることで、Cline は native function calling をサポートするモデルもテキスト出力しかできないローカルモデルも両方サービスできる。MCP ツールは組み込みツールと同じ形式に翻訳されて同じ仕組みに詰め込まれ、subagent ツールは実行時の設定で動的に生成される。だから toolset は静的な表ではなく動的に構築される。

  • ツールプロンプトがどう XML セグメントに組み立てられるか:/prompts/prompt-builder
  • plan / act 各モードが使えるツールの差異:/prompts/mode
  • handler が tools パラメータをどう消費するか:/providers/anthropic

公式資料:Cline 文档 · README