MCP Servers & Clients

Build Your First FastMCP Server in Python: Connect Any Database to Claude & Cursor (2026)

Build a custom Python FastMCP server in 10 minutes. Connect SQLite or PostgreSQL directly to Claude Desktop and Cursor with simple code, zero headaches, and full security.

Build Your First FastMCP Server in Python: Connect Any Database to Claude Desktop and Cursor IDE with simple Python code and zero boilerplate.
Your Custom AI Database Bridge: Building a Model Context Protocol (MCP) server in Python using FastMCP to link SQLite and PostgreSQL directly to Claude and Cursor.

Key takeaways

  • FastMCP is a friendly Python library that lets you build a Model Context Protocol (MCP) server using simple decorators like @mcp.tool()—just like writing a FastAPI app.
  • Instead of copying and pasting database tables into your chat, your AI assistant (Claude Desktop or Cursor) can query schemas, run test searches, and inspect data directly.
  • You can build a working SQLite database server in fewer than 30 lines of clean Python code without needing complex TypeScript or messy boilerplate.
  • Connecting to Cursor or Claude takes one tiny JSON block pointing to your Python script using uv or python3.
  • Always protect your data: use read-only queries (SELECT only), add parameterized inputs to stop SQL injection, and never hand an AI agent delete or drop permissions.

Let's be completely honest with each other: we have all suffered through the painful copy-paste marathon.

You are working on a tricky bug in your application. Your backend keeps throwing an error, and you need help from Claude or Cursor. So you open your database app, run a query, copy 40 rows of JSON results, jump back to your AI chat, paste it in, write out your table schema by hand, and explain what each column means. Five minutes later, you change a query parameter and you have to repeat the entire dance all over again.

It drains your energy, breaks your creative flow, and frankly makes modern AI feel a lot less magical than it should be.

What if your AI assistant could simply reach out, look at your database tables with its own eyes, run safe queries, and help you fix the bug immediately—all without you lifting a finger to copy-paste anything? That is exactly what the Model Context Protocol (MCP) does. And thanks to a delightful Python tool called FastMCP, you can build your own custom database bridge in less than 15 minutes, using plain, friendly Python that anyone can write.

In this hands-on, step-by-step guide, I will walk you through building your very first FastMCP server from scratch. We will connect a real database (SQLite first, then PostgreSQL), hook it up to both Claude Desktop and Cursor, and wrap it in tight safety locks so your data stays 100% safe. No confusing computer science buzzwords, no endless boilerplate—just simple steps that actually work.

Quick Answer: What is FastMCP and How Does It Work?

FastMCP is an open-source Python framework that makes building Model Context Protocol (MCP) servers as easy as building a tiny web app with FastAPI. Instead of writing complex low-level JSON-RPC protocol code by hand, you write regular Python functions and add a simple @mcp.tool() tag above them.

Once your server is running, AI clients like Claude Desktop and Cursor can call your Python functions directly through standard input and output (stdio). When Claude wants to know your database structure or look up customer records, it asks your FastMCP server, your server runs a safe query, and returns the answers straight into the conversation.

Why FastMCP Is a Breath of Fresh Air for Developers

When Anthropic first launched the Model Context Protocol in late 2024, the official software development kit (SDK) was primarily built around TypeScript and Node.js. While it was powerful, writing a custom server felt heavy. You had to define JSON schemas by hand, handle input validation types, configure transport streams, and write dozens of lines of setup code just to return a simple list of names.

For Python developers, data scientists, and backend engineers, this felt frustrating. Python is the natural language of data analysis, AI models, and database scripting! Why should you have to leave your favorite language just to connect a database to your coding assistant?

Enter FastMCP. Created to bring the simplicity and joy of FastAPI to the MCP universe, FastMCP changes the game in three big ways:

  • Python Type Hints Do the Work: You just write normal Python type hints (like query: str, limit: int = 10). FastMCP automatically translates those types into the exact JSON schema that Claude and Cursor understand.
  • Docstrings Become Tool Descriptions: Whatever you write in your Python function docstring is read directly by the AI model to understand when and how to use the tool.
  • Zero Boilerplate: A complete, working server that exposes two database tools takes fewer than 30 lines of code. You can read the whole program in one glance.

How FastMCP Connects Your Tools Together

