MCP

Registering Tools

Expose custom tools to your agent via MCP.

Registering Tools

Register custom tools on your MCP server to expose them to any connected agent. Each tool needs a name, description, and a JSON Schema for its input.

Tool Definitions

Define tools in your server config or in code using the MCP server SDK. The description is especially important — the model uses it to decide when to call the tool.

Versioning

Tools are versioned alongside your MCP server. When you change a tool’s schema, bump the server version to avoid breaking existing agent runs.

Anatomy of a tool definition

An MCP tool has three parts: a name (snake_case, unique per server), a description (natural language, used by the model to decide when to call it), and an inputSchema (JSON Schema defining the tool’s input parameters).

TypeScript example

import { McpServer } from ‘@modelcontextprotocol/sdk/server/mcp.js’; import { z } from ‘zod’; const server = new McpServer({ name: ‘my-tools’, version: ‘1.0.0’ }); server.tool( ‘search_docs’, ‘Search the internal documentation and return the top 3 most relevant pages.’, { query: z.string().describe(‘The search query’) }, async ({ query }) => { const results = await searchDocs(query); return { content: [{ type: ‘text’, text: JSON.stringify(results) }] }; } );

Writing good descriptions

The tool description is the single most important thing you control for tool quality. The model reads it to decide whether to use the tool and how to construct its input.

A good description answers: what does this tool do, when should it be used (and when should it not be), what are the inputs, and what does the output look like.

Input schema best practices

Every parameter should have a description. Use enums to constrain string inputs where possible. Mark required fields explicitly. Avoid overly complex nested schemas — simpler inputs lead to fewer tool call errors.

Error handling in tools

Return structured error information rather than throwing exceptions. MCP tools should return a content array with an isError flag set to true and a message the agent can reason about:

return { content: [{ type: ‘text’, text: ‘File not found: src/missing.ts’ }], isError: true };

On this page

Create a free website with Framer, the website builder loved by startups, designers and agencies.