Who this is for
This guide is for developers who want to give an AI application access to their own data or tools through the Model Context Protocol (MCP). You should be comfortable running commands in a terminal and writing a few lines of Python or TypeScript. By the end you should understand what an MCP server exposes, be able to run one locally, inspect it, and connect it to a client.
What an MCP server exposes
An MCP server is a program that exposes specific capabilities to AI applications through a standard protocol. It provides functionality through three building blocks: Tools, Resources and Prompts [2]. They differ in who decides when they are used.
Tools are functions that the LLM can call actively. It decides when to use them, based on the user's request. A tool can write to a database, call an external API, modify files or trigger other logic [2]. Each tool performs a single operation with clearly defined inputs and outputs, and MCP uses JSON Schema to validate them [2].
Resources are passive data sources that give read-only access to information for context, such as file contents, database schemas or API documentation. The application controls when they are used [2]. Each resource has a unique URI, such as file:///path/to/document.md, and declares its MIME type. Resources support two discovery patterns: direct resources with fixed URIs, and resource templates with dynamic URIs [2].
Prompts are pre-built instruction templates that tell the model to work with specific tools and resources. The user controls them, and they need an explicit invocation rather than triggering on their own [2].
The protocol operations follow from these blocks. Tools use tools/list and tools/call. Resources use resources/list, resources/templates/list, resources/read and subscriptions/listen. Prompts use prompts/list and prompts/get [2]. The current protocol version is 2026-07-28 [5]. Every request declares its version in the io.modelcontextprotocol/protocolVersion key of its _meta field. Over Streamable HTTP the same value also travels in the MCP-Protocol-Version header [5].
Choosing a transport
MCP has two transport mechanisms [3]. Stdio runs the server as a local process and talks to it through standard input and output. There is no network overhead, and it is used between processes on the same machine [3]. Streamable HTTP uses HTTP POST for client-to-server messages, with optional Server-Sent Events. It is the choice for remote servers. It supports standard HTTP authentication, including bearer tokens, API keys and custom headers, and MCP recommends OAuth to obtain the tokens [3].
Start with stdio while you develop. Move to Streamable HTTP when the server has to run somewhere other than your machine.
There is one rule that catches almost every first-time author. For a stdio server, never write to stdout, because that corrupts the JSON-RPC messages. TypeScript servers should use console.error(), and Python servers should use the standard library logging module, which writes to stderr. Standard output logging is fine for HTTP-based servers [1].
Set up the SDK
The official SDKs page lists ten SDKs and sorts them into tiers by feature completeness, protocol support and maintenance commitment. TypeScript, Python, C#, Go, Rust and Ruby are Tier 1, Java is Tier 2, and Swift, PHP and Kotlin are Tier 3 [4].
For Python, the SDK requires Python 3.11 or newer. It supports stdio, Streamable HTTP and SSE [8]. Install it with uv add "mcp[cli]" or pip install "mcp[cli]". The cli extra adds the mcp command-line tool, which provides mcp dev, mcp run and mcp install [8].
For TypeScript, the main branch of the SDK is v2. The stable packages are @modelcontextprotocol/server and @modelcontextprotocol/client, and they implement the 2026-07-28 spec and run on Node.js, Bun and Deno [9]. Install the server package with npm install @modelcontextprotocol/server, bun add @modelcontextprotocol/server or deno add npm:@modelcontextprotocol/server [9]. Tool and prompt schemas use Standard Schema, which works with Zod v4, Valibot or ArkType [9].
A first server in Python
The Python SDK README gives this complete server in about fifteen lines [8]:
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"The add function is a tool. The greeting function is a resource template, because its URI contains a {name} parameter. Both are plain functions with type hints and docstrings. The same server file can be tested and served with the commands below [8]:
uv run mcp dev server.py
uv run mcp run server.py --transport streamable-httpThe first command opens the server in the MCP Inspector. The second serves it over HTTP [8].
A first server in TypeScript
The official TypeScript tutorial starts a src/index.ts file with these imports and constants [1]:
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";
const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";The imports bring in the server class, a stdio transport helper and Zod for schemas. The two constants are the base address of an external API and a user-agent string. The rest of the tutorial builds the tools on top of this, and you should follow it step by step rather than copy a complete file from here.
Test with the MCP Inspector
The MCP Inspector is the reference tool for testing and debugging MCP servers. It ships as the single package @modelcontextprotocol/inspector, which provides Web, CLI and TUI clients behind one binary [6]. It needs Node 22.19.0 or newer and runs through npx with no installation step [6].
To open the web UI against a local stdio server, run npx @modelcontextprotocol/inspector node path/to/server/index.js [6]. To list the tools of a server from the command line, run npx @modelcontextprotocol/inspector --cli node path/to/server/index.js --method tools/list [6]. Run the second one first. It proves the server starts and answers before you add a client.
Connect it to Claude Desktop
Claude Desktop reads its local servers from claude_desktop_config.json. The file lives at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, at %APPDATA%\Claude\claude_desktop_config.json on Windows, and at ~/.config/Claude/claude_desktop_config.json on Linux [7]. Local servers go under the mcpServers key with a command and an args array [7]. The macOS example in the docs uses "command": "npx", with -y, @modelcontextprotocol/server-filesystem and the directories the server may access as its arguments [7].
Connect it to Claude Code
Claude Code has its own command to add a server. To add a remote server over HTTP, run claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp [11]. To add a local stdio server, run claude mcp add playwright -- npx -y @playwright/mcp@latest. The -- separator passes everything after it to the server, and local servers use the default stdio transport [11].
The general syntax is claude mcp add [options] <name> -- <command> [args...]. Options include --env KEY=value for environment variables and --header "Authorization: Bearer your-token" for authentication headers [12].
Check the connection with claude mcp list from the shell, or with /mcp inside a session [11]. Servers can be scoped. local is the default and is stored in ~/.claude.json. project is stored in .mcp.json in the project root. user is stored in ~/.claude.json under the top-level mcpServers key [11]. You can also edit .mcp.json directly, with entries of "type": "http" plus a url, or "type": "stdio" plus a command and args. Claude Code reads that file at the start of a session [11].
Reference servers
The modelcontextprotocol/servers repository is a collection of reference implementations. The maintained reference servers are Everything, Fetch, Filesystem, Git, Memory, Sequential Thinking and Time [10]. TypeScript ones start with npx, for example npx -y @modelcontextprotocol/server-memory. Python ones start with uvx, for example uvx mcp-server-git, or with pip install mcp-server-git [10].
Every server in that repository serves stdio. Only Everything also serves Streamable HTTP, at a URL such as http://localhost:3001/mcp [10]. The servers are educational examples for developers who build their own. They are not production-ready solutions [10]. Read them for patterns, and do not deploy them as they are.
Limits and common questions
- Stray output breaks stdio servers. Never write to stdout: it corrupts the JSON-RPC messages. TypeScript servers should use
console.error()and Python servers the standardloggingmodule, both of which write to stderr [1]. - Protocol version matters. Clients and servers must agree on the version. The current version is
2026-07-28, and every request carries it [5]. - Remote auth is more than a token. Streamable HTTP supports bearer tokens and API keys, but MCP recommends OAuth [3].
- **The TypeScript SDK is v2 on
main.** Check which major version your tutorial uses before you copy its imports [9].
Next steps
Read the server concepts page for the three building blocks in more depth [2]. The build guide walks through a full TypeScript server [1]. The Python SDK README covers the decorators and the mcp command-line tool [8]. The Inspector page covers the web, CLI and TUI clients [6]. For Claude Code, the MCP pages cover scopes and configuration [11][12].
Sources
- 1Build an MCP serverModel Context Protocol
- 2Understanding MCP serversModel Context Protocol
- 3Architecture overviewModel Context Protocol
- 4SDKsModel Context Protocol
- 5VersioningModel Context Protocol
- 6MCP InspectorModel Context Protocol
- 7Connect to local MCP serversModel Context Protocol
- 8MCP Python SDK READMEmodelcontextprotocol (GitHub)
- 9MCP TypeScript SDK READMEmodelcontextprotocol (GitHub)
- 10Model Context Protocol servers READMEmodelcontextprotocol (GitHub)
- 11MCP quickstart (Claude Code)Anthropic (Claude Code Docs)
- 12MCP (Claude Code)Anthropic (Claude Code Docs)
Cite this page: Building an MCP server from scratch. TellWorld, https://www.tellworld.net/practice/practice-mcp-server. Updated 2026-11-14