Build an MCP Server in Python with FastMCP

A
Author
02 Sep, 2026 1 min read 183 views

The official Python SDK includes FastMCP, a high-level API where type hints and docstrings become the tool schema. A working server takes only a few lines.

1. Create the project

uv init notes-mcp && cd notes-mcp
uv add "mcp[cli]"

2. Write the server

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

mcp = FastMCP("notes")
db = sqlite3.connect("notes.db", check_same_thread=False)
db.execute("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, title TEXT, body TEXT)")

@mcp.tool()
def add_note(title: str, body: str) -> str:
    """Save a note. Returns the new note's id."""
    cur = db.execute("INSERT INTO notes (title, body) VALUES (?, ?)", (title, body))
    db.commit()
    return f"Saved note {cur.lastrowid}"

@mcp.tool()
def search_notes(query: str, limit: int = 5) -> list[dict]:
    """Search notes whose title or body contains the query text."""
    rows = db.execute(
        "SELECT id, title, body FROM notes WHERE title LIKE ? OR body LIKE ? LIMIT ?",
        (f"%{query}%", f"%{query}%", limit),
    ).fetchall()
    return [{"id": r[0], "title": r[1], "body": r[2]} for r in rows]

@mcp.resource("notes://count")
def note_count() -> str:
    """How many notes are stored."""
    return str(db.execute("SELECT COUNT(*) FROM notes").fetchone()[0])

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

3. Test it

uv run mcp dev server.py   # starts the server with the MCP Inspector

How FastMCP builds the schema

  • Parameter names and type hints become JSON Schema properties.
  • Parameters with defaults become optional.
  • The docstring becomes the tool description, so write it for the model.
  • Return values are serialised for you; returning structured data is fine.

Going remote

To serve over HTTP instead of stdio, run mcp.run(transport="streamable-http"). Add authentication before exposing it beyond localhost.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.