Ship Your First MCP Tool in 30 Minutes
Everyone’s talking about MCP. Almost nobody has actually built one. Let’s fix that.
Real John here - I was going to take this week off, but got inspired with all the babble about MCP this and MCP that. But no one actually knows what they are doing or how to even create your own. Well, by the end of this week’s newsletter, you’ll create one and be able to use it in Claude. We make things WAY harder than they need to be because as engineers we are used to having to figure things out, make sure things are clean, and not break. The models are getting better everyday (yes DAILY), so go play… and have fun! 10 of Spades - if you know you know.
Everyone in the AI dev space is throwing around “MCP” like it’s been part of their vocabulary forever. Model Context Protocol this, MCP server that. I watched a demo last week where someone connected Claude to their database, their GitHub, and their Slack — all from the terminal — and it felt like magic.
It’s not magic. It’s plumbing. And once you build one yourself, the mystery evaporates completely.
I’m going to walk you through shipping your first MCP tool in about 30 minutes. Real code. No hand-waving. By the end, Claude will be able to call your custom function like it was born knowing about it.
What Even Is MCP?
Quick, no-fluff explanation: MCP (Model Context Protocol) is an open standard Anthropic shipped in late 2024. It lets AI tools like Claude Code connect to external systems — your database, your APIs, your custom logic — through a single standardized interface.
Before MCP, connecting Claude to GitHub required one custom integration. Connecting it to Slack required a different one. Every tool meant new glue code. MCP solves that with a universal connector layer. There are over 2,300 public MCP servers available as of right now, and every major AI coding tool — Claude Code, Cursor, Windsurf, VS Code — supports it.
But here’s the thing: most developers have only ever used MCP servers. They’ve never built one. And building one is how you actually understand what’s happening under the hood.
What We’re Building
A simple MCP tool that takes a URL and returns a summary of the page’s metadata (title, description, status code). Boring? Yes. Perfect for learning? Also yes. The pattern transfers to anything — querying your DB, hitting an internal API, reading a log file, whatever.
Prerequisites: Node.js 18+, Claude Code installed, 30 minutes.
Step 1: Scaffold the Project
mkdir my-first-mcp && cd my-first-mcp
npm init -y
npm install @modelcontextprotocol/sdk
The MCP SDK handles all the protocol boilerplate. You just define your tools.
Step 2: Write the Server
Create index.js:
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: "url-inspector",
version: "1.0.0",
});
server.tool(
"inspect_url",
"Fetches metadata from a URL: title, description, and HTTP status",
{ url: z.string().url() },
async ({ url }) => {
try {
const res = await fetch(url);
const html = await res.text();
const title = html.match(/<title>(.*?)<\/title>/i)?.[1] ?? "No title";
const desc = html.match(/<meta[^>]+name="description"[^>]+content="([^"]+)"/i)?.[1] ?? "No description";
return {
content: [
{
type: "text",
text: `Status: ${res.status}\nTitle: ${title}\nDescription: ${desc}`,
},
],
};
} catch (err) {
return {
content: [{ type: "text", text: `Error: ${err.message}` }],
isError: true,
};
}
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
That’s it. That’s a real MCP server. The server.tool() call registers your function, the Zod schema validates inputs, and the stdio transport is how Claude Code will talk to it.
Add "type": "module" to your package.json so ES imports work.
Step 3: Register It With Claude Code
claude mcp add --transport stdio url-inspector -- node /absolute/path/to/my-first-mcp/index.js
Verify it registered:
claude mcp list
You should see url-inspector in the list.
Step 4: Use It
Open a Claude Code session:
claude
Then just ask it:
“Use inspect_url to check what’s on https://cashcritters.com”
Claude will call your tool, get the response, and use it in its answer. Your code. Your tool. Running live inside an AI session.
What Just Happened
A few things worth internalizing:
You defined the interface, not the implementation. Claude doesn’t know how your tool works — it just knows the name, description, and input schema. You control what runs underneath.
The description is the most important line you wrote. Claude decides when to call your tool based on that string. Write it like you’re explaining to a smart junior dev what this function does and when to reach for it.
Stdio transport means local only. For a production MCP server that multiple people or agents can hit, you’d switch to SSE (Server-Sent Events) transport and host it somewhere. Vercel works fine for this. But for personal tooling or team-local tools, stdio is perfect.
Where To Go From Here
Once you have the pattern down, the interesting tools are obvious:
Query your own database — give Claude direct read access to your schema so it stops hallucinating column names
Internal API wrapper — expose your company’s internal APIs as MCP tools so Claude can pull real data in context
Log parser — tail your Vercel function logs and surface errors on demand
StatusSage integration — I’ve been wiring up my own projects to MCP so Claude can check status and incidents without me copy-pasting anything
The pattern is always the same: define the tool, write the logic, register it. Everything else is just what you point it at.
The best way to understand any abstraction is to build one layer below it. MCP seemed like magic until I wrote my first server. Now it’s just a function with a description attached. That’s the whole thing.
Go build something amazing.
John Mann is the founder of Startups and Code LLC, former CTO, and the guy who built Cash Critters for $50/month because constraints are a feature, not a bug. Subscribe for weekly takes on AI, startups, and building things that matter.



