Turning Point Academy · MCP Engineering

Your first MCP server in Python — Commented code

Curso MCP Engineering · M2


This is the complete version, ready to print and keep next to you, of the server we built in the lesson. It's meant to be read top to bottom: first you prepare the environment, then you write the server.py file line by line, and finally you run it and connect it to a real client to test it. You don't need to know MCP by heart: each block explains itself. Copy each snippet exactly as it is and you won't run into surprises.

The goal is deliberately minimal: a calculator with two tools (multiply and add). Once you understand this example, you understand the pattern behind any MCP server in Python.


Step 0 — What is FastMCP and why do we use it?

FastMCP is a Python library that implements the MCP protocol for you. Without it, you'd have to write all the "plumbing" by hand: the initial handshake between client and server, the exact message format, the list of tools shown to the model, the validation of incoming data… That's a lot of repetitive code and easy to get wrong. With FastMCP you focus on just one thing: what your server does. You write normal Python functions; the library exposes them as MCP tools.


Step 1 — Prepare the environment and install FastMCP

Always work inside a virtual environment (.venv). A virtual environment is a folder that isolates this project's packages from the rest of your system, so versions don't get mixed up and nothing breaks elsewhere. If you're coming from Module 0, you already have one created; activate it. If not, create it with python -m venv .venv.

# (If you don't have it yet) create the virtual environment once:
python -m venv .venv

# Activate the virtual environment
# macOS / Linux:
source .venv/bin/activate
# Windows (PowerShell):
# .venv\Scripts\Activate.ps1

# Install FastMCP inside the environment
pip install fastmcp

When the environment is active, you'll see (.venv) at the start of your terminal line. That's your signal that pip install will install the package inside the project and not system-wide. pip is Python's package installer: it downloads FastMCP from PyPI (the official repository) and leaves it ready to import.


Step 2 — The complete server.py file

Create a file called server.py in the same folder and paste this. Below the code I explain it block by block.

# server.py
# A minimal MCP server: a calculator with two tools.

# 1) We import FastMCP, the library that implements the MCP protocol for us.
from fastmcp import FastMCP

# 2) We create the server and give it a name.
#    That name ("calculator") is how the client will identify it.
mcp = FastMCP("calculator")


# 3) We define a tool.
#    - The decorator @mcp.tool publishes it as a tool.
#    - The type hints (a: float, b: float -> float) describe inputs and output.
#    - The docstring is what THE AGENT READS to decide when to use it.
@mcp.tool
def multiply(a: float, b: float) -> float:
    """Multiply two numbers."""
    return a * b


# 4) A second tool, so you can see the pattern repeated.
@mcp.tool
def add(a: float, b: float) -> float:
    """Add two numbers."""
    return a + b


# 5) We start the server.
#    mcp.run() uses stdio by default: client and server talk through the terminal.
if __name__ == "__main__":
    mcp.run()

What each block does

Remember: the docstring (the text between """...""") is what the agent reads to understand what the tool does. Write one for every tool, always.

Step 3 — Run the server

From the folder where server.py is, with the environment activated:

python server.py

If no error appears, the server is running and waiting for a client. It's normal not to see any output: a stdio server stays quiet, listening. To stop it, press Ctrl+C.


Step 4 — Connect it to Claude Code and test it

A server on its own does nothing visible: it needs a client to talk to it. The quickest way is to register it in Claude Code, pointing to the command that starts it.

# Register the server in Claude Code
claude mcp add calculator -- python server.py

# Verify it was registered
claude mcp list

# Then, inside Claude Code, try something like:
#   "multiply 6 by 7"   -> uses the multiply tool and returns 42
#   "add 10 and 5"      -> uses the add tool and returns 15

The agent will discover your tools on its own, decide which one to use, pass it the numbers and return the result to you. That back-and-forth is the MCP lifecycle, now with your own server.


Common errors (and how to fix them)


Checklist

The pattern you take away

Create the server → hang tools with @mcp.toolmcp.run(). That's the skeleton of any MCP server in Python. The rest of the course is variations on this same thing.

FastMCP is installed from PyPI with pip install fastmcp. Always work inside your virtual environment.