Adding Tools & Schemas
1. Defining Argument Structs
Section titled “1. Defining Argument Structs”In Go, define your tool arguments using standard Go structs with jsonschema tags:
type QueryDatabaseArgs struct { Query string `json:"query" jsonschema:"The SQL query or search keyword to execute"` Limit int `json:"limit,omitempty" jsonschema:"Optional maximum number of records to return (default: 20)"` Category string `json:"category,omitempty" jsonschema:"Optional domain category filter"`}The Go SDK automatically inspects these struct tags to generate OpenAPI/JSON Schema metadata for connecting LLMs.
2. Implementing the Handler
Section titled “2. Implementing the Handler”Tool handlers must conform to the standard signature:
func queryDatabaseHandler(ctx context.Context, req *mcp.CallToolRequest, args QueryDatabaseArgs) (*mcp.CallToolResult, *QueryDatabaseResult, error) { if strings.TrimSpace(args.Query) == "" { return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: "Error: query parameter is required."}, }, IsError: true, }, nil, nil }
result := &QueryDatabaseResult{ ... }
// Dual-Emit: Markdown for general LLMs + typed JSON struct for programmatic agents return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: formatMarkdown(result)}, }, }, result, nil}3. Registering the Tool in mcp.go
Section titled “3. Registering the Tool in mcp.go”Use mcp.AddTool to register your tool with human-readable titles, descriptions, and read-only annotations:
mcp.AddTool(server, &mcp.Tool{ Name: "query_database", Title: "Query Database", Description: "Executes structured queries against the operational datastore.", Annotations: &mcp.ToolAnnotations{ReadOnlyHint: true},}, queryDatabaseHandler)