Tools & Actions
Tools are how agents interact with the outside world. Learn how to design, implement, and use agent tools.
What are Tools?
Tools are interfaces that let agents take real actions. Without tools, an agent can only generate text; with tools, an agent can:
- Read and write files
- Execute code
- Call APIs
- Search information
- Interact with databases
- Send messages
Function Calling
Modern LLMs support function calling, which is the foundation of tool use. The flow looks like this:
1. Define the tool schema
{
"name": "read_file",
"description": "Read the contents of a file",
"parameters": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
}
},
"required": ["path"]
}
}
2. The LLM decides to call
{
"tool_call": {
"name": "read_file",
"arguments": {"path": "config.json"}
}
}
3. Execute the tool and return the result
{
"content": "{\"name\": \"my-app\", ...}"
}
import { query } from "@anthropic-ai/claude-agent-sdk";
const response = query({
prompt: "Read package.json and tell me the project name",
options: {
// Control which tools the agent can use
allowedTools: ["Read", "Glob"],
// Or use preset + overrides
// tools: { type: 'preset', preset: 'claude_code' },
// disallowedTools: ["Write", "Bash"]
}
});
for await (const message of response) {
if (message.type === "tool_call") {
console.log(`Tool: ${message.tool_name}`);
console.log(`Input: ${JSON.stringify(message.tool_input)}`);
}
if (message.type === "tool_result") {
console.log(`Result: ${message.content.slice(0, 100)}...`);
}
}
Tool Categories
File Tools
| Tool | Function |
|---|---|
read_file |
Read file contents |
write_file |
Create or overwrite a file |
edit_file |
Edit part of a file |
list_directory |
List directory contents |
Shell Tools
bash({
"command": "npm install",
"working_dir": "/project",
"timeout": 60
})
Search Tools
grep- Text searchglob- Filename matchingsemantic_search- Semantic searchweb_search- Web search
API Tools
- HTTP requests (GET/POST/PUT/DELETE)
- Database queries
- Third-party service integrations (GitHub, Slack, etc.)
Tool Design Principles
1. Atomicity
Each tool should do only one thing:
// BAD: too many responsibilities
create_and_run_test(file, test_content, run_args)
// GOOD: split into atomic operations
write_file(path, content)
run_command("pytest " + path)
2. Clear Descriptions
Descriptions should be detailed enough for the LLM to know when to use them:
// BAD
"description": "Search files"
// GOOD
"description": "Search for files by name pattern using glob syntax.
Use this when you need to find files matching a pattern like '*.py'
or 'src/**/*.ts'. Returns a list of matching file paths."
3. Reasonable Parameters
{
"name": "edit_file",
"parameters": {
"path": "string (required) - File to edit",
"old_string": "string (required) - Exact text to replace",
"new_string": "string (required) - Replacement text",
"expected_count": "number (optional) - Expected match count"
}
}
4. Helpful Error Messages
// BAD
{"error": "Failed"}
// GOOD
{
"error": "FileNotFoundError",
"message": "File 'config.json' not found. Available files in current directory: package.json, tsconfig.json, src/"
}
const response = query({
prompt: "Clean up the temp directory",
options: {
allowedTools: ["Read", "Bash", "Glob"],
// Custom permission gate
canUseTool: async (toolName, input) => {
// Allow read-only operations
if (["Read", "Glob", "Grep"].includes(toolName)) {
return { behavior: "allow" };
}
// Block destructive commands
if (toolName === "Bash") {
const dangerous = ["rm -rf", "dd if=", "> /dev/"];
if (dangerous.some(p => input.command?.includes(p))) {
return {
behavior: "deny",
message: "Destructive command blocked"
};
}
}
// Ask user for anything else
return {
behavior: "ask",
message: `Allow ${toolName}?`
};
}
}
});
SDK Insight: Three Permission Behaviors
canUseTool returns one of three decisions: allow (auto-execute), deny (block with message), or ask (request human confirmation). This is the foundation of safe agent design — you'll expand this pattern extensively in P11 (HITL).
Model Context Protocol (MCP)
MCP is a tool standardization protocol proposed by Anthropic that lets different agents share tools:
// MCP Tool Definition
{
"name": "github_create_issue",
"server": "github-mcp",
"description": "Create a GitHub issue",
"inputSchema": {
"type": "object",
"properties": {
"repo": {"type": "string"},
"title": {"type": "string"},
"body": {"type": "string"}
}
}
}
MCP advantages:
- Reusable tools
- Cross-agent compatibility
- Standardized interface
- Rich ecosystem
Safety Considerations
- Sandboxed execution - Limit the tool runtime environment
- Permission control - Distinguish read-only vs writable tools
- Confirmation mechanism - Dangerous actions require user confirmation
- Audit logs - Record all tool calls
- Rate limits - Prevent runaway loops
Next Steps
- Memory Systems - How tool results are stored
- Planning - How to plan tool call sequences
- OpenClaw Tools - View the full tool catalog
Try It: Tool Permission Gate
Build a permission-controlled agent that logs every tool call and blocks dangerous operations.
- Create an agent with
allowedTools: ["Read", "Bash", "Glob"] - Implement
canUseToolthat logs every tool request to console - Block any Bash command containing
rmorsudo - Ask the agent to "list all .ts files and count their lines"
- Observe the tool_call → tool_result cycle in the stream
canUseTool blocks dangerous ops, multi-tool sequences observed in stream.