AI Engineering16 min read

How to Build Your First MCP Server in 2026 (Step by Step)

A hands on guide to building a Model Context Protocol server in Python and TypeScript, testing it with the MCP Inspector, and connecting it to Claude, Cursor, and Copilot. No fluff, real code.

Dev Kant Kumar
Dev Kant Kumar
July 10, 2026
Hands on Tutorial for 2026

Build Your First MCP Server

Connect Claude, Cursor, and Copilot to your own tools

Dev Kant Kumar
16 min read
Beginner Friendly

If you have used an AI coding tool this year, you have probably heard people talk about MCP. Here is how to actually build one, start to finish, in about twenty minutes.

The Model Context Protocol is having a moment. It is the standard that lets AI assistants like Claude, Cursor, and Copilot talk to outside tools in a consistent way, and developers are searching for how to build one more than twenty thousand times a month. The problem is that most of what you find online is either the raw specification or a wall of theory. This guide is the opposite. We will build a working server you can talk to from Claude, and I will explain each piece as we go.

Works with:Claude logo ClaudeCursor logo CursorGitHub Copilot logo Copilot
What you will have by the end

A running MCP server with a working tool, tested in the MCP Inspector, and connected to Claude Desktop so you can ask Claude to call it in plain English. You will see the exact code in both Python and TypeScript.

What is an MCP server, in plain English

Think of MCP as a universal adapter for AI. Before it, every tool that wanted to plug into an AI assistant needed its own custom integration, which meant the same work rebuilt over and over. MCP fixes that with one shared protocol. You build a server once, and any MCP aware client, whether that is Claude, Cursor, or a growing list of others, can use it.

People often call it the USB-C of AI tools, and the comparison fits. A single standard plug, and everything speaks the same language. Your server is the device. The AI assistant is the laptop. MCP is the port in between. If you have read my guide on the best AI coding tools, this is the plumbing that lets those tools reach into your own systems.

The three things an MCP server can expose

An MCP server can offer three kinds of building blocks. You do not need all three, and most first servers use only the first one, but it helps to know the map before you start.

Tools

Actions the AI can take, like search a database, send an email, or call an API. This is what you will build today.

Resources

Read only data the AI can pull in as context, like a file, a document, or a row from your database.

Prompts

Reusable prompt templates a user can trigger, like a saved workflow for a common task.

Tools are the star

For your first server, focus entirely on a tool. Once one tool works end to end, adding resources and prompts is a small step. Do not try to learn all three at once.

What you need before you start

  • Python 3.10 or newer, or Node.js 18 or newer, depending on which version you follow.
  • The Claude Desktop app installed, so you can connect your server to a real client.
  • Comfort running commands in a terminal. That is the only hard requirement.

Build an MCP server in Python, the fast way

Python is the quickest path because the official SDK ships with FastMCP, a helper that turns a plain function into an MCP tool with a single decorator. Start by setting up a project and installing the SDK.

BASHsetup
# Create a project folder and a virtual environment
mkdir weather-mcp && cd weather-mcp
python -m venv .venv

# Activate it
# macOS or Linux:
source .venv/bin/activate
# Windows (PowerShell):
.venv\Scripts\Activate.ps1

# Install the official MCP SDK (ships FastMCP)
pip install "mcp[cli]"

Now create a file called server.py. This is the entire server. Read the comments, because every line earns its place.

PYTHONserver.py
# server.py
from mcp.server.fastmcp import FastMCP

# Give your server a clear, unique name.
mcp = FastMCP("weather-demo")

@mcp.tool()
def get_forecast(city: str) -> str:
    """Return a short weather forecast for a city."""
    # In a real server you would call a weather API here.
    # We keep it simple so you can see the whole flow first.
    return f"The weather in {city} is sunny, 27 degrees C."

if __name__ == "__main__":
    # stdio is the default transport for local servers.
    mcp.run()

That is genuinely all it takes. The @mcp.tool() decorator reads your function name, its type hints, and its docstring, then turns all of that into a tool the AI can discover and call. The type hint on city becomes input validation for free. Run it to make sure nothing is broken.

BASHrun
python server.py

If the command sits there quietly without an error, that is a good sign. A stdio server communicates over standard input and output, so it is supposed to wait silently for a client. Press Ctrl C to stop it, and let us test it properly.

