Skip to content
AI Agent How-To

Home ›MCP server setup guides

How to Build an MCP Server in Python (FastMCP Quickstart)

Intermediate ~4 min read Last tested October 2026

Updated 2026-10-15

An MCP server exposes tools (and optionally resources and prompts) to any MCP client: Claude Desktop, Cursor, VS Code, or your own agent. With the official Python SDK’s FastMCP class, a working server is about ten lines.

Prerequisites

  • Python 3.10+
  • uv (recommended) or pip
  • An MCP client to test with (Claude Desktop, Cursor, or the MCP Inspector)

Steps

1. Create the project

uv init weather-mcp && cd weather-mcp
uv add "mcp[cli]" httpx

With pip: pip install "mcp[cli]" httpx.

2. Write the server

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

mcp = FastMCP("weather")

@mcp.tool()
async def current_weather(latitude: float, longitude: float) -> str:
    """Get the current temperature and wind speed for a location."""
    url = "https://api.open-meteo.com/v1/forecast"
    params = {"latitude": latitude, "longitude": longitude, "current": "temperature_2m,wind_speed_10m"}
    async with httpx.AsyncClient(timeout=10) as c:
        data = (await c.get(url, params=params)).json()["current"]
    return f"{data['temperature_2m']} °C, wind {data['wind_speed_10m']} km/h"

@mcp.resource("info://about")
def about() -> str:
    """Static info the client can read."""
    return "Weather MCP server using the free Open-Meteo API."

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

The function signature becomes the tool’s JSON Schema and the docstring becomes its description, so write good docstrings.

3. Test with MCP Inspector

uv run mcp dev server.py

This opens the Inspector in your browser. Click Connect → Tools → current_weather, enter coordinates, and run it.

4. Add it to Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

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

Fully quit and restart Claude Desktop. The tool appears in the tools menu.

5. Add it to Cursor

Create .cursor/mcp.json in your project (or ~/.cursor/mcp.json globally) with the same mcpServers block.

6. Serve it remotely (optional)

Run over HTTP instead of stdio so remote clients can connect:

if __name__ == "__main__":
    mcp.run(transport="streamable-http")   # serves on http://127.0.0.1:8000/mcp

Put authentication in front of any remote server that touches private data.

Common errors

Never print to stdout in a stdio server. print() corrupts the JSON-RPC stream. Log to stderr: print("debug", file=sys.stderr).

spawn uv ENOENT in Claude Desktop: the app can’t find uv on its PATH. Use the absolute path from which uv as command.

Tool doesn’t appear: JSON syntax error in the config, or Claude wasn’t fully quit. See MCP server not connecting to Claude Desktop.