惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
有赞技术团队
有赞技术团队
量子位
N
Netflix TechBlog - Medium
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Blog — PlanetScale
Blog — PlanetScale
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
V2EX
IT之家
IT之家
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

DigitalOcean Community Tutorials

It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu
How to Build an MCP Server in Python
Amit Jotwani · 2026-06-12 · via DigitalOcean Community Tutorials

Introduction

An MCP server in Python exposes tools, resources, and prompts to AI hosts through the Model Context Protocol (MCP). You write a small Python program. Cursor, Claude Desktop, or another MCP host starts the program and calls your functions when the model needs live data.

This tutorial builds a local SQLite query server with the official MCP Python SDK and FastMCP. You register one tool, connect the server to Cursor and Claude Desktop, and confirm the model reads your database at chat time.

For protocol background, start with DigitalOcean’s MCP 101: An Introduction to Model Context Protocol and Understanding Model Context Protocol (MCP).

claude_mcp_server_sqlite_demo
I ask for the top chatters and Claude shows the results straight from my MCP server.
cursor_mcp_server_sqlite_demo
I request the top chatters and Cursor pulls the data live from my MCP server.

Key takeaways

  • An MCP server in Python uses the mcp package. Pin mcp>=1.27,<2 until the stable 2.x release ships.
  • FastMCP (from mcp.server.fastmcp import FastMCP) registers tools with @mcp.tool() and runs over stdio by default for local hosts.
  • MCP has three primitives: tools (model actions), resources (read-only data), and prompts (reusable templates). This tutorial focuses on tools.
  • Local hosts start your server as a subprocess. Cursor reads ~/.cursor/mcp.json. Claude Desktop reads claude_desktop_config.json under both mcpServers keys.
  • Use absolute paths to your virtualenv Python binary and server script in every config file.
  • On stdio transports, log to stderr. Never print() to stdout or you break JSON-RPC messages.
  • After setup, the host shows a green status dot (Cursor) or a tools icon (Claude Desktop). Approve each tool call before the server runs.

What you’ll learn

  • Why MCP matters for LLM apps
  • How to build a Python MCP server with FastMCP and SQLite
  • How to register the server in Cursor and Claude Desktop
  • How to test tool calls end to end
  • Where to go next for remote MCP and production deployment

Prerequisites

Before you start, confirm you have:

What is MCP and why do you need it?

MCP is an open protocol for connecting LLM hosts to external data and actions. Anthropic introduced MCP in November 2024. Hosts speak JSON-RPC over stdio or HTTP transports. Servers expose structured capabilities instead of custom one-off integrations per model.

Large language models predict text. They do not query your database or call your APIs unless a host routes a tool call to a server you control. MCP standardizes that bridge.

Role What it does Example in this tutorial
Host UI where you chat Cursor or Claude Desktop
Client MCP protocol layer inside the host Built into the host app
Server Your Python code with tools sqlite-server.py
Tool Function the model requests get_top_chatters

How the pieces fit together

When you chat in Cursor or Claude Desktop, the host is the app window. The MCP client inside the host lists available tools, sends your message to the model, and forwards approved tool calls to your server.

  1. You ask a question, for example “List the top chatters.”
  2. The model selects the get_top_chatters tool if the description matches.
  3. The host asks you to approve the tool call.
  4. The MCP client sends the call to your Python server over stdio.
  5. The server queries SQLite and returns JSON rows.
  6. The model formats the answer in the chat.

mcp-flow-diagram

Everything in the diagram runs on your machine for this walkthrough. The host spawns your server locally. The server opens community.db on disk.

Note: Host and client often share one process. To write a standalone MCP client, follow the Build an MCP client guide.

MCP server primitives at a glance

Primitive Who controls it Purpose
Tool Model (with user approval) Run code: query a DB, call an API
Resource Application Expose read-only files or records
Prompt User Ship reusable prompt templates

This project implements one tool. Resources and prompts follow the same FastMCP decorators (@mcp.resource(), @mcp.prompt()). See the MCP Python SDK server docs for full examples.

Building your first MCP server in Python

You will create a virtual environment, install the SDK, download sample data, and write sqlite-server.py.

Step 1: Set up your environment

Create and activate a virtual environment:

python3 -m venv mcp-env
source mcp-env/bin/activate

On Windows PowerShell:

python -m venv mcp-env
mcp-env\Scripts\Activate.ps1

Install the MCP Python SDK. Pin below 2.x while v2 is in alpha:

pip install "mcp>=1.27,<2"

Step 2: Download the sample database

Download community.db into the same folder as your server script. The file contains a chatters table with name and messages columns.

For SQLite fundamentals in a web app context, see How To Use an SQLite Database in a Flask Application.

Step 3: Write the MCP server

Create sqlite-server.py:

# sqlite-server.py
from pathlib import Path

import sqlite3
from mcp.server.fastmcp import FastMCP

DB_PATH = Path(__file__).resolve().parent / "community.db"

mcp = FastMCP("Community Chatters")


@mcp.tool()
def get_top_chatters(limit: int = 10) -> list[dict]:
    """Return chatters ranked by message count."""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute(
        "SELECT name, messages FROM chatters ORDER BY messages DESC LIMIT ?",
        (limit,),
    )
    rows = cursor.fetchall()
    conn.close()
    return [{"name": name, "messages": messages} for name, messages in rows]


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

