import { z } from "zod"
import { tool , serve } from "@reminix/runtime"
const getWeather = tool ( "get-weather" , {
description: "Get current weather for a city" ,
inputSchema: z . object ({
location: z . string (). describe ( "City name" ),
units: z . enum ([ "celsius" , "fahrenheit" ]). describe ( "Temperature units" ). optional (),
}),
handler : async ({ location , units }) => {
return { temperature: 72 , condition: "sunny" , location }
},
})
serve ({ tools: [ getWeather ] })
When deployed, your tools are automatically served via MCP and discoverable by any MCP-compatible client.
Tool description. Shown in MCP discovery and used by AI models to understand when to call the tool.
inputSchema
ZodType | JSONSchema
required
Zod schema (recommended) or JSON Schema defining the tool’s input parameters. Zod schemas provide typed handlers and automatic runtime validation.
Zod schema or JSON Schema defining the tool’s output. Optional but recommended for documentation.
Tags for filtering and organizing tools.
Additional metadata attached to the tool.
The tool’s handler function. Receives (args, context?) and returns the tool’s output. When using Zod, args is fully typed.
Define input parameters with Zod. Required fields, types, descriptions, and defaults are all supported.
import { z } from "zod"
const searchDocs = tool ( "search-docs" , {
description: "Search the document index" ,
inputSchema: z . object ({
query: z . string (). describe ( "Search query" ),
maxResults: z . number (). default ( 10 ). describe ( "Max results to return" ),
filters: z . object ({
category: z . string (). optional (),
dateRange: z . string (). optional (),
}). optional (). describe ( "Optional filters" ),
}),
handler : async ({ query , maxResults , filters }) => {
return [{ title: "Result 1" , score: 0.95 }]
},
})
Output Schema
Optional but recommended. Defines the shape of the tool’s return value for documentation and validation.
import { z } from "zod"
const getWeather = tool ( "get-weather" , {
description: "Get weather" ,
inputSchema: z . object ({
location: z . string (),
}),
outputSchema: z . object ({
temperature: z . number (),
condition: z . string (),
}),
handler : async ({ location }) => {
return { temperature: 72 , condition: "sunny" }
},
})
Context Parameter
Tools can receive execution context as the second argument, providing access to the caller’s identity and metadata.
import { z } from "zod"
const myTool = tool ( "my-tool" , {
description: "Tool with context" ,
inputSchema: z . object ({
query: z . string (),
}),
handler : async ({ query }, context ? ) => {
const identity = context ?. identity
return { result: query , user: identity }
},
})
Tools and agents can be served together from the same server. Agents get REST endpoints while tools are served via MCP.
import { z } from "zod"
import { agent , tool , serve } from "@reminix/runtime"
const bot = agent ( "bot" , {
type: "chat" ,
handler : async ( input ) => "Hello!" ,
})
const search = tool ( "search" , {
description: "Search for information" ,
inputSchema: z . object ({ query: z . string () }),
handler : async ({ query }) => [{ result: query }],
})
serve ({ agents: [ bot ], tools: [ search ] })
MCP compatibility
When deployed, your tools are automatically served via the Model Context Protocol (MCP) . Any MCP-compatible client — including Claude Desktop, custom MCP clients, and other Reminix agents — can discover and call your tools.
MCP is an open standard for connecting AI models to tools and data sources. Your Reminix tools work with any client that speaks MCP.
Next steps
Tools (concept) How tools become MCP servers and how clients discover them.
Connecting MCP clients Add your tools to Claude Desktop, Cursor, and Windsurf.
Creating Agents Define agents that call your tools internally.
Deploying Ship your tools to production.