Adding Tools
Tools are the primary way agents interact with external systems. Each tool provides a set of actions with defined parameter schemas, permission levels, and execution logic.
The BaseTool Pattern
Section titled “The BaseTool Pattern”All tools extend the BaseTool abstract class, which provides:
- Action registration: Define actions with names, descriptions, parameter schemas, and permission levels
- Permission enforcement: Automatic permission checks before action execution
- Error handling: Standardized error reporting
- Lifecycle management: Initialization and cleanup hooks
Creating a New Tool
Section titled “Creating a New Tool”-
Create the tool directory and file
Create
src/tools/mytool/index.ts:import { BaseTool } from '../base-tool';export class MyTool extends BaseTool {id = 'mytool';name = 'My Tool';description = 'Description of what this tool does';tools = [{name: 'my_action',description: 'What this action does',parameters: {type: 'object',properties: {input: {type: 'string',description: 'The input parameter'}},required: ['input']},permissions: {action: 'execute',level: 'ASK' // ALLOW, ASK, or DENY}}];async execute(toolName: string, args: Record<string, unknown>) {switch (toolName) {case 'my_action':return this.myActionHandler(args);default:throw new Error(`Unknown action: ${toolName}`);}}private async myActionHandler(args: Record<string, unknown>) {const input = args.input as string;// Your implementation herereturn { result: `Processed: ${input}` };}} -
Define action parameter schemas
Action parameters use JSON Schema format. The schema is provided to the LLM so it knows how to call your tool:
parameters: {type: 'object',properties: {path: {type: 'string',description: 'The file path to operate on'},recursive: {type: 'boolean',description: 'Whether to operate recursively',default: false}},required: ['path']} -
Register the tool
Add your tool to the tool registry in
src/tools/registry.ts:import { MyTool } from './mytool';// In the registry initialization:registry.register(new MyTool()); -
Enable the tool
Add your tool ID to the
ENABLED_TOOLSenvironment variable:ENABLED_TOOLS=filesystem,shell,git,browser,websearch,docker,mytool
Permission Levels
Section titled “Permission Levels”Each action should specify an appropriate permission level:
| Level | When to Use |
|---|---|
| ALLOW | Read-only operations, safe queries |
| ASK | Write operations, network requests, anything with side effects |
| DENY | Dangerous operations that should never run automatically |
Best Practices
Section titled “Best Practices”- Keep actions focused: Each action should do one thing well
- Descriptive parameters: LLMs rely on parameter descriptions to use actions correctly
- Appropriate permissions: Default to
ASKfor anything with side effects - Error handling: Return meaningful error messages that help the LLM recover
- Idempotency: Where possible, make actions idempotent so retries are safe
- Validation: Validate all inputs before executing operations
Existing Tools as Reference
Section titled “Existing Tools as Reference”Study the built-in tools for patterns and conventions:
| Tool | Path | Good Example Of |
|---|---|---|
filesystem | src/tools/filesystem/ | Multiple actions, read/write permissions |
shell | src/tools/shell/ | Background execution, elevated permissions |
git | src/tools/git/ | Complex multi-action tool |
browser | src/tools/browser/ | External dependency (Playwright) |
websearch | src/tools/websearch/ | Multi-tier fallback strategy |
docker | src/tools/docker/ | System-level operations |
github | src/tools/github/ | REST API integration |
google-workspace | src/tools/google-workspace/ | Multi-service OAuth tool |