How to Build an MCP Server
A Step-by-Step 2026 Tutorial, With a Full Working Code Example
If you are wondering how to build an MCP server, the short answer is that it takes far less code than most developers expect. An MCP server is a small program that exposes tools, data, and prompts to an AI model such as Claude through the open Model Context Protocol. This tutorial walks through the architecture, the official SDKs, and a complete working example, so you can go from a blank folder to a tool that Claude can actually call in under an hour. Once it works locally, hosting an MCP server covers getting it into production.
Key Takeaways
- Building an MCP server mainly means defining tools with a typed schema and connecting them to a transport - no machine learning experience required
- Two transports cover almost every use case: stdio for local, single-client tools and Streamable HTTP for remote, multi-client deployments
- Official SDKs exist in ten languages, but TypeScript and Python have the most mature tooling and documentation
- The current spec (2025-11-25, with a 2026-07-28 release candidate in review) adds structured tool output, elicitation, and stronger OAuth-based authorization
MCP Server Development at a Glance, 2026
Sources: Model Context Protocol Specification, MCP Servers Repository, GitHub
What Is an MCP Server?
The Model Context Protocol (MCP) is an open standard, originally released by Anthropic in November 2024, that defines how an AI model requests information and takes action through an external program. An MCP server is that external program. It declares a set of tools, resources, and prompts, and it responds to requests from an MCP client - usually the application hosting the model, such as Claude Desktop, Claude Code, or an IDE like Cursor or VS Code.
In practice, an MCP server looks a lot like a small backend service. It has a name, it exposes a handful of functions with typed parameters, and it returns structured content. The difference from a typical internal API is that the function names, descriptions, and parameter schemas are written so a language model can read them and decide, on its own, which tool to call and when.
Why MCP Exists
Before MCP, every AI application that wanted to call a database, a ticketing system, or an internal tool needed a custom, one-off integration. MCP standardizes that connection once, so any MCP-compatible client can use any MCP server without custom glue code. For a full catalog of ready-made servers, see the Planetary Labour MCP servers directory, and for hardening a server before production, read the companion guide on MCP security best practices.
How Do MCP Servers Work?
Every MCP interaction follows the same lifecycle: a client launches or connects to a server, the two sides exchange capabilities during an initialization handshake, and then the client sends JSON-RPC 2.0 requests for as long as the session is open. Understanding this flow is the fastest way to understand MCP architecture as a whole.
The Two-Layer Architecture
MCP separates cleanly into a data layer and a transport layer. The data layer defines what gets said - the JSON-RPC messages, the tool and resource schemas, the capability negotiation. The transport layer defines how those messages physically travel between client and server.
Data Layer
The data layer is transport-agnostic. It covers the JSON-RPC 2.0 message format, the initialize handshake where client and server agree on a protocol version, and the three core primitives a server can expose: tools, resources, and prompts. Because this layer never changes based on how the bytes are transmitted, a server written against the stdio transport can be moved to Streamable HTTP with almost no changes to its business logic.
Transport Layer
The transport layer is where the client and server actually exchange bytes. MCP standardizes two transports, and choosing between them is one of the first real decisions when you build an MCP server.
stdio Transport
With stdio, the client launches the server as a local subprocess and communicates over standard input and output, with each JSON-RPC message on its own line. There is no network hop, so latency is minimal and there is nothing to deploy. This is the default choice for developer tools such as Claude Desktop and Claude Code, and it is the transport used in almost every getting-started tutorial.
When to reach for stdio
Use stdio when the server and client run on the same machine, when only one client needs to connect at a time, and when you are still prototyping. It is the fastest way to go from zero to a working tool call.
Streamable HTTP Transport
Streamable HTTP replaced the older HTTP-plus-SSE transport in the 2025-03-26 revision of the spec. The server runs as an independent, long-lived process that accepts HTTP POST requests and can stream responses back using Server-Sent Events. Because it runs over standard HTTP, it supports bearer tokens, API keys, and OAuth-based authorization, and a single deployment can serve many clients at once - which is the shape most production and remote MCP servers use today.
How a Tool Call Actually Travels
The model decides a tool is needed, the client sends a tools/call request with the tool name and arguments as JSON, the server validates the arguments against the schema it registered, executes the underlying logic, and returns a content array back to the client. The model then reads that content as if it were part of the conversation. The whole exchange is just JSON-RPC 2.0 messages over whichever transport you chose.
MCP Server Architecture: Tools, Resources, and Prompts
Once the transport is settled, the actual architecture of an MCP server comes down to three primitives. Almost every server you will build or read about is some combination of these three building blocks.
Core Primitives
Tools
Tools are functions the model can call to take action or fetch information - querying a database, sending a message, running a calculation. Each tool has a name, a human-readable description, and an input schema (usually JSON Schema, generated from Zod in TypeScript or Pydantic in Python). The quality of the description and schema directly affects how reliably the model chooses the right tool at the right time.
Tool Naming Conventions
Effective tool names are short, lowercase, and use underscores rather than spaces - get_forecast rather than Get The Weather Forecast For A City. Descriptions should state exactly what the tool does and when to use it, since that description is the only context the model has for deciding whether the tool is relevant.
Example Tool Schema
A well-formed tool definition names every parameter, marks which ones are required, and constrains types wherever possible - for example, restricting a days parameter to the integer range 1 through 7, rather than accepting any free-form number.
Resources
Resources expose read-only data through a URI, similar to a GET endpoint - a file, a database row, or a configuration document. Clients can list available resources and fetch their content, giving the model a way to pull in context without that data being force-fed into every conversation.
Prompts
Prompts are reusable, parameterized templates that a server exposes so a client can turn them into a ready-made message - useful for standardizing common workflows such as a code review checklist or a support-ticket triage prompt across every user of the server.
Architecture Tip
Keep each tool doing one job. A server with ten narrow, well-described tools is easier for a model to use correctly than a server with two broad tools that accept a dozen optional parameters. This is the same single-responsibility principle that applies to well-designed REST endpoints.
MCP Client SDKs: Choosing Your Language
Every MCP server needs an SDK on both sides of the connection: a server SDK to define tools and handle the protocol, and a client SDK (built into applications such as Claude Desktop, Claude Code, and most modern IDEs) to send requests and render results. As of 2026, Anthropic and the open source community maintain official SDKs for ten languages.
| Language | Package | Best For |
|---|---|---|
| TypeScript | @modelcontextprotocol/sdk | Node.js tooling, web integrations, the largest example base |
| Python | mcp (FastMCP) | Data, ML, and scripting-heavy servers |
| Java / Kotlin | io.modelcontextprotocol | Existing JVM and Spring backends |
| C# | ModelContextProtocol | .NET and enterprise Microsoft stacks |
| Go / Rust | mcp-go / rmcp | High-throughput, low-latency remote servers |
| Ruby / Swift / PHP | community-maintained | Teams already standardized on those ecosystems |
On the client side, the same SDKs expose an MCP client you can embed directly into your own application if you are building an agent rather than relying on Claude Desktop or Claude Code. A minimal client connects over the same transport, calls list_tools to discover what a server offers, and then issues tools/call requests - the mirror image of everything the server side implements.
Which SDK Should You Pick?
If you are unsure, start with TypeScript or Python. Both have the most complete documentation, the largest set of reference servers to copy from on the official MCP servers repository, and first-class support in Claude Desktop and Claude Code. Reach for Go, Rust, or the JVM SDKs only once you have a concrete performance or existing-stack reason to.
How to Build an MCP Server, Step by Step
Here is the full sequence for building and testing a working MCP server, condensed from the official SDK quickstarts. Follow along and check off each step as you go.
Interactive Build Checklist
0 / 8 completeMCP Server Example: A Working Weather Tool
Below is a complete, minimal MCP server example with one tool, get_forecast, shown in both TypeScript and Python. Toggle between the two to compare the shape of each SDK - the logic is identical either way.
Minimal MCP Server: get_forecast Tool
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-tools",
version: "1.0.0",
});
server.registerTool(
"get_forecast",
{
title: "Get Weather Forecast",
description: "Return a short-range weather forecast for a city.",
inputSchema: {
city: z.string().describe("City name, e.g. Stockholm"),
days: z.number().min(1).max(7).default(3),
},
},
async ({ city, days }) => {
const data = await fetchForecast(city, days);
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);Once the server file is built, point a client at it. For Claude Desktop, add an entry to the MCP configuration file:
{
"mcpServers": {
"weather-tools": {
"command": "node",
"args": ["/absolute/path/to/weather-server/build/index.js"]
}
}
}Restart the client, and get_forecast becomes available the next time the model decides weather data is relevant to the conversation. No further wiring is needed - the schema you registered in step 3 is exactly what the model reads to decide how to call the tool.
Testing and Deploying Your MCP Server
A tool that works once in a demo is not the same as a tool that is safe to ship. Before treating an MCP server as production-ready, run it through the same rigor you would apply to any other backend service.
- Use the MCP Inspector - the official debugging tool that lets you call tools and inspect raw JSON-RPC traffic without a full AI client attached
- Validate every input - never trust a model-generated argument; reject malformed input at the schema level before it reaches your business logic
- Log every tool call - capture arguments, results, and latency so a bad tool choice by the model is easy to trace after the fact
- Move to Streamable HTTP with OAuth before exposing a server beyond your own machine, following the resource-binding requirements added in the 2025-06-18 spec revision
- Rate-limit and sandbox destructive tools separately from read-only ones, and require explicit confirmation for anything irreversible
Go Deeper on Security
MCP servers that touch production data or execute code are a real attack surface, not a toy. The full MCP security guide covers permission scoping, prompt-injection risks, and audit logging in detail. If you are running many servers behind one endpoint, the MCP gateway article explains how to centralize authentication and routing instead of managing credentials per server.
Common Mistakes When Building an MCP Server
Vague tool descriptions
A tool named do_task with a one-line description gives the model almost nothing to reason about. Write descriptions the way you would write documentation for a new engineer joining the project.
Overly broad tools
A single execute_action tool that accepts a free-text command string defeats the purpose of typed schemas and makes behavior unpredictable. Split it into narrow, purpose-built tools instead.
Skipping input validation
Models occasionally generate malformed or unexpected arguments. Treat every tool call the way you would treat an untrusted network request, and validate before executing.
Choosing the wrong transport for the job
Shipping a stdio-only server when multiple remote clients need to connect - or building full remote infrastructure for a tool only you will ever run locally - both waste engineering time. Match the transport to how the server will actually be used.
Forgetting structured output
Since the 2025-06-18 spec revision, tools can return structuredContent alongside plain text. Returning only unstructured text makes it harder for clients to render or chain results reliably - use structured output wherever the data has real shape.
MCP Server vs Traditional REST API
An MCP server is not a replacement for your REST API - it is usually a thin, model-friendly layer that sits in front of one. The table below summarizes where each approach fits.
| Aspect | REST API | MCP Server |
|---|---|---|
| Consumer | Developer writing fixed code paths | An AI model deciding at runtime |
| Discovery | Read documentation separately | Self-describing via tools/list |
| Integration effort | Custom per client application | Built once, reused by any MCP client |
| Message format | Any (JSON, XML, GraphQL, etc.) | Standardized JSON-RPC 2.0 |
| Typical use | Powering apps, websites, services | Giving an AI agent controlled access to that same logic |
In practice, most teams building an MCP server for 2026 are wrapping an existing REST API or internal SDK, not replacing it. A closer look at that specific decision is in the dedicated MCP vs API comparison.
MCP Servers Are the Plumbing - Autonomous Agents Are the Payoff
Building one MCP server is a great first step. The bigger win is connecting many of them - search, publishing, social, and analytics - to autonomous agents that act on their own schedule. Planetary Labour runs exactly that kind of stack: AI agents wired into MCP-style tool access that publish SEO articles, post to X and Reddit, and build domain authority around the clock, without a human in the loop for every task. Explore the agentic AI frameworks guide to see how these pieces fit together in a full autonomous system.
Why MCP Matters for Autonomous GTM, Not Just Chat
Most MCP tutorials stop at connecting a single tool to a chat client. The more durable use case is wiring MCP servers into autonomous agents that run continuously - checking a content calendar, drafting a post, publishing it, and logging the result, all without a person clicking through each step.
That is the model Planetary Labour is built on: an always-on GTM engine where AI agents hold tool access to publishing, social, and outreach systems the same way an MCP client holds tool access to the servers you just built. The engineering pattern is the same one covered in this tutorial - typed tools, validated inputs, and clear boundaries on what the agent can and cannot do - just pointed at growth workflows instead of a single chat session.
If you are building MCP servers for your own product, it is worth reading how agentic AI systems are assembled end to end, since the server you build today is very often the tool an autonomous agent calls tomorrow.
Frequently Asked Questions
What is an MCP server and how does it work?
An MCP server is a lightweight program that exposes tools, resources, and prompts to an AI model over the Model Context Protocol. It works by opening a transport connection (stdio or Streamable HTTP), advertising its capabilities during an initialization handshake, then responding to JSON-RPC requests as the model calls its tools or reads its resources.
What programming languages can I use to build an MCP server?
Anthropic and the community maintain official MCP SDKs for TypeScript, Python, Java, Kotlin, C#, Go, Rust, Ruby, Swift, and PHP. TypeScript and Python are the most mature and widely documented, so most tutorials and reference servers use one of the two.
Do I need deep AI experience to build an MCP server?
No. Building an MCP server is closer to writing a small API wrapper than doing machine learning work. If you can write a function, define its inputs, and call an external service, you already have the skills needed to build a working MCP server in under an hour.
What is the difference between an MCP server and a REST API?
A REST API is designed for a developer to call from known code paths. An MCP server wraps that same logic in a self-describing format - with named tools, typed parameters, and natural-language descriptions - so an AI model can discover what it can do and decide when to call it, without a human writing the integration code for every use case.
How long does it take to build a working MCP server?
A minimal MCP server with one tool over stdio typically takes 15 to 30 minutes to build and test locally using the official TypeScript or Python SDK. Production-ready servers with authentication, error handling, and remote Streamable HTTP transport usually take a few days of focused engineering work.
Continue Learning
Model Context Protocol: The Complete Guide →
The pillar guide to MCP — architecture, primitives, transports, and production concerns.
The Complete MCP Servers Directory →
Browse 100+ official and community MCP servers by category before you build your own.
MCP Security Best Practices →
Permission scoping, prompt-injection risks, and audit logging for production MCP servers.
