Skip to content
Helped by a Nerd

AI Tools

How to Build an MCP Server: A Beginner's Step-by-Step Guide

Published on Reading time: 10 min

  • #mcp
Contents

You have probably watched an AI assistant fetch the weather, query a database, or read a file and wondered how it actually reaches outside its own chat window. The answer, in 2026, is almost always the Model Context Protocol. An MCP server is the small program that hands those abilities to the model, and building one is far less intimidating than it sounds.

In this guide you will build a working MCP server from an empty folder, expose a single tool the model can call, test it locally, and connect it to Claude Desktop so you can use it in a real conversation. No prior protocol knowledge is required. If you can write a basic Python function and run a command in a terminal, you can finish this.

What is an MCP server, in one sentence?

An MCP server is a small program that exposes tools, data, and prompts to an AI client through a standard protocol, so the model can take real actions instead of only generating text. The Model Context Protocol (MCP) is an open standard that defines how AI applications and external capabilities talk to each other. Instead of every tool inventing its own integration, MCP gives them one shared language, the same way USB gave every device one shared port. If you want the bigger-picture explanation before you start coding, read what is an MCP server — this guide assumes you just want to build one.

A server can expose three kinds of things: tools (functions the model can call, like “get the forecast”), resources (data the model can read, like a file or a record), and prompts (reusable templates). For your first server, a single tool is all you need.


What you need before you start

You need Python 3.10 or newer, a terminal, and a few minutes to install one package — that is the entire prerequisite list for a basic server. You do not need a paid API key, a cloud account, or a deep understanding of networking to get a local server running.

Here is the short checklist:

  • Python 3.10+ installed and on your PATH. Run python --version to confirm.
  • A package manager. The official tooling recommends uv, a fast Python package and project manager, but plain pip works too.
  • The MCP Python SDK, which ships a helper called FastMCP that hides almost all of the protocol plumbing.
  • A client to connect to. This guide uses Claude Desktop because the setup is the gentlest. If you prefer the command line, Claude Code also speaks MCP and the Claude Code MCP setup follows the same idea.

You can build MCP servers in many languages — TypeScript and Python are the most common — but Python with FastMCP is the friendliest starting point, so that is what we use here.


How do you set up the project?

Create a fresh folder, set up an isolated Python environment, and install the MCP SDK — that gives you a clean workspace where nothing collides with the rest of your system. Keeping each server in its own environment is a habit worth forming early, because it prevents version conflicts down the line.

Open a terminal and run:

# create and enter a project folder
mkdir weather-server
cd weather-server

# create an isolated environment and install the SDK
uv init
uv add "mcp[cli]"

If you would rather use the standard tools, the equivalent with pip is:

python -m venv .venv
source .venv/bin/activate   # on Windows: .venv\Scripts\activate
pip install "mcp[cli]"

Either path leaves you with a folder containing an isolated environment and the MCP SDK installed. That is the whole setup. Now you can write the server.


How do you write the basic server skeleton?

The skeleton of an MCP server is just a few lines: import FastMCP, create a server instance, and start it — everything else is the tools you add on top. FastMCP handles the JSON-RPC messaging, the handshake with the client, and the transport layer, so you write ordinary Python and let the library do the protocol work.

Create a file named server.py and start with this:

from mcp.server.fastmcp import FastMCP

# name your server — the client shows this to the user
mcp = FastMCP("weather")

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

That is a complete, valid MCP server. It does nothing useful yet because it has no tools, but it will start, announce itself to a client, and respond to the protocol handshake. The FastMCP("weather") line gives the server a name, and mcp.run() starts it listening on stdio — standard input and output — which is how a desktop client launches and talks to a local server. You will add a real capability in the next step.


How do you add your first tool?

You turn an ordinary Python function into a callable tool by adding the @mcp.tool() decorator and a clear docstring — the model reads that docstring to decide when to use it. This is the part that matters most: the description you write is not a comment for other developers, it is the instruction the AI uses to pick the right tool at the right moment.

Add a tool to server.py:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather")

@mcp.tool()
def get_forecast(city: str) -> str:
    """Get a short weather forecast for a given city.

    Args:
        city: The name of the city, e.g. "Berlin" or "Tokyo".
    """
    # in a real server you would call a weather API here.
    # for now we return a fixed string so the wiring is easy to test.
    return f"The forecast for {city} is sunny, 24 degrees Celsius."

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

Three small things are doing the heavy lifting. The decorator registers the function as a tool the model can call. The type hints (city: str and -> str) tell the client what arguments the tool expects and what it returns, so the model sends valid input. The docstring is the natural-language description the model reads when it decides whether this tool fits the user’s request. Write it the way you would explain the tool to a colleague: say what it does and what each argument means.

Return a hard-coded string for now. Once the plumbing works end to end, swapping in a real weather API call is a one-line change. Resisting the urge to wire up the live API first is what keeps your first build debuggable.


How do you test the server locally?

