Build Your First MCP Server with Python and FastMCP (Step-by-Step Tutorial)
📖 TL;DR
- FastMCP is a Python framework (22k+ GitHub stars) that powers ~70% of all MCP servers
- Install with
pip install fastmcp, create tools with@mcp.tool, expose data with@mcp.resource - Connect to Claude Desktop, Cursor, or any MCP client
- From zero to a working server in ~15 minutes
Want to give your AI assistant superpowers? An MCP server lets Claude, ChatGPT, Cursor, or any MCP client call your Python functions, access your data, and use your tools—all through a standard protocol.
This tutorial shows you how to build one from scratch using FastMCP, the most popular Python framework for MCP servers. By the end, you'll have a working server that any AI client can connect to.
What is FastMCP?
FastMCP is a Python framework created by Jeremiah Lowin that makes building MCP servers simple. Think of it as "Flask for MCP"—you write Python functions, add decorators, and FastMCP handles the protocol, validation, and transport.
| Detail | Info |
|---|---|
| GitHub | jlowin/fastmcp (22k+ stars) |
| Docs | gofastmcp.com |
| Install | pip install fastmcp |
| Python | 3.10+ |
| License | Apache 2.0 |
| Latest | v2.x stable (v3.0 in beta as of Jan 2026) |
FastMCP 1.0 was so good that it was incorporated into the official MCP Python SDK. FastMCP 2.x adds enterprise auth, deployment tools, and client libraries. v3.0 (beta) introduces components, providers, and transforms for advanced use cases. Use v2.x for production today.
Prerequisites
Check with python --version
Package manager
Claude Desktop or Cursor to test
Step 1: Install FastMCP
pip install fastmcp
Or with uv (faster):
uv add fastmcp
Verify:
fastmcp version
Step 2: Create Your First Server
Create a file called server.py:
from fastmcp import FastMCP
# Create an MCP server
mcp = FastMCP("My First Server")
@mcp.tool
def add(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
@mcp.tool
def multiply(a: int, b: int) -> int:
"""Multiply two numbers together."""
return a * b
if __name__ == "__main__":
mcp.run()
That's it. Two tools, ready to use. FastMCP automatically:
- Generates JSON schemas from your type hints
- Validates parameters
- Handles the MCP protocol (JSON-RPC 2.0)
- Runs over STDIO for local clients
Step 3: Run and Test
Run the server in development mode:
fastmcp dev server.py
This starts an interactive inspector where you can test your tools. Or run it directly:
fastmcp run server.py
Step 4: Add Resources
Tools perform actions (functions the AI can call). Resources provide data (read-only, like REST endpoints). Let's add both:
from fastmcp import FastMCP
import json
from datetime import datetime
mcp = FastMCP("Company Dashboard")
# --- Tools (actions) ---
@mcp.tool
def search_employees(query: str) -> list[dict]:
"""Search employees by name or department."""
employees = [
{"name": "Alice", "dept": "Engineering", "role": "Senior Dev"},
{"name": "Bob", "dept": "Marketing", "role": "Manager"},
{"name": "Charlie", "dept": "Engineering", "role": "DevOps"},
]
return [e for e in employees if query.lower() in json.dumps(e).lower()]
@mcp.tool
def calculate_budget(department: str, months: int = 12) -> dict:
"""Calculate estimated budget for a department."""
rates = {"Engineering": 15000, "Marketing": 12000, "Sales": 10000}
monthly = rates.get(department, 10000)
return {"department": department, "monthly": monthly, "total": monthly * months}
# --- Resources (data) ---
@mcp.resource("company://stats")
def company_stats() -> str:
"""Current company statistics."""
return json.dumps({
"employees": 47,
"departments": 5,
"founded": "2020",
"updated": datetime.now().isoformat()
})
@mcp.resource("company://departments/{dept}")
def department_info(dept: str) -> str:
"""Get info about a specific department."""
info = {
"engineering": {"head_count": 18, "lead": "Alice", "budget": "180k/yr"},
"marketing": {"head_count": 8, "lead": "Bob", "budget": "96k/yr"},
}
return json.dumps(info.get(dept.lower(), {"error": "Department not found"}))
if __name__ == "__main__":
mcp.run()
Now the AI can call search_employees and calculate_budget as tools, and read company://stats or company://departments/engineering as resources.
Step 5: Connect to Claude Desktop
FastMCP includes a CLI to install your server into Claude Desktop:
fastmcp install server.py
This adds the server to your Claude Desktop config automatically. You can also do it manually by editing claude_desktop_config.json:
{
"mcpServers": {
"my-server": {
"command": "fastmcp",
"args": ["run", "server.py"]
}
}
}
Restart Claude Desktop. You should see the hammer icon indicating tools are loaded. Try asking:
- "Search for employees in Engineering."
- "What's the budget for Marketing over 6 months?"
- "Show me company stats."
Step 6: Connect to Cursor
In Cursor: Settings → Tools & MCP → Add MCP server:
| Field | Value |
|---|---|
| Name | my-server |
| Type | stdio |
| Command | fastmcp |
| Args | run server.py |
FastMCP vs Official MCP Python SDK
You might also see pip install mcp — that's the official MCP Python SDK (v1.26.0, maintained at modelcontextprotocol/python-sdk). Both work. Here's when to use each:
| Use case | Recommendation |
|---|---|
| Quick server, simple tools | FastMCP — less boilerplate, decorators |
| Full protocol control, custom transports | Official SDK (pip install mcp) |
| Enterprise auth (OAuth, GitHub, Azure) | FastMCP 2.x — built-in auth providers |
| Learning MCP internals | Official SDK — closer to the protocol |
What About TypeScript?
If you prefer TypeScript/Node.js, the official MCP TypeScript SDK (modelcontextprotocol/typescript-sdk) is the standard. We have a separate guide: Build a Custom MCP Server Using Node.js.
Next Steps
- Add async tools: Use
@mcp.toolwithasync deffor I/O-bound operations (API calls, DB queries). - Add prompts: Use
@mcp.promptto define reusable prompt templates. - Deploy remotely: FastMCP supports HTTP transport for remote servers. See gofastmcp.com for deployment guides.
- Test it: Use
fastmcp dev server.pyfor the interactive inspector, or write tests with FastMCP's testing utilities.
Test Remote MCP Servers in the Browser
Built a remote server? Test it instantly with MCP Playground
Open MCP Playground →Related Content
- What Is the Model Context Protocol (MCP)?
- Build a Custom MCP Server Using Node.js
- How to Set Up MCP in Claude Desktop
- Awesome MCP Servers List
Frequently Asked Questions
Do I need FastMCP or can I use the official MCP SDK?
pip install mcp) gives you more protocol-level control. FastMCP 1.0 was actually adopted into the official SDK, so they share DNA. For most use cases, FastMCP is faster to start with.Can I use FastMCP with ChatGPT or other AI clients?
How do I deploy my MCP server remotely?
Should I use FastMCP v2 or v3?
Nikhil Tiwari
15+ years of experience in product development, AI enthusiast, and passionate about building innovative solutions that bridge the gap between technology and real-world applications. Specializes in creating developer tools and platforms that make complex technologies accessible to everyone.