Test it with the MCP Inspector first

Before you wire anything into Claude, test the server on its own. The MCP Inspector is an official tool that launches your server and gives you a web UI to list its tools and call them by hand. No AI model is involved, so if something is wrong you find out here instead of wondering why Claude is silent.

BASHinspector
# The Inspector launches your server and gives you a UI
# to list tools and call them, with no AI model involved.
npx @modelcontextprotocol/inspector python server.py

It opens a page in your browser. Click to list the tools, find get_forecast, type a city into the argument box, and run it. If you get your forecast text back, your server works. This one habit will save you hours over the next few months.

Connect your server to Claude Desktop

Claude Desktop reads a small config file that lists the MCP servers it should start. You point it at your server, restart the app, and Claude can use your tool. First, open the config file. You will find it here:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

If the file does not exist yet, create it. Add your server like this, and use the full absolute path to your file, not a relative one.

JSONclaude_desktop_config.json
{
  "mcpServers": {
    "weather-demo": {
      "command": "python",
      "args": ["/absolute/path/to/weather-mcp/server.py"]
    }
  }
}

Save the file and fully restart Claude Desktop. Once it reopens, you will see a tools icon in the message box. Ask Claude something like "what is the weather in Mumbai," and it will call your get_forecast tool and answer using what your server returns. That is the whole loop, and you built it.

It also works in Cursor

Cursor and several other clients read a similar MCP config. Once your server speaks the protocol, the same code works across every MCP aware tool. Build once, use everywhere.

Prefer TypeScript? Here is the same server in Node

If your world is JavaScript, the official TypeScript SDK gives you the same result with a little more setup. Install the packages first.

BASHsetup
mkdir weather-mcp && cd weather-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node

Then write the server. It reads slightly longer than the Python version, but it is doing the same three jobs: create a server, register a tool with a schema, and connect a transport.

TYPESCRIPTindex.ts
// index.ts
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-demo", version: "1.0.0" });

