Tool System
How agents define, register, expose, and execute tools.
The Universal Tool Shape
Every agent defines tools with the same interface:
Tool {
name: string
description: string
parameters: JSONSchema
execute(params) → result
}
| Agent | Type Name | Extras |
|---|---|---|
| Pi | AgentTool<TParameters> | label, executionMode (sequential/parallel) |
| Goose | Tool (rmcp) | ToolAnnotations (read_only, destructive, idempotent, open_world) |
| Grok Build | ToolDefinition | ToolKind, ToolNamespace, versioned descriptions |
| Kimi Code | ExecutableTool | Per-step dynamic rebuild via buildTools() |
| OpenCode/Kilocode | Effect-TS Tool | ToolRegistry service, codec-validated |
| Cline | AgentTool | zodToJsonSchema for schema generation |
| Qwen Code | Same as OpenCode | tool-search for dynamic MCP discovery |
Tool Surface by Agent
| Agent | Total Tools | Strategy |
|---|---|---|
| Codex | ~3 | Minimal: patch + plan + shell |
| Pi | ~4-6 | Core set: read, bash, edit, write + skills |
| Cline | ~6 | read_files, run_commands, search_codebase, edit_file, apply_patch, submit_and_exit |
| Goose | 0 built-in | All via MCP extensions (platform tools: schedule only) |
| Grok Build | ~25 | Rich built-in set per toolset variant (grok_build, grok_build_hashline, grok_build_concise) |
| OpenCode/Kilocode | ~20 | read, edit, write, bash, grep, glob, ls, web-fetch, web-search, skill, todowrite, apply-patch, enterPlanMode, exitPlanMode |
| Kimi Code | dynamic | Tool set determined at runtime by session config |
| Qwen Code | ~60+ | Largest surface: all of OpenCode + monitor, cron, workflow, agent, team-*, artifact, notebook-edit, image-gen, lsp, tool-search, loop-wakeup, enter/exit-worktree, send-message |
Tool Protocol: Where Tools Come From
- Built-in only: Codex, Pi — all tools are compiled into the binary
- Built-in + MCP optional: Grok Build, Qwen Code, OpenCode/Kilocode, Cline — core tools built-in, MCP extends
- MCP-native: Goose — ALL tools come from extensions via MCP. No built-in coding tools.
Tool Execution: Sequential vs Parallel
| Agent | Default | Control |
|---|---|---|
| Pi | Configurable | Per-tool executionMode field |
| Goose | Sequential | No parallel option |
| Grok Build | Parallel encouraged | Prompt instructs “parallelize independent calls” |
| Cline | Parallel encouraged | Prompt instructs “emit all independent calls now” |
| Qwen Code | Parallel | Standard multi-tool-call support |
| Codex | Parallel | multi_tool_use.parallel |
Tool Annotations/Metadata
Goose is unique in having rich tool annotations:
#![allow(unused)]
fn main() {
ToolAnnotations {
title: String,
read_only: bool,
destructive: bool,
idempotent: bool,
open_world: bool,
}
}
This enables the permission system to auto-classify tools without LLM calls for simple cases.
Dynamic Tool Loading
Agents that change available tools mid-session:
- Kimi Code:
buildTools()re-invoked before every step (tools loaded mid-turn are immediately available) - Qwen Code:
tool-searchlets the model discover MCP tools on demand - Goose: Extensions can be enabled/disabled mid-conversation
- Grok Build: Different toolset variants (hashline vs standard) per agent definition