How to Create MCP Tools for Claude and AI Assistants
How to Create MCP Tools for Claude and AI Assistants
To create MCP (Model Context Protocol) tools: 1) Define your tool schema with name, description, and parameters, 2) Implement the handler function, 3) Register it with an MCP server. Claude, OpenClaw, and other AI assistants can then use your custom tools.
Quick Answer
MCP is an open protocol that lets AI assistants use external tools and access data sources. Creating an MCP tool involves defining what the tool does (schema) and how it does it (handler).
The protocol is gaining adoption in 2026 as the standard way to extend AI capabilities.
Basic MCP Tool Structure
Every MCP tool needs:
- Name - Unique identifier (e.g.,
get_weather) - Description - What the tool does (AI reads this)
- Parameters - Input schema (JSON Schema format)
- Handler - Function that executes the tool
Step 1: Define Your Tool Schema
const weatherTool = {
name: "get_weather",
description: "Get current weather for a location. Use this when the user asks about weather conditions.",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "City name or coordinates"
},
units: {
type: "string",
enum: ["celsius", "fahrenheit"],
default: "celsius"
}
},
required: ["location"]
}
};
Step 2: Implement the Handler
async function handleGetWeather(params: { location: string; units?: string }) {
const { location, units = "celsius" } = params;
// Call your weather API
const response = await fetch(
`https://api.weather.com/current?q=${location}&units=${units}`
);
const data = await response.json();
return {
location: data.location.name,
temperature: data.current.temp,
conditions: data.current.condition.text,
humidity: data.current.humidity
};
}
Step 3: Create an MCP Server
Using the official MCP SDK:
import { Server } from "@modelcontextprotocol/sdk/server";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";
const server = new Server({
name: "weather-server",
version: "1.0.0"
});
// Register your tool
server.setRequestHandler("tools/list", async () => ({
tools: [weatherTool]
}));
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "get_weather") {
const result = await handleGetWeather(request.params.arguments);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
}
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Step 4: Register with Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/path/to/your/weather-server.js"]
}
}
}
MCP Tool Best Practices
Write Clear Descriptions
The AI reads your description to decide when to use the tool:
// ❌ Bad
description: "Gets weather"
// ✅ Good
description: "Get current weather conditions including temperature, humidity, and forecast for any city worldwide. Use when user asks about weather, temperature, or if they should bring an umbrella."
Handle Errors Gracefully
async function handleTool(params) {
try {
const result = await doSomething(params);
return { success: true, data: result };
} catch (error) {
return {
success: false,
error: `Failed to process: ${error.message}`
};
}
}
Keep Responses Concise
AI context windows are limited. Return only essential data:
// ❌ Returns entire API response
return apiResponse;
// ✅ Returns only what's needed
return {
temperature: apiResponse.current.temp_c,
conditions: apiResponse.current.condition.text
};
Common MCP Tool Types
| Type | Example | Use Case |
|---|---|---|
| Data fetch | get_stock_price | Real-time information |
| Search | search_documents | RAG/knowledge base |
| Action | send_email | Execute operations |
| Calculation | convert_currency | Complex computations |
| Integration | create_github_issue | Connect to services |
Tools That Work with MCP
- Claude Desktop - Native MCP support
- OpenClaw - Full MCP integration
- LangFlow - MCP support built-in
- Continue - IDE with MCP tools
- Cline - VS Code extension
Example: Complete File Reader Tool
import { Server } from "@modelcontextprotocol/sdk/server";
import { readFile } from "fs/promises";
const server = new Server({ name: "file-reader", version: "1.0.0" });
server.setRequestHandler("tools/list", async () => ({
tools: [{
name: "read_file",
description: "Read contents of a text file. Provide the full path.",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "Full file path" }
},
required: ["path"]
}
}]
}));
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "read_file") {
try {
const content = await readFile(request.params.arguments.path, "utf-8");
return { content: [{ type: "text", text: content }] };
} catch (e) {
return { content: [{ type: "text", text: `Error: ${e.message}` }] };
}
}
});
Related Questions
- What is MCP (Model Context Protocol)?
- How to build an AI agent?
- Best AI tools for developers?
Last verified: 2026-03-04