FastMCP reads the function name, type hints, and docstring to build the tool schema. mcp.run() starts the stdio transport, which local hosts expect.

Stdio logging: Do not use print() on stdout in stdio servers. Use logging or print(..., file=sys.stderr) so JSON-RPC frames stay intact. See the official server logging notes.

Test the query without the host:

python3 -c "import sqlite3; c=sqlite3.connect('community.db'); print(c.execute('SELECT COUNT(*) FROM chatters').fetchone())"

You should see a row count printed to the terminal.

Adding your MCP server to Cursor

Open Cursor → Settings → MCP and click Add a New Global MCP Server. Cursor opens ~/.cursor/mcp.json.

cursor_mcp_server_sqlite_add

Replace the placeholder paths with your absolute paths. Run which python inside your activated virtualenv to get the interpreter path.

{
  "mcpServers": {
    "sqlite-server": {
      "command": "/absolute/path/to/mcp-env/bin/python",
      "args": [
        "/absolute/path/to/sqlite-server.py"
      ],
      "description": "Query top chatters from the community SQLite database"
    }
  }
}

cursor_mcp_server_sqlite_json

Save the file and return to MCP Settings. A green dot next to the server name means the process started cleanly.

cursor_mcp_server_sqlite_verify

Testing your MCP server in Cursor

  1. Open a chat and ask: “How many chatters are in the database?”
  2. Cursor proposes the get_top_chatters tool. Approve the prompt.
  3. The server returns rows. The model summarizes them in the reply.

cursor_mcp_server_sqlite_ask

cursor_mcp_server_sqlite_results

If the tool never appears, see Troubleshooting below.

Adding your MCP server to Claude Desktop

Claude Desktop uses the same mcpServers object shape as Cursor.

  1. Open Claude Desktop → Settings → Developer → Edit Config.
  2. Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json).
  3. Add your server block with the same command and args paths as Cursor.
  4. Save, quit Claude Desktop completely, and reopen the app.
{
  "mcpServers": {
    "sqlite-server": {
      "command": "/absolute/path/to/mcp-env/bin/python",
      "args": [
        "/absolute/path/to/sqlite-server.py"
      ]
    }
  }
}

claude_mcp_server_sqlite_tool_icon

Ask Claude: “Show me the top five chatters.” Approve the tool call when prompted.

claude_mcp_server_sqlite_ask

claude_mcp_server_sqlite_results

The same Python server now works from two hosts. The model brand changes. The MCP contract stays the same.

Troubleshooting

Symptom Fix
Red or missing status in Cursor Check absolute paths, confirm pip show mcp inside the venv, run the server manually with the same command and args
Tool never offered Improve the tool docstring, restart the host, verify the green dot or tools icon
ModuleNotFoundError: mcp Activate the venv whose Python path you put in mcp.json
Empty or error results Confirm community.db sits beside sqlite-server.py
Claude Desktop shows no tools Use mcpServers, not a top-level servers array. Restart the app after edits

Claude Desktop writes MCP logs to ~/Library/Logs/Claude/mcp*.log on macOS. See Connect to local MCP servers for log locations on other platforms.

FAQs

1. What is MCP in Python?

MCP in Python means you implement a Model Context Protocol server with the mcp package (FastMCP on top). The server exposes tools the host forwards to the model. Python is one supported language. The TypeScript SDK serves the same role for Node hosts.

2. What is the best Python MCP library for building a server?

You can use the official mcp package with FastMCP from mcp.server.fastmcp. Install with pip install "mcp>=1.27,<2". The standalone fastmcp project targets the same ergonomic API for HTTP-first deployments. Start with the official SDK so your code matches modelcontextprotocol.io docs.

3. How do you create an MCP server in Python?

  1. Create a virtualenv and pip install "mcp>=1.27,<2".
  2. Instantiate FastMCP("ServerName").
  3. Register functions with @mcp.tool().
  4. Call mcp.run() under if __name__ == "__main__":.
  5. Point Cursor or Claude Desktop at the venv Python and your script path in mcpServers.

The create-python-server scaffold generates a starter repo if you prefer a template.

4. What is the difference between an MCP SDK and MCP?

MCP is the protocol specification (messages, transports, capability types). An MCP SDK is a language library that implements the spec. The Python SDK handles JSON-RPC framing, schema generation, and stdio or HTTP transports so you focus on tool logic.

5. Is MCP just a REST API?

No. MCP uses JSON-RPC messages and a defined capability model (tools, resources, prompts). Hosts spawn stdio servers or connect over Streamable HTTP. REST endpoints are optional. You wrap existing REST APIs inside tool functions, but the wire format is not plain HTTP CRUD.

Conclusion

You built an MCP server in Python with FastMCP, wired SQLite data into Cursor and Claude Desktop, and validated tool calls end to end. The same pattern extends to email gateways, cloud APIs, and deployment workflows.

What’s next

Grow from this local stdio server into production-oriented patterns:

Run experiments on a DigitalOcean Droplet or ship apps with App Platform. For managed models and knowledge bases, explore the DigitalOcean AI Platform.

Still looking for an answer?

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.