💻 1. The AI Client Claude Desktop or Cursor IDE receives your prompt and decides it needs database data.
⚡ 2. Your FastMCP Server Runs quietly in the background via Python, listens for requests, and executes your safe function.
🗄️ 3. Your Live Database SQLite, PostgreSQL, or MySQL returns clean rows back to your AI pair programmer.

What You Will Need Before We Begin (Prerequisites)

You do not need any fancy tools to follow along. Everything we use is free and takes just two minutes to get ready:

  1. Python 3.10 or newer: Installed on your Mac, Windows, or Linux machine. You can check by running python3 --version in your terminal.
  2. A modern package manager: We recommend uv (the blazing-fast Python tool from Astral) or standard pip.
  3. Claude Desktop or Cursor IDE: Make sure you have at least one of these installed so you can test your new server live!
  4. A sample database: We will create a small SQLite database in Step 2 with fake customer and order data so you don't have to risk any sensitive company files.

Step 1: Install FastMCP in Under 30 Seconds

Let's start by setting up a clean folder for our project and installing the fastmcp package. Open your terminal and run these commands:

# 1. Create a new directory and move into it
mkdir my-first-fastmcp
cd my-first-fastmcp

# 2. Create a clean virtual environment (optional but recommended)
python3 -m venv .venv
source .venv/bin/activate  # On Windows, use: .venv\Scripts\activate

# 3. Install FastMCP
pip install fastmcp

If you prefer using uv (which is wonderfully fast and great for running MCP servers), you can simply install it via:

uv add fastmcp

That is all the installation required! No complex build tools, no Node dependencies, no headaches.


Step 2: Create a Practice SQLite Database

To keep things 100% safe and simple, let's create a small SQLite database called store.db with two tables: customers and orders.

Create a file named setup_db.py and paste this code:

# setup_db.py
import sqlite3

# Connect to our local SQLite database file
conn = sqlite3.connect("store.db")
cursor = conn.cursor()

