How to Build Your First MCP Tool: A Practical Guide
MCP (Model Context Protocol) is quickly becoming the standard way to extend what LLMs can do. Instead of embedding tool logic in your prompts, you define a clean interface that any MCP-compatible client can discover and call. The result: agents that can actually do things, not just describe them.
This is a hands-on guide to building your first MCP tool - a timezone time checker, wired end-to-end in under 20 minutes.
What is MCP?
MCP is an open protocol that defines how AI clients and tool servers communicate. Think of it like USB for AI tools: any MCP client (Claude Desktop, Cursor, your custom agent) can connect to any MCP server without custom integration code. An MCP server exposes tools - each with a name, description, and JSON schema for inputs. The client calls the tool with matching arguments, the server executes and returns a result.
Step 1: Set up the project
mkdir my-mcp-tool && cd my-mcp-tool
npm init -y
npm install @modelcontextprotocol/sdk zodStep 2: Create the server
Create index.ts and define a get_time tool that returns the current time for any IANA timezone.
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new McpServer({ name: 'time-tool', version: '1.0.0' });
server.tool(
'get_time',
'Get the current time for a given IANA timezone',
{ timezone: z.string().describe('e.g. Europe/Amsterdam') },
async ({ timezone }) => {
const time = new Intl.DateTimeFormat('en-US', {
timeZone: timezone,
dateStyle: 'full',
timeStyle: 'long',
}).format(new Date());
return { content: [{ type: 'text', text: `Current time in : ` }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);Step 3: Wire it up to Claude Desktop
Add your server to the Claude Desktop config file. On Mac: ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows: %APPDATA%\Claude\claude_desktop_config.json.
{"mcpServers":{"time-tool":{"command":"node","args":["/absolute/path/to/my-mcp-tool/index.js"]}}}Restart Claude Desktop. Ask it: 'What time is it in Tokyo?' and watch it call your tool.
What makes a good MCP tool?
Clear, specific description - the LLM uses your description to decide when to call it. Be precise about what it does, not just what it is.
Typed inputs with .describe() - use Zod or Pydantic to define your schema. Add .describe() to every field. The LLM reads these when constructing arguments.
Graceful error handling - return meaningful error messages, not stack traces. The agent will try to recover based on what you return.
Idempotency where possible - tools that can be safely retried work much better in agentic loops.
Your turn
This month at AIT Community we're running a challenge: build and share your first MCP tool. No minimum complexity requirement - just ship something that works and write up what you learned. Share it in the community forum. We'll feature the best submissions in the knowledge base.