How to Build an MCP Server in Python
Building an MCP server in Python means using the MCP SDK to define 'tools', 'resources', and 'prompts' that an AI agent can consume over a standard protocol. This guide walks you through creating a server that makes a cloud storage bucket browsable for AI agents.
What is an MCP Server?
The Model Context Protocol (MCP) is an open standard that lets AI models interact with external data and systems safely. Instead of building custom integrations for every new LLM, you build one MCP server that works with Claude, IDEs like Cursor, and other MCP-compliant clients.
An MCP server provides three main capabilities:
- Resources: Data that agents can read (like files, logs, or API responses).
- Tools: Functions that agents can execute (like "upload_file" or "query_database").
- Prompts: Reusable templates that help agents use your server well.
Python works well for data-heavy MCP servers because of its rich ecosystem for data science, API handling, and file manipulation.
Prerequisites and Setup
You'll need Python 3.10 or higher. We recommend using uv for fast package management, but pip works fine too.
Create a new directory for your project and set up a virtual environment:
mkdir my-mcp-server
cd my-mcp-server
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Next, install the official MCP SDK. We'll use the mcp package which includes the high-level FastMCP interface:
pip install "mcp[cli]"
Now you're ready to write your first server code.
Step 1: Create a Basic Server with FastMCP
The FastMCP class handles the low-level protocol details so you can focus on your logic. Create a file named server.py:
from mcp.server.fastmcp import FastMCP
# Initialize the server
mcp = FastMCP("My Python Server")
# Define a simple tool
@mcp.tool()
def add_numbers(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
if __name__ == "__main__":
# Run the server using stdio transport by default
mcp.run()
This code creates a server with one tool, add_numbers. The docstring is critical. It tells the AI agent when and how to use this tool.
Step 2: Expose Cloud Storage as a Resource
One of the best features of MCP is Resources. Resources let you make data available via URI templates. Agents can "read" external systems as if they were local files.
Here's how to simulate a cloud storage bucket (like S3) as an MCP resource. This lets an agent read s3://my-bucket/data.txt directly.
from mcp.server.fastmcp import FastMCP, Context
# Simulated cloud storage
MOCK_BUCKET = {
"reports/2025-q1.txt": "Revenue: $5M\nGrowth: 15%",
"configs/app.json": '{"debug": true, "version": "1.0.0"}'
}
mcp = FastMCP("Cloud Storage Server")
@mcp.resource("s3://{bucket}/{path}")
def read_s3_object(bucket: str, path: str) -> str:
"""Read a file from the mock S3 bucket."""
key = f"{path}"
if key in MOCK_BUCKET:
return MOCK_BUCKET[key]
raise FileNotFoundError(f"File {path} not found in {bucket}")
With this code, if an agent asks to read s3://my-bucket/reports/2025-q1.txt, the server fetches the content and returns it. In a real application, you would use boto3 to fetch actual data from AWS.
Step 3: Define Tools for Action
While resources are for reading, Tools are for taking action. Let's add a tool that allows the agent to "upload" a file to our bucket.
@mcp.tool()
def upload_file(filename: str, content: str) -> str:
"""Upload a new file to the storage bucket."""
MOCK_BUCKET[filename] = content
return f"Successfully uploaded {filename} ({len(content)} bytes)"
Notice how we use type hints (str, int). The MCP SDK uses these to automatically generate the JSON schema that the LLM uses to validate its inputs.
Step 4: Running and Testing Your Server
MCP servers typically run over stdio (standard input/output), which is how Claude Desktop and other clients communicate with them locally.
To test your server with the MCP Inspector (a web-based debugger):
npx @modelcontextprotocol/inspector python server.py
This command launches a web UI where you can see your resources and test your tools manually.
To connect it to Claude Desktop, edit your claude_desktop_config.json:
{
"mcpServers": {
"my-python-server": {
"command": "uv",
"args": ["run", "server.py"]
}
}
}
MCP Tools vs. Resources
When should you use a Tool versus a Resource? Use this comparison to decide:
| Feature | Resource
| Tool | | :--- | :--- | :--- | | Purpose | Reading data passively | Taking action or calculating | | Interaction | GET (like a file read) | POST (function call) | | Side Effects | None (should be idempotent) | Yes (database writes, API calls) | | Agent View | "I want to read X" | "I want to do Y" | | Example | Reading a log file | Sending a Slack message |
If you need to give the AI context (like a list of users), use a Resource. If you need the AI to perform a task (like creating a user), use a Tool.
Production-Ready MCP with Fast.io
Building your own MCP server is great for custom internal tools, but managing authentication, file uploads, and large-scale storage can be complex.
Fast.io provides a managed Universal MCP Server that works out of the box. It gives your agents:
- 251 pre-built tools for file management, search, and sharing.
- Persistent storage (50GB free) so agents can save work between sessions.
- Universal access, enabling agents to read files from Google Drive, Dropbox, and S3 without you writing any integration code.
Instead of building a file system server from scratch, you can install the Fast.io skill and give your agent instant access to a production-ready cloud storage backend.
Frequently Asked Questions
How do I start an MCP server?
You start an MCP server by running your Python script. If using `FastMCP`, calling `mcp.run()` at the end of your script will automatically handle the stdio communication needed by clients like Claude Desktop.
What is the difference between an MCP tool and a resource?
A resource is passive data that an agent can read (like a file or web page), while a tool is an executable function that performs an action (like calculating a sum or sending an API request).
Can I host an MCP server on a VPS?
Yes, you can host an MCP server on a VPS. While stdio is common for local use, MCP also supports Server-Sent Events (SSE) over HTTP, allowing you to run a remote server that agents can connect to via a URL.
Give your AI agents persistent memory
Stop building file servers from scratch. Fast.io gives your agents 50GB of free cloud storage and 250+ ready-to-use tools.