This guide explains how to selectively enable built-in tools and register custom tools in agentsdk-go, while keeping backward compatibility and simplicity.
Every custom tool must implement tool.Tool:
type Tool interface {
Name() string
Description() string
Schema() *JSONSchema
Execute(ctx context.Context, params map[string]any) (*ToolResult, error)
}Options.Tools []tool.Tool
Legacy field. When non-empty it fully overrides the tool set, ignoring other tool options (backward compatible).Options.EnabledBuiltinTools []string
Controls the built-in whitelist (case-insensitive):nil(default): register all built-ins- empty slice: disable all built-ins
- non-empty: enable only the listed built-ins
Available names (lowercase):bash,read,write,edit,glob,grep,skill.
Options.CustomTools []tool.Tool
Appends custom tools whenToolsis empty (nil entries are skipped).
Priority: Tools > (EnabledBuiltinTools filtering + CustomTools append).
opts := api.Options{
ProjectRoot: ".",
ModelFactory: provider,
EnabledBuiltinTools: []string{"bash", "grep", "read"}, // enable only these
}
rt, _ := api.New(context.Background(), opts)opts := api.Options{
ProjectRoot: ".",
ModelFactory: provider,
EnabledBuiltinTools: []string{}, // register no built-ins
CustomTools: []tool.Tool{&EchoTool{}}, // custom only
}opts := api.Options{
ProjectRoot: ".",
ModelFactory: provider,
// nil means all built-ins stay enabled
CustomTools: []tool.Tool{&EchoTool{}},
} opts := api.Options{
ProjectRoot: ".",
ModelFactory: provider,
EnabledBuiltinTools: []string{"bash", "read"},
CustomTools: []tool.Tool{&CalculatorTool{}},
}type EchoTool struct{}
func (t *EchoTool) Name() string { return "echo" }
func (t *EchoTool) Description() string { return "returns the input text" }
func (t *EchoTool) Schema() *tool.JSONSchema {
return &tool.JSONSchema{
Type: "object",
Properties: map[string]any{
"text": map[string]any{"type": "string", "description": "text to echo"},
},
Required: []string{"text"},
}
}
func (t *EchoTool) Execute(ctx context.Context, params map[string]any) (*tool.ToolResult, error) {
return &tool.ToolResult{Output: fmt.Sprint(params["text"])}, nil
}- Name matching is case-insensitive;
-or spaces are treated as_. Prefer the listed lowercase forms. - MCP tools are registered by default; when MCP server config includes
enabledTools/disabledTools, registration is filtered accordingly. - When names collide, the first tool wins and a warning is logged to highlight the conflict.