Custom Tools
Conform to ToolProvider directly to expose any Swift function as a callable tool. The protocol has two requirements: listTools (declare what exists) and call (execute by name).
For a full explanation of AgentTool, ToolResult, ToolVisibility, and JSONValue, see Tools Overview.
Single-tool provider
Section titled “Single-tool provider”The minimal pattern — one struct, one tool:
import AgentSquad
struct WeatherToolProvider: ToolProvider { func listTools() async throws -> [AgentTool] { [ AgentTool( name: "get_weather", description: "Returns current weather for a city.", inputSchema: [ "type": "object", "properties": [ "city": ["type": "string", "description": "City name"] ], "required": ["city"] ] ) ] }
func call(_ name: String, arguments: JSONValue) async throws -> ToolResult { guard name == "get_weather" else { return .failure("Unknown tool: \(name)") } guard case .string(let city) = arguments["city"] else { return .failure("Missing required argument: city") } // ... call your API ... let summary = "Sunny, 22 °C" return ToolResult( content: [.text(summary)], structuredContent: ["city": .string(city), "summary": .string(summary)] ) }}Pass the provider when constructing an agent — see Agents Overview.
Composing multiple providers
Section titled “Composing multiple providers”You don’t need to hand-write a composite — AggregateToolProvider is built in. It fans out listTools in parallel, deduplicates by name (first-wins), and routes each call to the owning provider:
let tools = AggregateToolProvider([ myCustomProvider, ToolKit([localTool, apiTool]), MCPServer(url: "https://mcp/sse"),])Controlling visibility
Section titled “Controlling visibility”Use ToolVisibility to restrict who can invoke a tool:
AgentTool( name: "internal_audit_log", description: "Records an audit event.", visibility: .app // never offered to the model; only callable by host code)| Value | Effect |
|---|---|
.model | LLM may call it; host code may not |
.app | Host code may call it; never offered to the LLM |
.all | Both (default) |
Using MCP tools alongside native tools
Section titled “Using MCP tools alongside native tools”MCP-backed tools arrive as a ToolProvider (MCPServer) from the AgentSquadMCP module. Combine them with your native tools using AggregateToolProvider:
let tools = AggregateToolProvider([ nativeProvider, // your custom ToolProvider MCPServer(url: "https://mcp/sse"), // from AgentSquadMCP])See MCP servers for session setup. To plug a different MCP SDK or transport, conform your own type to MCPClient — see Custom MCP client.