Menu

AI

How to Build Your First MCP Server (Python and TypeScript)

Build a working MCP server in Python or TypeScript with the official v2 SDKs, test it with MCP Inspector, connect it to Claude, and know what to do next.

By: Irina ShvayaOctober 28, 2026

How to Build Your First MCP Server (Python and TypeScript)

This article is part of our MCP Guide: what the Model Context Protocol is, how to use it safely, and how to choose servers, tools and help. Want a second opinion on your setup? Request a free MCP readiness review.

To build an MCP server, install an official MCP SDK, register one or more tools as functions, and run the server over a transport such as stdio. Then point an AI app like Claude at it. A first working server takes a few dozen lines of code.

This guide follows the official Build an MCP server tutorial on modelcontextprotocol.io and the README files of the official Python and TypeScript SDKs. We checked them on 28 October 2026. The code below uses the v2 SDKs, which implement the 2026-07-28 MCP specification.

If you have not met the terms yet, read how MCP works first. It explains hosts, clients, servers and tools.

Key Takeaways

  • Use the official SDKs: the mcp package on PyPI for Python and @modelcontextprotocol/server on npm for TypeScript.
  • Both SDKs moved to version 2 in July 2026, so many older tutorials use import paths that no longer work.
  • A tool is just a function with a name, a description and typed inputs; the SDK turns that into the schema the AI app sees.
  • In a stdio server, never print to standard output, because it corrupts the protocol messages.
  • Test with MCP Inspector before you connect the server to Claude or another app.
  • A local demo is not production; remote servers need HTTPS, authorization, logging and a security review.

Which SDK versions this guide uses

As of 28 October 2026, these were the current releases on the package registries:

LanguagePackageVersion checkedNotes
Pythonmcp on PyPI2.3.02.0.0 was released 28 July 2026
TypeScript@modelcontextprotocol/server on npm2.4.0v2 released 27 July 2026, per the SDK README

Why this matters: the Python SDK's "What's new in v2" page says the high-level server class was renamed from FastMCP to MCPServer. The old mcp.server.fastmcp import path was removed, so v1 code breaks on import. The page says v1 moves to maintenance and keeps getting critical fixes and security patches.

On the TypeScript side, the TypeScript SDK README says v2 ships as split packages, @modelcontextprotocol/server and @modelcontextprotocol/client. The older @modelcontextprotocol/sdk package is v1. The README says v1 gets bug fixes and security updates for at least six months after the v2 release.

If you copy code from a blog post, check which version it targets.

Before you start

You need:

  • Python: the official tutorial asks for Python 3.10 or higher and SDK 2.0.0 or higher. The Python SDK README lists Python 3.11+, so 3.11 or newer is the safe choice.
  • TypeScript: Node.js 20 or higher, per the tutorial.
  • An MCP host to test with, such as Claude Desktop. See which AI apps support MCP for others.
  • Basic comfort with a terminal.

One rule that breaks most first servers

The official tutorial is blunt about this. For servers that use the stdio transport, never write to standard output (stdout). Doing so corrupts the JSON-RPC messages and breaks the server.

In Python, that means no print(). Use the logging module, which writes to stderr. In TypeScript, use console.error() instead of console.log(). HTTP-based servers do not have this problem.

Option 1: Build an MCP server in Python

Step 1: Set up the project

The tutorial uses uv, a Python package manager. After installing it, create a project and add the SDK:

uv init my-server
cd my-server
uv venv
source .venv/bin/activate
uv add "mcp[cli]"

The cli extra adds the mcp command-line tool, which includes mcp dev for testing.

Step 2: Write the server

Create server.py. This minimal example comes from the Python SDK README. It exposes one tool and one resource:

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}!"


if __name__ == "__main__":
    mcp.run(transport="stdio")

Notice what you did not write. The README points out that the type hints (a: int, b: int) become the input schema. The docstring becomes the tool description the AI model reads. The last two lines follow the official tutorial's pattern for running over stdio.

Step 3: Test it with MCP Inspector

Run:

uv run mcp dev server.py

This opens the server in MCP Inspector, the official testing tool. The README's example: call add with a=1 and b=2 and you get 3 back.

Step 4: Connect it to Claude Desktop

Open Claude Desktop's config file. On macOS the tutorial gives this path: ~/Library/Application Support/Claude/claude_desktop_config.json. Add your server under mcpServers:

{
  "mcpServers": {
    "demo": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/my-server",
        "run",
        "server.py"
      ]
    }
  }
}

Use the absolute path to your project folder. The tutorial notes you may need the full path to uv as well (run which uv to find it). Save the file and restart Claude Desktop.

Option 2: Build an MCP server in TypeScript

Step 1: Set up the project

These commands follow the official tutorial:

mkdir my-server
cd my-server
npm init -y
npm install @modelcontextprotocol/server zod
npm install -D @types/node typescript
mkdir src
touch src/index.ts

In package.json, add "type": "module" and a build script such as "build": "tsc". The tutorial's tsconfig.json targets ES2022 with Node16 modules and compiles src into build.

The SDK README says tool schemas use Standard Schema, so you can use Zod v4 or a compatible library.

Step 2: Write the server

Put this in src/index.ts. It follows the tutorial's pattern: a createServer() function that builds a fresh server and registers tools, served over stdio with serveStdio.

