MCP Protocol

Build Your First MCP Server In 50 Lines

All articles
🔌🪄

Behold: One File. Real Tool Calling.

People act like MCP is some sprawling enterprise framework. Behold: a full working server in fifty lines of TypeScript. If you can write an Express handler, you can write an MCP tool.

The Setup

Install the SDK and Zod. The SDK handles JSON-RPC framing, schema discovery, and the lifecycle handshake. You write tools. That's the deal.

{`npm install @modelcontextprotocol/sdk zod
mkdir -p src && touch src/server.ts`}

The Money Pattern

One file. One tool. The model can now check the weather, fetch a Pipedrive deal, or run a BigQuery query — swap the handler body and you're done.

{`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: "weather-mcp",
  version: "0.1.0",
});

server.tool(
  "get_weather",
  "Get current weather for a city",
  { city: z.string().describe("City name, e.g. Brisbane") },
  async ({ city }) => {
    const res = await fetch(
      \`https://wttr.in/\${encodeURIComponent(city)}?format=j1\`
    );
    const data = await res.json();
    const current = data.current_condition[0];
    return {
      content: [
        {
          type: "text",
          text: \`\${city}: \${current.temp_C}°C, \${current.weatherDesc[0].value}\`,
        },
      ],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("weather-mcp running on stdio");`}

The Catch

Stdio is fussy. Anything you print to stdout that isn't JSON-RPC kills the connection — that's why the log goes to stderr. Use the MCP Inspector (npx @modelcontextprotocol/inspector node dist/server.js... fine, run it directly, I know the rule) because guessing why your tool isn't appearing is misery. Also, ESM is mandatory. Set "type": "module" in package.json or watch it explode.

The Verdict

MCP servers are smaller than your average Tailwind config. The barrier to building one is now lower than writing a custom OpenAI function. If you've got an internal API, wrap it in MCP this week — your future agents will thank you.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.