DEV Community

Marco Arras
Marco Arras

Posted on

What is MCP? A Developer's Guide with Working Code

MCP stands for Model Context Protocol. It's an open standard that defines how AI models connect to external tools and data sources.

Before MCP, every AI platform had its own way of doing tool integration. OpenAI had function calling. LangChain had its own tool format. Every agent framework invented its own interface. Build a tool for one system, it didn't work anywhere else.

MCP fixes this. One protocol. Any client. Any tool server. Build once, work everywhere.

The architecture in 30 seconds

┌─────────┐     MCP Protocol     ┌─────────────┐     Your Code     ┌──────────┐
│  Client  │ ◄──────────────────► │  MCP Server  │ ◄────────────────► │  APIs /   │
│ (Claude) │                      │  (your code) │                    │  Data     │
└─────────┘                       └─────────────┘                    └──────────┘
Enter fullscreen mode Exit fullscreen mode

Client — The AI application. Claude Desktop, an IDE with AI, or any app that speaks MCP.

Server — Your code. A program that exposes tools, resources, and prompts to the client.

Transport — How they talk. stdio (local, stdin/stdout) or HTTP/SSE (remote, over the network).

The client discovers what your server offers, then calls your tools when the model decides it needs them.

What a tool looks like

A tool is a function with a name, a description, an input schema, and a handler:

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(
  "generate_uuid",
  "Generate a random UUID",
  {},
  async () => ({
    content: [{ type: "text", text: crypto.randomUUID() }],
  })
);
Enter fullscreen mode Exit fullscreen mode

15 lines. When Claude connects to this server, it sees a tool called generate_uuid. When a user asks for a unique ID, Claude calls this tool and returns the result.

The description matters more than you'd think. It's how the model decides when to use your tool. Write it for Claude, not for humans. Be specific about what the tool does and when it's useful.

Input schemas with Zod

Most tools need input. MCP uses JSON Schema to define inputs, and the SDK uses Zod to generate it from TypeScript:

server.tool(
  "get_stock_quote",
  "Get the latest stock price for a given ticker symbol",
  {
    ticker: z.string().describe("Stock ticker symbol, e.g. AAPL"),
  },
  async ({ ticker }) => {
    const res = await fetch(
      `https://api.polygon.io/v2/aggs/ticker/${ticker}/prev?apiKey=${process.env.POLYGON_API_KEY}`
    );
    const data = await res.json();
    const result = data.results[0];

    return {
      content: [{
        type: "text",
        text: [
          `${ticker} — Previous Close`,
          `Open: $${result.o}`,
          `High: $${result.h}`,
          `Low: $${result.l}`,
          `Close: $${result.c}`,
          `Volume: ${result.v.toLocaleString()}`,
        ].join("\n"),
      }],
    };
  }
);
Enter fullscreen mode Exit fullscreen mode

Claude sees: "This server has a tool called get_stock_quote that takes a ticker string and returns stock price data."

User says: "What's Apple's stock price?"

Claude calls get_stock_quote with ticker: "AAPL".

The Zod schema does double duty: validates input at runtime (Claude can't send garbage) and generates JSON Schema so the model knows what format to use.

The connection flow

Here's what happens when Claude Desktop connects to your MCP server:

  1. Launch — Claude starts your server as a subprocess
  2. Initialize — Your server sends capabilities: name, version, available tools
  3. Discovery — Claude reads the tool list and descriptions
  4. Conversation — User talks to Claude. Claude decides when to call your tools.
  5. Tool call — Claude sends: { tool: "get_stock_quote", input: { ticker: "AAPL" } }
  6. Response — Your handler runs, returns content. Claude uses it in its response.

Steps 4–6 repeat as needed. Claude might call one tool or chain five together.

How MCP compares to function calling

If you've used OpenAI's function calling, MCP might seem familiar. Key differences:

Function Calling MCP
Scope Single API provider Universal protocol
Discovery Defined per request Server advertises capabilities
Transport HTTP only stdio, HTTP, SSE
Packaging Not standardized npm packages, shared configs
Ecosystem Locked to one provider Works with any MCP client

Function calling is "here are the tools for this conversation." MCP is "here's a server full of capabilities that any client can discover and use."

The complete 40-line server

Here's a complete, working MCP server. This is real — you can run this today:

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: "starter-tools",
  version: "0.1.0",
});

server.tool(
  "generate_uuid",
  "Generate a random UUID",
  {},
  async () => ({
    content: [{ type: "text", text: crypto.randomUUID() }],
  })
);

server.tool(
  "timestamp",
  "Get the current time in multiple formats",
  {},
  async () => {
    const now = new Date();
    return {
      content: [{
        type: "text",
        text: [
          `ISO: ${now.toISOString()}`,
          `Unix: ${Math.floor(now.getTime() / 1000)}`,
          `Human: ${now.toLocaleString()}`,
        ].join("\n"),
      }],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
Enter fullscreen mode Exit fullscreen mode

Save as src/index.ts. Add to your Claude Desktop config:

{
  "mcpServers": {
    "starter-tools": {
      "command": "npx",
      "args": ["tsx", "src/index.ts"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude. You have a working agent with two tools.

The rest is about making those tools useful, reliable, and shippable.


This is Part 2 of a free 3-part series on MCP.

Part 3 covers the opportunity — where the gaps are in the ecosystem, how to go from open source package to paid product, and the actual revenue math.

The full course — **Build & Ship MCP Tools* — takes you from your first tool to a published npm package. 7 modules, 33 lessons.*

Get early access for $29

Top comments (0)