server.registerTool(
  "get_forecast",
  {
    title: "Get forecast",
    description: "Return a short weather forecast for a city.",
    inputSchema: { city: z.string().describe("City name, e.g. Mumbai") },
  },
  async ({ city }) => {
    // In a real server you would call a weather API here.
    const text = "The weather in " + city + " is sunny, 27 degrees C.";
    return { content: [{ type: "text", text }] };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

Compile it with npx tsc, then point Claude Desktop at the built JavaScript file instead of the Python one.

JSONclaude_desktop_config.json
{
  "mcpServers": {
    "weather-demo": {
      "command": "node",
      "args": ["/absolute/path/to/weather-mcp/build/index.js"]
    }
  }
}

stdio vs HTTP: local now, production later

You just used the stdio transport, where the client starts your server as a local process and they talk over standard input and output. It is perfect for a server that runs on your own machine, which is most first projects.

When you want a server that lives on the internet and serves many users, you switch to the Streamable HTTP transport. The tool code you wrote does not change. You only swap how the server is exposed, and you add the things any public service needs.

QuestionstdioStreamable HTTP
Where it runsYour own machineA server on the internet
Who can use itJust youMany users
Setup effortAlmost noneMore, plus auth
Best forLearning and personal toolsShared, production servers

Going to production: what actually changes

Do not jump to this until your local server works, but here is what the path looks like so it is not a mystery. Moving a server to production usually means four things:

  1. Switch to Streamable HTTP so clients can reach it over the network.
  2. Add authentication. The common choice is OAuth 2.1, so only allowed users can call your tools.
  3. Package it in Docker so it runs the same everywhere and is easy to deploy.
  4. Handle errors and limits like timeouts, rate limits, and clear messages when a tool call fails.
Never skip auth on a public server

A local stdio server only you can start is safe by nature. A public HTTP server that runs actions is not. If your tools can touch real data or systems, treat authentication as a requirement, not an afterthought.

Common mistakes and how to fix them

When a server does not show up in Claude, it is almost always one of these. Check them in order.

  1. A relative path in the config. Claude cannot guess where your file is. Use the full absolute path.
  2. You did not restart Claude. The config is read on startup. Quit the app completely and reopen it, do not just close the window.
  3. Broken JSON. A missing comma or a stray bracket makes the whole file invalid. Paste it into a JSON validator if the server will not load.
  4. The wrong Python. If you installed the SDK inside a virtual environment, point the config at that environment's Python, or the import will fail.
  5. You skipped the Inspector. If you are not sure whether the problem is your server or the config, test with the Inspector first. It removes half the guesswork.

Where to go from here

Your weather tool is a toy, on purpose, so you could see the whole shape without noise. The real power shows up when the tool does something only you can offer. A few ideas that make great second projects:

  • A tool that queries your own database so Claude can answer questions about your data.
  • A tool that reads and writes your notes, tickets, or project files.
  • A tool that wraps an internal API your team already uses every day.

There are already hundreds of community built MCP servers for tools like GitHub, Slack, Postgres, Stripe, and Docker, so you rarely start from zero. If you want to understand the bigger picture of AI agents that use tools like this, read my guide on building AI agents that work.

The bottom line

MCP looks intimidating from the outside, but the core is small. Create a server, register a tool, connect a transport, and point a client at it. Everything else, the resources, the prompts, the production setup, is built on top of that same simple loop. You now have the loop working, which is the part most people never get past.

Build the weather server today, then replace the tool with something real tomorrow. The moment Claude calls a tool you wrote and does something useful with the result, the whole idea clicks, and you will not look at AI assistants the same way again.

Frequently asked questions

What is an MCP server?

An MCP server is a small program that exposes tools, data, or prompts to AI assistants through the Model Context Protocol. It lets clients like Claude, Cursor, and Copilot call your own functions and read your own data in a standard way, so you build the integration once and any MCP aware client can use it.

Do I need Python or TypeScript to build an MCP server?

Either works. Python is the fastest start because the official SDK ships FastMCP, which turns a function into a tool with one decorator. The official TypeScript SDK gives you the same result with a bit more setup. MCP also has SDKs for Java, Kotlin, C#, Rust, and Swift.

How do I connect an MCP server to Claude?

Open Claude Desktop's claude_desktop_config.json file, add your server under the mcpServers key with the command and the absolute path to your server file, then fully restart Claude Desktop. A tools icon appears and Claude can call your tool when you ask in plain English.

What is the MCP Inspector?

The MCP Inspector is an official tool you run with npx @modelcontextprotocol/inspector. It launches your server and gives you a web UI to list and call its tools by hand, with no AI model involved, so you can confirm the server works before connecting it to a client.

What is the difference between stdio and HTTP transports?

stdio runs your server as a local process that talks over standard input and output, which is ideal for personal tools on your own machine. Streamable HTTP exposes the server over the network for many users and production use, and it usually adds authentication such as OAuth 2.1. Your tool code stays the same either way.

Is it safe to run an MCP server?

A local stdio server that only you can start is safe by nature. A public HTTP server that can run actions or touch real data needs authentication and careful error handling. Never expose a production MCP server without auth if its tools can affect real systems.

Recommended Resources
How To Practice Coding Every Day
Han Shavir

Build a Consistent Coding Habit

Stop guessing and start building. This e-book provides practical strategies, exercises, and routines to help you code regularly and improve steadily.

Get E-Book
How to Read and Understand Other People's Code
Han Shavir

Master Unfamiliar Codebases

Struggling to make sense of someone else's code? Learn practical strategies to navigate, analyze, and master unfamiliar codebases with confidence.

Get E-Book

Tags

#MCP#Model Context Protocol#AI Tools#Claude#Python#TypeScript#AI Agents#Developer Tools
Dev Kant Kumar

Dev Kant Kumar

Author

Full Stack Developer passionate about crafting high-performance user experiences. I write about Agentic AI, React, and the future of web development.

💬 Discussion

Recommended Resources
How To Practice Coding Every Day
Han Shavir

Build a Consistent Coding Habit

Stop guessing and start building. This e-book provides practical strategies, exercises, and routines to help you code regularly and improve steadily.

Get E-Book
How to Read and Understand Other People's Code
Han Shavir

Master Unfamiliar Codebases

Struggling to make sense of someone else's code? Learn practical strategies to navigate, analyze, and master unfamiliar codebases with confidence.

Get E-Book