# How do you build your first MCP server?

Date: 2025-03-29 · Author: Robert Scales · https://guidetoartificialintelligence.com/en/learn/build-first-mcp-server/

**Answer:** Install the official MCP Python SDK, write a short file that creates a FastMCP server and turns one Python function into a tool with a decorator, then open it in the MCP Inspector to check it. When the tool behaves, one command adds it to Claude Desktop.

The Model Context Protocol (MCP) is an open standard that lets an AI assistant use outside data and actions through small programs called **servers**. The assistant side, such as Claude Desktop, is the **client**. A server can offer three kinds of things: **tools** (actions the model can ask to run), **resources** (data it can read) and **prompts** (reusable templates). Most people start with a tool, because it is the easiest way to give an assistant a new ability.

You don't need much code. The official Python SDK includes **FastMCP**, a helper that turns a normal Python function into an MCP tool. The function's name becomes the tool name, its type hints describe the inputs, and its docstring (the text in triple quotes) becomes the description the model reads when deciding whether to use it.

## What you need

- A recent Python and **uv**, a fast Python project manager that the SDK's README recommends. (Plain `pip install mcp` also works.)
- A text editor and a terminal.
- Node.js, only if you want to run the Inspector on its own with `npx`.
- Claude Desktop, if you want to connect the finished server to an assistant.

## Step by step: a "days until" tool

Our server will answer one question that language models often get wrong: how many days remain until a given date. A model can't reliably know today's date or count calendar days; a three-line function can.

**1. Create the project and add the SDK.**

```bash
uv init days-server
cd days-server
uv add "mcp[cli]"
```

The `[cli]` part installs the `mcp` command-line tool you'll use for testing.

**2. Write `server.py`.**

```python
# server.py
from datetime import date
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Days Until")

@mcp.tool()
def days_until(target: str) -> str:
    """Count the days from today until a date given as YYYY-MM-DD.
    Returns a negative number if the date has passed."""
    try:
        when = date.fromisoformat(target)
    except ValueError:
        return "Please give the date as YYYY-MM-DD, for example 2025-12-25."
    delta = (when - date.today()).days
    return f"{delta} days from {date.today().isoformat()} to {target}."

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

Three details matter. The docstring is written for the model, so it says exactly what the input format is. Bad input returns a helpful message instead of crashing, so the model can correct itself. And the function does one job, which makes it easy to test.

**3. Test it** with the Inspector (next section).

**4. Connect it to Claude Desktop.**

```bash
uv run mcp install server.py
```

This registers the server with Claude Desktop, which keeps its list of MCP servers in a file called `claude_desktop_config.json`. Quit Claude Desktop fully and reopen it; it connects to servers at startup. Then ask "How many days until December 25?" and Claude should offer to call `days_until`. Claude Desktop asks you to confirm before sensitive operations, and the server runs only on your own computer.

> **Try it:** Add a second tool, `day_of_week(target: str)`, that returns the weekday name for a date. Restart the server and check that both tools appear before you connect anything.

## If something goes wrong

- **The tool doesn't appear in Claude Desktop.** Make sure you quit the app completely, not just closed the window. Its logs (on a Mac, in `~/Library/Logs/Claude/` in files starting with `mcp`) show whether the server started.
- **The server starts but the tool fails.** Run it in the Inspector and read the error message there; it is much quicker than testing through a chat.
- **The model never calls your tool.** Improve the docstring. Say plainly what the tool does and when to use it.

## How do you test it before connecting it to an assistant?

Use the **MCP Inspector**, the official tool for checking and debugging a server while you build it. It acts as a client, connects to your server and shows you exactly what an assistant would see: the list of tools, their descriptions and input fields, and the raw results. Because no language model is involved, you test your code alone, without wondering whether the model misunderstood.

The SDK starts the Inspector for you:

```bash
uv run mcp dev server.py
```

The command launches your server together with the Inspector, which runs a small web page in your browser (by default on port 5173) and a local proxy that talks to your server (port 3000 by default). Open the address it prints, connect, and list the tools. You should see `days_until` with the docstring you wrote. Run it with a valid date, then with something wrong like `25/12/2025`, and check that you get your friendly error message rather than a crash.

If your server is written in another language, or you want to run the Inspector on its own, start it with `npx @modelcontextprotocol/inspector` followed by the command that launches your server; you can pass environment variables with `-e KEY=value`. One safety note from the Inspector's README: its proxy can start programs on your machine, so keep it on your own computer and never expose it to an untrusted network.

A good habit is to keep a short list of test inputs (a normal case, an edge case such as today's date, and a bad input) and run them in the Inspector every time you change the server. Only when all three behave as you expect is it worth connecting the server to an assistant.

## Sources

- MCP Python SDK (README): https://github.com/modelcontextprotocol/python-sdk/blob/d3bf9cd325e4083f79e53b07d6853fc49195a257/README.md
- MCP Inspector (README): https://github.com/modelcontextprotocol/inspector/blob/ec738314875c0b984dca92df88c2be73c7ef4df2/README.md
- Quickstart (Model Context Protocol documentation): https://github.com/modelcontextprotocol/docs/blob/aeebcc279b27cef5c82a3dfc2d7f4e686a953fdc/quickstart.mdx
