Back to Blog
Tutorial

Build Your First MCP Server with Python and FastMCP (Step-by-Step Tutorial)

February 1, 202615 min readBy Nikhil Tiwari

📖 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

Python 3.10+

Check with python --version

pip or uv

Package manager

MCP client (optional)

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.tool with async def for I/O-bound operations (API calls, DB queries).
  • Add prompts: Use @mcp.prompt to 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.py for 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

Frequently Asked Questions

Do I need FastMCP or can I use the official MCP SDK?
Both work. FastMCP is higher-level (less boilerplate, decorators, built-in auth). The official 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?
Yes. Any MCP-compatible client can connect to your FastMCP server. This includes Claude Desktop, Cursor, VS Code with GitHub Copilot, ChatGPT (via OpenAI Apps SDK), and custom clients built with the MCP SDK.
How do I deploy my MCP server remotely?
FastMCP supports HTTP transport in addition to STDIO. You can deploy to any server (cloud VM, Docker, serverless) and expose it as an HTTP endpoint. Clients connect via the URL instead of running a local command. See the FastMCP docs for deployment guides.
Should I use FastMCP v2 or v3?
Use v2.x for production. v3.0 was released in beta (Jan 2026) and introduces powerful new concepts (components, providers, transforms) but is not yet stable. The FastMCP team recommends v2 for production systems.
NT

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.