Skip to main content
RapidDev - Software Development Agency
mcp-tutorial

How to install the MCP Python SDK

Install the MCP Python SDK with pip install mcp[cli] or uv add mcp[cli], then create a minimal server using the FastMCP class with decorator-based tool definitions. The Python SDK uses type hints for input validation (no Zod needed), supports async handlers natively, and can be run directly with python server.py or via the mcp CLI. A working server is under 15 lines of code.

What you'll learn

  • How to install the MCP Python SDK with pip or uv
  • How to create a minimal FastMCP server with decorators
  • How to define tools, resources, and prompts in Python
  • How to run and test your Python MCP server
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner7 min read10 minPython 3.10+, pip or uv package managerMarch 2026RapidDev Engineering Team
TL;DR

Install the MCP Python SDK with pip install mcp[cli] or uv add mcp[cli], then create a minimal server using the FastMCP class with decorator-based tool definitions. The Python SDK uses type hints for input validation (no Zod needed), supports async handlers natively, and can be run directly with python server.py or via the mcp CLI. A working server is under 15 lines of code.

Setting Up the MCP Python SDK with FastMCP

The Python MCP SDK provides FastMCP, a high-level class that makes building MCP servers as simple as writing decorated functions. Unlike the TypeScript SDK which uses Zod for schemas, the Python SDK uses native type hints and docstrings to generate input schemas automatically. This tutorial walks you through installation, project setup, and creating your first Python MCP server.

Prerequisites

  • Python 3.10 or later installed (check with python --version)
  • pip or uv package manager available
  • A code editor (VS Code, Cursor, or similar)
  • Basic familiarity with Python and async/await

Step-by-step guide

1

Install the MCP Python SDK

Install the mcp package with the cli extra, which includes the FastMCP class and the mcp command-line tool for running and testing servers. You can use pip or uv (the fast Python package manager). The cli extra is important — it includes the development server and inspector integration.

typescript
1# Using pip
2pip install "mcp[cli]"
3
4# Using uv (recommended faster)
5uv add "mcp[cli]"

Expected result: The mcp package is installed. Running python -c "import mcp" should produce no errors.

2

Create your project structure

Create a project directory with a minimal structure. Python MCP servers can be as simple as a single file. For larger projects, you will want a proper package structure, but for getting started, one file is enough.

typescript
1mkdir my-mcp-server
2cd my-mcp-server
3
4# If using uv, initialize the project
5uv init
6uv add "mcp[cli]"
7
8# Create the server file
9touch server.py

Expected result: A project directory with server.py ready to edit.

3

Create a minimal FastMCP server

Open server.py and create a FastMCP instance. The FastMCP class handles all protocol details — you just define tools, resources, and prompts using decorators. The @mcp.tool() decorator turns a regular Python function into an MCP tool. Type hints are used to generate the input schema automatically, and the docstring becomes the tool description.

typescript
1# server.py
2from mcp.server.fastmcp import FastMCP
3
4# Create the server
5mcp = FastMCP("my-mcp-server")
6
7@mcp.tool()
8async def hello(name: str) -> str:
9 """Greet someone by name."""
10 return f"Hello, {name}!"
11
12@mcp.tool()
13async def add(a: float, b: float) -> str:
14 """Add two numbers together."""
15 return str(a + b)

Expected result: A server.py file with two tool definitions using FastMCP decorators.

4

Run the server with the mcp CLI

The mcp CLI tool (included with mcp[cli]) can run your server directly. Use mcp dev to start the server with the MCP Inspector for interactive testing. Use mcp run for production-style stdio execution. The dev command opens a browser-based inspector where you can call your tools and see the JSON-RPC messages.

typescript
1# Development mode with Inspector
2mcp dev server.py
3
4# Production mode (stdio transport)
5mcp run server.py
6
7# Or run directly with Python
8python server.py

Expected result: Running mcp dev server.py opens the MCP Inspector in your browser where you can test the hello and add tools.

5

Add a resource and a prompt

FastMCP supports all three MCP capability types. Use @mcp.resource() with a URI pattern to define resources, and @mcp.prompt() to define prompt templates. Resources return data for context, prompts return message templates for structured interactions.

typescript
1# Add to server.py
2
3@mcp.resource("config://app")
4async def get_config() -> str:
5 """Current application configuration."""
6 return '{"version": "1.0.0", "env": "development"}'
7
8@mcp.resource("users://{user_id}/profile")
9async def get_user_profile(user_id: str) -> str:
10 """Get a user's profile by ID."""
11 return f'{{"id": "{user_id}", "name": "Jane Doe"}}'
12
13@mcp.prompt()
14async def review_code(language: str) -> str:
15 """Generate a code review prompt for the specified language."""
16 return f"Review the following {language} code for bugs, security issues, and best practices."

Expected result: Your server now exposes tools, resources, and prompts. The MCP Inspector shows all three capability types.

6

Configure the server for Claude Desktop or Cursor

To connect your Python MCP server to an AI host, add it to the host's configuration file. For Claude Desktop, edit claude_desktop_config.json. For Cursor, edit .cursor/mcp.json. The command should point to your Python interpreter and the server file. Use uv run if you are using uv for dependency management.

typescript
1// claude_desktop_config.json example
2{
3 "mcpServers": {
4 "my-server": {
5 "command": "uv",
6 "args": ["run", "--directory", "/path/to/my-mcp-server", "server.py"]
7 }
8 }
9}
10
11// Alternative using python directly
12{
13 "mcpServers": {
14 "my-server": {
15 "command": "python",
16 "args": ["/path/to/my-mcp-server/server.py"]
17 }
18 }
19}

Expected result: After restarting the AI host, your Python MCP server's tools appear and can be called by the AI model.

