Skip to content

Tools & MCP

Tool registration middleware. Define TypeScript function tools with Zod schema validation, or connect to MCP servers for external tool discovery.

Creates function tools with Zod schemas for input validation and JSON Schema generation.

function toolsFunction(defs: ToolDef | ToolDef[]): Middleware
import { tools } from "agent-express"
import { z } from "zod"
agent.use(tools.function({
name: "get_weather",
description: "Get current weather for a city",
schema: z.object({
city: z.string().describe("City name"),
units: z.enum(["celsius", "fahrenheit"]).optional(),
}),
execute: async ({ city, units }) => {
const data = await fetchWeather(city, units)
return `${data.temp} degrees in ${city}`
},
}))

Accepts a single ToolDef or an array:

agent.use(tools.function([weatherTool, searchTool, calculatorTool]))

Hooks: agent — registers tools via ctx.registerTool() before next().

ToolDef options:

OptionTypeDefaultDescription
namestringrequiredTool name sent to the LLM
descriptionstringrequiredDescription for the LLM
schemaZodSchemarequiredZod schema for input validation and JSON Schema generation
execute(args, ctx) => Promise<unknown>requiredExecution function
timeoutnumber30000Max execution time in ms
requireApprovalboolean | (args) => boolean | Promise<boolean>undefinedWhether to require HITL approval

Connects to an MCP (Model Context Protocol) server, discovers its tools, and registers them on the agent. Requires @modelcontextprotocol/sdk as a peer dependency.

function mcpTools(config: McpServerConfig): Middleware
// Local process via stdio
agent.use(tools.mcp({
name: "crm",
transport: "stdio",
command: "npx",
args: ["-y", "@acme/crm-mcp"],
}))
// Remote server via HTTP
agent.use(tools.mcp({
name: "docs",
transport: "http",
url: "https://mcp.example.com",
headers: { Authorization: "Bearer token" },
}))
// SSE transport
agent.use(tools.mcp({
name: "search",
transport: "sse",
url: "https://sse.example.com/mcp",
}))

One server per .use() call. For multiple servers, call .use() multiple times.

Common options:

OptionTypeDefaultDescription
namestringrequiredServer identifier for debugging and tool name disambiguation
requireApprovalboolean | string[] | (toolName, args) => boolean | Promise<boolean>undefinedWhich tools require human approval. string[] supports glob patterns (e.g., "delete_*").

Transport options (discriminated union on the transport field):

TransportOptions
stdiocommand, args?, env?
httpurl, headers?, timeout?
sseurl, headers?, timeout?

Hooks: agent — connects on init, discovers and registers tools, disconnects on dispose.

Approval for MCP tools:

agent.use(tools.mcp({
name: "crm",
transport: "stdio",
command: "npx",
args: ["-y", "@acme/crm-mcp"],
requireApproval: true, // all tools
// or: requireApproval: ["delete_*", "drop_*"] // glob patterns
// or: requireApproval: (toolName, args) => toolName.startsWith("delete")
}))

The MCP client connects during agent.init() and disconnects during agent.dispose().