Agents & MCP
Build a Model Context Protocol server that exposes clean tools and resources, with good schemas, error handling, and a testable transport.
1 file
Description
Build a Model Context Protocol server that exposes clean tools and resources, with good schemas, error handling, and a testable transport.
Creating an MCP server, adding a tool to one, or debugging why a client will not call your tool or gets a bad result.
An MCP tool is a function the model chooses to call. The name and description are prompt engineering, not documentation.
search_orders, create_invoice. Not orders or invoiceTool.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: "orders", version: "1.0.0" });
server.tool(
"search_orders",
"Find orders by customer email. Use when the user asks about a specific customer's purchases.",
{ email: z.string().email(), limit: z.number().int().max(50).default(10) },
async ({ email, limit }) => {
const rows = await db.orders.findByEmail(email, limit);
return { content: [{ type: "text", text: JSON.stringify(rows) }] };
}
);
await server.connect(new StdioServerTransport());
Return errors as tool results the model can read, not thrown exceptions that kill the transport. On failure return { content: [{ type: "text", text: "No customer found for that email." }], isError: true } so the model can recover.
console.log anywhere in a stdio server breaks it silently. Route all logging to stderr.Related
Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.