# Create a customers table
cursor.execute('''
CREATE TABLE IF NOT EXISTS customers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL,
    plan TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')

# Create an orders table
cursor.execute('''
CREATE TABLE IF NOT EXISTS orders (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    customer_id INTEGER,
    amount REAL NOT NULL,
    status TEXT NOT NULL,
    product_name TEXT NOT NULL,
    FOREIGN KEY(customer_id) REFERENCES customers(id)
)
''')

# Insert a few friendly sample records
cursor.execute("INSERT OR IGNORE INTO customers (name, email, plan) VALUES ('Sarah Connor', 'sarah@example.com', 'Pro')")
cursor.execute("INSERT OR IGNORE INTO customers (name, email, plan) VALUES ('Alex Murphy', 'alex@example.com', 'Enterprise')")
cursor.execute("INSERT OR IGNORE INTO customers (name, email, plan) VALUES ('Ellen Ripley', 'ripley@example.com', 'Starter')")

cursor.execute("INSERT OR IGNORE INTO orders (customer_id, amount, status, product_name) VALUES (1, 49.99, 'completed', 'AI Code Assistant Annual')")
cursor.execute("INSERT OR IGNORE INTO orders (customer_id, amount, status, product_name) VALUES (2, 299.00, 'completed', 'Team Workspace Seat')")
cursor.execute("INSERT OR IGNORE INTO orders (customer_id, amount, status, product_name) VALUES (1, 15.00, 'pending', 'Additional Storage')")

conn.commit()
conn.close()
print("Success! Created store.db with sample customers and orders.")

Run it in your terminal:

python3 setup_db.py

You now have a clean local database ready to explore!


Step 3: Write Your FastMCP Server Code (The Magic Part)

Here is where FastMCP truly shines. We are going to create a file called server.py. We will give our AI pair programmer three superpowers:

  1. list_tables: Tells the AI what tables exist in the database so it never has to guess.
  2. describe_table: Shows the exact columns, types, and constraints for any table.
  3. run_read_query: Executes a safe, read-only SQL query and returns the rows as neat text.

Take a look at how clean and readable this code is:

# server.py
import sqlite3
import os
from fastmcp import FastMCP

# 1. Initialize our FastMCP server with a friendly name
mcp = FastMCP("Local Store Database Manager")

# Helper function to get a database connection
def get_db_path() -> str:
    # Always resolve the absolute path so Claude Desktop finds the file
    base_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_dir, "store.db")

@mcp.tool()
def list_tables() -> list[str]:
    """Get a list of all tables present in the store database."""
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = [row[0] for row in cursor.fetchall() if row[0] != "sqlite_sequence"]
    conn.close()
    return tables

@mcp.tool()
def describe_table(table_name: str) -> list[dict]:
    """
    Get column details, data types, and primary keys for a specific table.
    
    Args:
        table_name: The name of the table to inspect (e.g. 'customers' or 'orders')
    """
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    
    # Use PRAGMA table_info to inspect the schema safely
    cursor.execute(f"PRAGMA table_info({table_name});")
    columns = []
    for col in cursor.fetchall():
        columns.append({
            "column_id": col[0],
            "name": col[1],
            "type": col[2],
            "not_null": bool(col[3]),
            "primary_key": bool(col[5])
        })
    conn.close()
    return columns

@mcp.tool()
def run_read_query(query: str) -> list[dict]:
    """
    Run a safe read-only SQL SELECT query on the store database and return matching rows.
    
    Args:
        query: The SQL SELECT statement to execute. Must start with SELECT.
    """
    clean_query = query.strip()
    
    # Safety Check: strictly forbid modifying commands
    forbidden_words = ["DROP", "DELETE", "UPDATE", "INSERT", "ALTER", "TRUNCATE"]
    upper_query = clean_query.upper()
    
    for word in forbidden_words:
        if word in upper_query:
            raise ValueError(f"Security Alert: The command '{word}' is not allowed. Only read-only SELECT queries are permitted.")
            
    if not upper_query.startswith("SELECT") and not upper_query.startswith("PRAGMA"):
        raise ValueError("Security Alert: Only SELECT queries are permitted.")

    conn = sqlite3.connect(get_db_path())
    conn.row_factory = sqlite3.Row  # Returns rows as dictionaries
    cursor = conn.cursor()
    
    try:
        cursor.execute(clean_query)
        rows = [dict(row) for row in cursor.fetchall()]
        return rows
    finally:
        conn.close()

# 2. Run the server using standard input/output when started
if __name__ == "__main__":
    mcp.run(transport="stdio")

Notice how straightforward this is:

  • FastMCP("Local Store Database Manager") names your server so you can spot it inside your AI editor.
  • @mcp.tool() is the only decorator you need. Any regular Python function marked with @mcp.tool() instantly becomes a tool that Claude or Cursor can execute!
  • The docstrings (the text inside comments) are not just notes for developers—Claude and Cursor actually read them to know when to call the tool and what arguments to provide.

Step 4: Test Your FastMCP Server in Your Terminal First

Before hooking this up to Claude or Cursor, it is always a smart idea to make sure our Python script runs without syntax errors. FastMCP comes with a handy built-in testing utility!

Run this command in your project directory:

fastmcp dev server.py

This command boots up an interactive test runner in your browser. You can click on each tool, pass in sample arguments (like typing customers into describe_table), and see the live JSON response immediately. When you see your customers table pop up on screen, celebrate for a second—you just built your very first Model Context Protocol server!


Step 5: Connect Your Server to Claude Desktop

Now let's bring our server to life inside Claude Desktop. Claude connects to local MCP servers through a small JSON configuration file on your computer.

1. Find Your Configuration File:

  • On a Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
  • On Windows: %APPDATA%\Claude\claude_desktop_config.json

If the file or folder does not exist yet, you can create it. Open the file in your favorite text editor (VS Code, TextEdit, or Notepad) and add your server definition:

{
  "mcpServers": {
    "store-db": {
      "command": "/Users/yourname/my-first-fastmcp/.venv/bin/python",
      "args": [
        "/Users/yourname/my-first-fastmcp/server.py"
      ]
    }
  }
}
Pro-Tip for Absolute Paths: Always use the full, absolute path to both your Python executable and your server.py file. Never use shortcuts like ~ or relative paths like ./server.py, because Claude Desktop launches background processes from its own application root folder.

2. Test It Live in Claude Desktop:

  1. Completely quit Claude Desktop (on Mac, press Cmd + Q; on Windows, right-click the taskbar icon and select Quit).
  2. Open Claude Desktop again.
  3. Look at the bottom right of the message box. You will see a small hammer icon or electrical plug icon with a number next to it. Click it, and you should see store-db with your 3 tools listed!
  4. Type a prompt like this:
    "Hey Claude, what tables are in our store database, and how many pending orders do we have?"

Watch in amazement as Claude calls list_tables, checks the orders table schema, runs a query to count pending orders, and gives you a clear, friendly answer in seconds!


Step 6: Connect Your Server to Cursor IDE

If you write code daily in Cursor, connecting your FastMCP server is just as effortless. Cursor gives you two easy ways to do it:

Method A: Through Cursor Settings (Easiest for Beginners)

  1. Open Cursor and press Cmd + , (or Ctrl + , on Windows) to open Settings.
  2. In the left sidebar, navigate to Features → MCP Servers.
  3. Click the Add New MCP Server button.
  4. Fill in the fields:
    • Name: store-db
    • Type: command
    • Command: /absolute/path/to/my-first-fastmcp/.venv/bin/python /absolute/path/to/my-first-fastmcp/server.py
  5. Click Save. A green indicator dot will turn on, showing your server is live!

Method B: Project-Level .cursor/mcp.json (Best for Teams)

If you want everyone on your team to have access to this server when they open your project repository, create a file named .cursor/mcp.json right inside your project root:

{
  "mcpServers": {
    "store-db": {
      "command": "python3",
      "args": ["server.py"]
    }
  }
}

Now in Cursor Composer (press Cmd + I or Ctrl + I), you can ask:

"@store-db Check our orders table and write a Python FastAPI endpoint that calculates average revenue per customer."

Cursor will inspect the actual columns, see that customer_id and amount exist, and write mathematically accurate code on the first try!


Level Up: Connecting to PostgreSQL with Real Production Safety

SQLite is wonderful for local files and rapid prototyping. But in real-world software engineering, your application data lives in a production or staging database like PostgreSQL.

Can FastMCP handle PostgreSQL? Absolutely! The pattern is identical. All you do is swap SQLite's library for psycopg (or psycopg2). Here is a production-ready snippet:

# postgres_server.py
import psycopg
from fastmcp import FastMCP

mcp = FastMCP("Postgres Production Staging Assistant")

# Connect using a dedicated READ-ONLY database user
DB_URL = "postgresql://readonly_user:securepassword@localhost:5432/my_staging_db"

@mcp.tool()
def get_postgres_tables() -> list[str]:
    """List all public relational tables in the PostgreSQL database."""
    with psycopg.connect(DB_URL) as conn:
        with conn.cursor() as cur:
            cur.execute("""
                SELECT table_name 
                FROM information_schema.tables 
                WHERE table_schema = 'public'
                ORDER BY table_name;
            """)
            return [row[0] for row in cur.fetchall()]

@mcp.tool()
def explain_slow_query(sql_statement: str) -> str:
    """
    Run EXPLAIN (ANALYZE, COSTS, BUFFERS) on a query to understand execution bottlenecks.
    
    Args:
        sql_statement: The SELECT query to profile.
    """
    if not sql_statement.strip().upper().startswith("SELECT"):
        return "Error: Can only analyze SELECT statements."

    with psycopg.connect(DB_URL) as conn:
        with conn.cursor() as cur:
            cur.execute(f"EXPLAIN ANALYZE {sql_statement}")
            plan_lines = [row[0] for row in cur.fetchall()]
            return "\n".join(plan_lines)

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

Imagine having Claude or Cursor analyze slow queries with EXPLAIN ANALYZE right inside your chat box and suggest the exact index that cuts your execution time from 400ms down to 4ms! That is what true AI-assisted engineering feels like.


3 Non-Negotiable Safety Rules When Connecting AI to Databases

Giving an AI assistant access to run queries is an incredible superpower, but you must keep your systems safe. Never skip these three golden rules:

1. Read-Only Always

Never give your MCP server credentials for an admin or write account. In PostgreSQL, create a user with GRANT SELECT ON ALL TABLES and nothing else. If an AI hallucinates, it cannot drop your tables.

2. Hide Sensitive Columns

If your tables have password hashes, billing credit card tokens, or private medical details, write an explicit block in your Python code that filters those columns out before returning data to the AI context window.

3. Limit Row Returns

Always add an automatic LIMIT 50 or LIMIT 100 to SQL queries. If an AI runs SELECT * FROM logs on a table with 2 million rows, it will instantly blow up your token limits and freeze your editor.


Troubleshooting: What to Do If Your Server Won't Connect

If you see a red indicator light in Cursor or the tool icon doesn't show up in Claude Desktop, don't panic! Here are the three most common hiccups and how to solve them in 30 seconds:

  • Symptom: Claude Desktop says "Server disconnected" immediately upon opening.
    Fix: Check your claude_desktop_config.json file. Did you use relative paths like ./server.py? Change them to full absolute paths like /Users/myname/projects/my-first-fastmcp/server.py. Also verify that your JSON file has no missing or trailing commas.
  • Symptom: The server starts, but says ModuleNotFoundError: No module named 'fastmcp'.
    Fix: Claude Desktop is using your system Python instead of your virtual environment. Point the "command" setting directly to the Python binary inside your .venv/bin/python folder.
  • Symptom: Cursor shows a yellow loading spinner forever.
    Fix: Make sure your server.py file does NOT have any print() statements outside of tools. Because MCP communicates over standard output (stdio), any loose print("hello world") will corrupt the JSON-RPC message stream and confuse the client.

Frequently Asked Questions About Building FastMCP Servers

Yes! FastMCP is built on top of the official Model Context Protocol standard and is recognized across the open-source AI engineering ecosystem as the premier, pythonic way to build MCP servers without the verbosity of raw protocol specifications.

Yes! FastMCP supports both local stdio transport (used for local editors on your laptop) and SSE (Server-Sent Events) over HTTP. This means you can deploy your FastMCP server to a cloud provider like Fly.io, Railway, or AWS, and let your team connect to it remotely.

Yes! Because Model Context Protocol is an open industry standard (JSON-RPC 2.0), any editor that supports MCP—including Windsurf Cascade, Zed, Continue.dev, and Sourcegraph Cody—can run your FastMCP server with the exact same configuration syntax.

Absolutely. Besides @mcp.tool(), FastMCP provides @mcp.resource("schema://{table}") to expose passive context data, and @mcp.prompt() to create reusable prompt templates that guide your team in asking structured questions.

Final Thoughts: Your AI Pair Programmer Just Got a Real Brain

When you take a step back and look at what you just built, it is genuinely exciting. You did not just write a Python script—you gave Claude and Cursor real-world senses. Instead of guessing your column names or forcing you to manually copy-paste query results, your AI assistant can now explore your data responsibly, verify facts on the fly, and help you ship cleaner code in half the time.

The beauty of FastMCP is that databases are only the starting point. You can use the exact same pattern to connect your local Docker containers, your company's internal REST APIs, your Redis cache, or even your local files.

Start with this simple SQLite setup, test it out on your personal projects, and see how much lighter your workday feels when you never have to do the copy-paste marathon again.

Ready to explore more MCP tools?
Discover pre-built servers for GitHub, Slack, Docker, and PostgreSQL in our complete developer catalog.

Frequently asked questions

FastMCP is a high-level Python library designed to make building Model Context Protocol (MCP) servers super fast and easy. Instead of writing dozens of lines of JSON-RPC protocol code by hand, you write standard Python functions and put a simple '@mcp.tool()' tag on top. FastMCP automatically creates the schemas, types, and connections for you.

Pre-built database MCP servers are great for generic setups, but custom FastMCP servers let you add your own business rules. You can filter out private columns (like user passwords or API tokens), create custom shortcuts (like 'get_active_subscribers()'), and join data from different databases or internal APIs in one single tool.

No! FastMCP is 100% free and open-source. It runs locally as a process on your own computer. You only need your usual Claude or Cursor account to talk to the AI model itself.

Yes, absolutely! The exact same FastMCP pattern works with any Python database library—like psycopg for PostgreSQL, pymysql for MySQL, or duckdb for analytics. You simply open your connection inside the tool function and return the rows as simple dictionaries or text.

You enforce safety in two simple ways: first, use a read-only database user account that only has SELECT permissions. Second, in your Python tool code, check that queries start with 'SELECT' or 'PRAGMA' and reject any commands with 'DROP', 'DELETE', 'UPDATE', or 'ALTER'.

On a Mac for Claude Desktop, the file is at '~/Library/Application Support/Claude/claude_desktop_config.json'. On Windows, it is at '%APPDATA%\Claude\claude_desktop_config.json'. In Cursor, open Settings, go to Features > MCP, and click 'Add New MCP Server', or create a '.cursor/mcp.json' file right inside your project folder.

A Tool is an action your AI can actively decide to run (like running a search query). A Resource is passive data your AI can read as background context (like a database schema or a file). A Prompt is a pre-written conversation template that helps users ask better questions.
Photo of Sanket

Sanket Founder, Aiversely

Sanket runs Aiversely and writes its guides on AI tools and workflows, with AI assistance for drafting and editing.

About Aiversely →
Join WhatsApp Channel

My AI Toolkit

0 items saved in this browser