Complete working example

server.py
1#!/usr/bin/env python3
2"""A complete MCP server demonstrating all capability types."""
3
4from mcp.server.fastmcp import FastMCP
5
6# Create the MCP server
7mcp = FastMCP("my-mcp-server")
8
9
10# === TOOLS (model-controlled actions) ===
11
12@mcp.tool()
13async def hello(name: str) -> str:
14 """Greet someone by name."""
15 return f"Hello, {name}!"
16
17
18@mcp.tool()
19async def calculate(a: float, b: float, operation: str) -> str:
20 """Perform basic arithmetic.
21
22 Args:
23 a: First number
24 b: Second number
25 operation: One of 'add', 'subtract', 'multiply', 'divide'
26 """
27 ops = {
28 "add": a + b,
29 "subtract": a - b,
30 "multiply": a * b,
31 "divide": a / b if b != 0 else "Error: division by zero",
32 }
33 result = ops.get(operation, f"Unknown operation: {operation}")
34 return f"{a} {operation} {b} = {result}"
35
36
37@mcp.tool()
38async def search_files(pattern: str, directory: str = ".") -> str:
39 """Search for files matching a glob pattern.
40
41 Args:
42 pattern: Glob pattern like '*.py' or '**/*.json'
43 directory: Directory to search in (default: current)
44 """
45 import glob
46 import os
47
48 search_path = os.path.join(directory, pattern)
49 matches = glob.glob(search_path, recursive=True)
50 if not matches:
51 return f"No files found matching '{pattern}' in {directory}"
52 return "\n".join(matches[:50]) # Limit to 50 results
53
54
55# === RESOURCES (app-controlled data) ===
56
57@mcp.resource("config://app")
58async def get_app_config() -> str:
59 """Current application configuration."""
60 import json
61 return json.dumps({
62 "name": "my-mcp-server",
63 "version": "1.0.0",
64 "python": "3.12",
65 }, indent=2)
66
67
68# === PROMPTS (user-controlled templates) ===
69
70@mcp.prompt()
71async def debug_error(error_message: str, language: str = "Python") -> str:
72 """Help debug an error message."""
73 return (
74 f"I encountered this error in {language}:\n\n"
75 f"{error_message}\n\n"
76 f"Please explain what caused this error and provide a fix."
77 )
78
79
80if __name__ == "__main__":
81 mcp.run()

Common mistakes when installing the MCP Python SDK

Why it's a problem: Installing mcp without the [cli] extra

How to avoid: Running pip install mcp installs the base package but not the CLI tools (mcp dev, mcp run). Always install with pip install "mcp[cli]" to get the full development toolkit.

Why it's a problem: Using print() for debugging in stdio servers

How to avoid: Like TypeScript servers, Python MCP servers use stdout for protocol messages. Use import sys; print('debug', file=sys.stderr) or the logging module with a stderr handler instead of regular print().

Why it's a problem: Forgetting type hints on tool parameters

How to avoid: FastMCP generates input schemas from type hints. Without them, the SDK cannot tell the AI model what types of values to pass. Always annotate parameters: async def search(query: str, limit: int = 10).

Why it's a problem: Not writing docstrings for tools

How to avoid: The tool's docstring becomes its description in MCP. Without a docstring, the AI model has no context for when to use the tool. Write clear docstrings: "Search GitHub issues by keyword and return matching results."

Best practices

  • Use uv instead of pip for faster installs and better dependency resolution
  • Always install mcp[cli] to get the development tools (mcp dev, mcp run)
  • Write descriptive docstrings for every tool — the AI model uses them to decide when to call each tool
  • Use type hints on all parameters so FastMCP generates accurate input schemas
  • Log to stderr instead of stdout: import sys; print('msg', file=sys.stderr)
  • Use async functions for tool handlers to avoid blocking the event loop during I/O operations
  • Test with mcp dev server.py to use the Inspector before connecting to a host
  • Pin your mcp package version in requirements.txt or pyproject.toml for reproducible builds

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Show me how to create an MCP server in Python using FastMCP. Include installation with pip, a server file with three tools using type hints and docstrings, and how to run it with the mcp CLI. Also show how to add a resource and a prompt.

MCP Prompt

Create a Python MCP server using FastMCP with these tools: (1) a file search tool using glob, (2) a text transformation tool that can uppercase/lowercase/reverse strings, (3) a JSON validator tool. Include proper type hints and docstrings for each.

Frequently asked questions

What Python version do I need?

Python 3.10 or later is required. The MCP SDK uses features like match statements and improved type hints that are not available in earlier versions. Python 3.12 is recommended.

Should I use pip or uv?

uv is recommended for new projects. It is 10-100x faster than pip, handles virtual environments automatically, and provides better dependency resolution. Install uv with curl -LsSf https://astral.sh/uv/install.sh | sh.

Can I use synchronous functions instead of async?

Yes. FastMCP accepts both sync and async functions. However, async is recommended for I/O operations (API calls, file reads, database queries) to avoid blocking the server while waiting for responses.

How do I pass environment variables to my Python MCP server?

In Claude Desktop or Cursor configs, add an "env" object to the server entry: {"command": "python", "args": ["server.py"], "env": {"API_KEY": "your-key"}}. Access them with os.environ["API_KEY"] in your server code.

Can RapidDev help build Python MCP servers for our team?

Yes. RapidDev helps teams build custom Python MCP servers that integrate with internal APIs, databases, and workflows. This includes design, implementation, testing, and deployment guidance for production use.

What is the difference between mcp dev and mcp run?

mcp dev starts your server with the MCP Inspector attached — a browser-based UI for testing tools interactively. mcp run starts the server in production stdio mode without the Inspector. Use dev for testing, run for production.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.