import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";

// serveStdio calls this whenever it needs an instance,
// so it must return a fresh server each time.
function createServer() {
  const server = new McpServer({ name: "greeting-server", version: "1.0.0" });

  server.registerTool(
    "greet",
    {
      description: "Greet someone by name",
      inputSchema: z.object({ name: z.string() }),
    },
    async ({ name }) => ({
      content: [{ type: "text", text: `Hello, ${name}!` }],
    }),
  );

  return server;
}

serveStdio(createServer, {
  onerror: (error) => console.error("Server error:", error),
});
console.error("Server running on stdio");

According to the tutorial, serveStdio negotiates the protocol version with each client. That means the same server answers 2026-07-28 clients and older clients that still use the 2025-era handshake.

The SDK README shows an alternative pattern using StdioServerTransport and server.connect(). Both come from official docs. We used the tutorial's pattern because of that version negotiation.

Step 3: Build and test

npm run build
npx @modelcontextprotocol/inspector --cli node build/index.js --protocol-era modern --method tools/list

The tutorial explains that the Inspector defaults to the legacy protocol era. Run the command a second time with --protocol-era legacy to check older clients too. Both runs should list your tool.

Step 4: Connect it to Claude Desktop

In the same config file, add:

{
  "mcpServers": {
    "greeting": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/my-server/build/index.js"]
    }
  }
}

Restart Claude Desktop, then ask it to greet someone.

Tips for tools an AI model can actually use

Getting the server to run is the easy part. Getting a model to pick the right tool takes care.

  • Name tools by task. find_overdue_invoices is clearer than query.
  • Write descriptions for the model. Say what the tool does, when to use it, and what it returns.
  • Keep inputs narrow. Use enums, ranges and required fields. The tutorial's TypeScript example limits latitude to -90 through 90 for this reason.
  • Return useful errors. "No invoices found for that customer ID" helps the model recover. A stack trace does not.
  • Start small. Ship three good tools before you ship thirty.

From demo to production

A local stdio server is fine for one person on one laptop. A server other people use is a different job.

Move to Streamable HTTP for remote use

The Python SDK README calls Streamable HTTP "the transport you deploy." It shows running a server with uv run mcp run server.py --transport streamable-http. The TypeScript SDK publishes optional middleware packages for Express, Fastify, Hono and Node.js HTTP.

Add authorization

The MCP authorization spec makes authorization optional. When you support it over HTTP, it is based on OAuth 2.1. Servers must publish OAuth Protected Resource Metadata and must only accept tokens issued for them. Stdio servers should read credentials from the environment instead. Our guide to MCP authentication and OAuth 2.1 walks through the flow.

Review security before launch

Read the official security best practices. Key points for server authors:

  • Do not accept or pass through tokens that were not issued for your server.
  • Request the smallest set of scopes, and ask for more only when needed.
  • Do not treat a state handle, such as a cart ID, as proof of identity; bind it to the authenticated user.
  • If your server runs locally, prefer stdio, or require a token if you expose HTTP.

Our article on MCP security risks covers the business side of these risks.

Publish it, if it is public

If you want others to find your server, you can list it in the official MCP Registry. The registry quickstart uses the mcp-publisher CLI. Read how to market an MCP server for the full launch plan.

When to get help

Build it yourself if you have a developer with time and the server is low-risk. Bring in help when the server touches customer data, payments or regulated records, or when you need OAuth, hosting and monitoring done right the first time. Our build vs buy guide helps you decide.

Next step

If you want a production MCP server scoped, built and reviewed, see eSEOspace MCP development to start the conversation.

Frequently asked questions

What language should I use to build an MCP server?

Use the language your team already knows. Python and TypeScript both have official SDKs, and the official tutorial also covers Java, Kotlin, C#, Ruby, Rust and Go. The protocol is the same whichever SDK you pick.

Why does my old FastMCP code fail with the new Python SDK?

In Python SDK v2, FastMCP was renamed to MCPServer and the old import path was removed. Change mcp.server.fastmcp imports to from mcp.server import MCPServer, or pin the SDK below version 2 until you migrate. The SDK's migration guide lists other changes.

Do I need Claude to test an MCP server?

No. MCP Inspector lets you list and call tools without any AI app. After that, you can connect any MCP-capable host. Claude Desktop is just the example the official tutorial uses.

Why is my stdio server not connecting?

The most common cause is writing to standard output. In a stdio server, print() or console.log() corrupts the protocol messages. Log to stderr instead, and check that the path in your client config is absolute.

How long does it take to build a production MCP server?

That depends on how many tools you need, how authentication works, and how much security review is required. A demo is quick. A production server needs time for OAuth, hosting, logging and testing. See MCP server development cost for the main drivers.

You Might Also like to Read

Get a FREE Website Audit

Enter your website and get a 20–30 page SEO, GEO, AEO & CRO audit within 24 hours. Completely free.

Don't have a site yet? Get in touch →

Ready to speak with a marketing expert?
Give us a call! (916) 866-7893

Websites Launched
1407
Websites Launched
Marketing Experts
29
Marketing Experts
Hours of Dedicated Work
204533
Hours of Dedicated Work
Irina S.Benjamin G.Jeanette M.David G.