Run the server with the MCP Inspector, a built-in tool that lets you call your functions by hand before any AI is involved — it is the fastest way to catch mistakes early. Testing in isolation means that when something breaks later, you already know the server itself is sound and the problem is in the connection or the prompt.

From your project folder, launch the inspector:

uv run mcp dev server.py

This opens a local web interface in your browser. In it you can see your get_forecast tool listed, type a city name into the argument field, click to run it, and read the response — all without touching an AI client. If the forecast string comes back, your server works.

If the inspector cannot find your tool, check two usual suspects: the @mcp.tool() decorator must sit directly above the function, and the file must run without import errors (try uv run python server.py to surface any tracebacks). Get a clean run here before moving on, because debugging the server and debugging the client connection at the same time is far harder than doing them in order. This local-test-first habit is part of a broader Claude Code workflow mindset: prove each piece works before you compose them.


How do you connect the server to Claude Desktop?

You connect the server by adding a small entry to Claude Desktop’s configuration file that tells it how to launch your script, then restarting the app. Claude Desktop does not connect to a running server — it starts your server itself each time it needs it, which is why the config describes a command to run rather than an address to dial.

Open Claude Desktop, go into its settings, and find the developer or MCP configuration option, which opens a file named claude_desktop_config.json. Add your server under the mcpServers key:

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/weather-server", "run", "server.py"]
    }
  }
}

Replace /absolute/path/to/weather-server with the real, full path to your project folder — relative paths will not work here. Save the file and fully quit and reopen Claude Desktop. After it restarts, you should see your server listed in the app’s tools indicator. Ask something like “What is the forecast for Berlin?” and watch Claude call your tool and answer with your server’s response.

Because details like the exact menu names and config file location change between releases, check the official Claude documentation if anything does not match what you see. If the server does not appear, the most common causes are a typo in the JSON (a missing comma breaks the whole file), a relative path where an absolute one is required, or forgetting to fully restart the app.


What are the next steps after your first server?

Once your hard-coded tool works end to end, the natural next steps are calling a real API, adding more tools, and tightening security before you share the server with anyone. You now have a working template, and almost everything beyond this point is variation on what you have already built.

A few directions worth exploring:

  • Make the tool real. Replace the fixed string with an actual API call inside get_forecast. The protocol wiring does not change — only the function body does.
  • Add more capabilities. Stack additional @mcp.tool() functions, or expose resources (read-only data) and prompts (templates) using the same decorator pattern.
  • Understand the alternatives. MCP is not the only way to give a model tools. Reading MCP vs function calling and Claude skills vs MCP vs subagents will help you choose the right mechanism for each job instead of reaching for MCP by default.
  • Take security seriously. A server that touches files, databases, or APIs is a real attack surface. Before you connect anything sensitive or share your server, read MCP security.
  • Find inspiration. Browse the best MCP servers and find MCP servers people have already published to see what mature implementations look like.

FAQ

What programming language should I use to build an MCP server?

You can build an MCP server in any language that has an MCP SDK, and the most common choices are Python and TypeScript. Python with the FastMCP helper is the gentlest starting point because a working server fits in about ten lines. Pick the language you are already comfortable with — the protocol concepts are identical across all of them.

Do I need an API key or a paid account to build an MCP server?

No. The local server in this guide runs entirely on your machine with no keys and no cloud account. You only need credentials when a tool calls an external paid service, such as a weather or maps API. Building, testing, and connecting your first server costs nothing.

What is the difference between stdio and HTTP transport?

Stdio (standard input and output) is for local servers that a client launches on your own machine, and it is the default for desktop setups like the one in this guide. HTTP transport is for remote servers that run on a different machine and serve many clients over a network. Start with stdio while learning, and move to HTTP only when you actually need to host your server remotely.

Why is the tool’s docstring so important?

The docstring is the description the AI model reads to decide whether and how to call your tool. Unlike a normal code comment, it directly affects behavior: a vague docstring leads the model to use the tool at the wrong times or with bad arguments. Write it as a clear, plain-language explanation of what the tool does and what each argument means.

How is building an MCP server different from building an AI agent?

An MCP server provides capabilities — it is a supplier of tools that any compatible client can use. An AI agent is the system that decides which tools to call and in what order to accomplish a goal. They are complementary: you might build an AI agent that consumes the very MCP server you built here. If the distinction is still fuzzy, what is an AI agent covers it in depth.


Conclusion

Building an MCP server comes down to four steps you have now done from start to finish: set up a clean Python project, turn a function into a tool with a decorator and a good docstring, test it locally with the Inspector, and register it in Claude Desktop’s config. The weather example is deliberately tiny, but the structure is exactly what production servers use — they just add more tools and real data behind them.

The most useful habit you can keep is the order you worked in: prove the server runs on its own before you connect it to anything, and prove the connection works with a hard-coded response before you add real logic. From here, swap in a live API, layer on more tools, and read up on MCP security before you point your server at anything that matters. You have the template — everything else is iteration.

More on this topic

Newsletter

Never miss an AI update

New tools, guides and deals – once a week, straight to your inbox.

100% free, cancel anytime.