Skip to main content

Python MCP Template

This guide walks you through using the official Python template for building Model Context Protocol (MCP) servers.

Introduction

The Python template provides a solid foundation for developing MCP servers using Python. It includes all the necessary boilerplate code and demonstrates best practices for building production-ready MCP applications.

Getting Started

Prerequisites

Before you begin, make sure you have:

  • Python 3.8 or later installed
  • pip package manager
  • TRMX CLI installed (see Installation Guide)

Creating a New Project

Create a new MCP server using the Python template:

# Using the TRMX CLI
trmx init my-python-mcp-server --template python

# Navigate to the project directory
cd my-python-mcp-server

# Create a virtual environment
python -m venv venv

# Activate the virtual environment
# On Windows
venv\Scripts\activate
# On macOS/Linux
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

Project Structure

The Python template creates the following directory structure:

my-python-mcp-server/
├── src/
│ ├── config/
│ │ ├── __init__.py # Configuration settings
│ │ └── logger.py # Logging configuration
│ ├── tools/
│ │ ├── __init__.py # Tool registration
│ │ └── calculator.py # Example calculator tool
│ ├── resources/
│ │ └── __init__.py # Resource registration
│ ├── prompts/
│ │ └── __init__.py # Prompt template registration
│ ├── middleware/
│ │ └── auth.py # Authentication middleware
│ ├── utils/
│ │ └── error_handler.py # Error handling utilities
│ └── main.py # Main entry point
├── tests/
│ ├── tools/
│ │ └── test_calculator.py # Tool unit tests
│ └── integration/
│ └── test_api.py # API integration tests
├── .env # Environment variables
├── .env.example # Example environment variables
├── .gitignore
├── requirements.txt
├── README.md
└── Dockerfile # Docker configuration

Core Components

Server Configuration

The main server configuration is in src/config/__init__.py:

# src/config/__init__.py
import os
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

class Config:
PORT = int(os.getenv('PORT', 3000))
ENVIRONMENT = os.getenv('ENVIRONMENT', 'development')
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')
AUTH_ENABLED = os.getenv('AUTH_ENABLED', 'false').lower() == 'true'
API_KEY = os.getenv('API_KEY')
DEFAULT_MODEL = os.getenv('DEFAULT_MODEL', 'gpt-4')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

config = Config()

Main Entry Point

The server's entry point is src/main.py:

# src/main.py
from trmx.server import MCPServer
from config import config
from tools import tools
from resources import resources
from prompts import prompts
from config.logger import logger

def main():
try:
# Create an MCP server
server = MCPServer(
port=config.PORT,
tools=tools,
resources=resources,
prompts=prompts,
logger=logger
)

# Start the server
server.start()
logger.info(f"MCP server running on port {config.PORT}")
except Exception as e:
logger.error(f"Failed to start MCP server: {e}")
exit(1)

if __name__ == "__main__":
main()

Defining Tools

Create tools in the src/tools directory:

# src/tools/calculator.py
class CalculatorTool:
name = 'calculator'
description = 'Performs basic arithmetic operations'
parameters = {
'type': 'object',
'properties': {
'operation': {
'type': 'string',
'enum': ['add', 'subtract', 'multiply', 'divide'],
'description': 'The operation to perform'
},
'a': {
'type': 'number',
'description': 'First operand'
},
'b': {
'type': 'number',
'description': 'Second operand'
}
},
'required': ['operation', 'a', 'b']
}

async def execute(self, params):
operation = params['operation']
a = params['a']
b = params['b']

if operation == 'add':
return {'result': a + b}
elif operation == 'subtract':
return {'result': a - b}
elif operation == 'multiply':
return {'result': a * b}
elif operation == 'divide':
if b == 0:
raise ValueError('Division by zero')
return {'result': a / b}
else:
raise ValueError(f'Unknown operation: {operation}')

calculator_tool = CalculatorTool()

Register tools in src/tools/__init__.py:

# src/tools/__init__.py
from .calculator import calculator_tool

tools = [
calculator_tool
# Add more tools here
]

Adding Resources

Create resources in the src/resources directory:

# src/resources/documents.py
class DocumentsResource:
name = 'documents'
description = 'Access to company documentation'

async def fetch(self, query):
# In a real implementation, you would search a database or other data source
documents = [
{'id': 1, 'title': 'Getting Started', 'content': 'This guide helps you get started with our product...'},
{'id': 2, 'title': 'API Reference', 'content': 'Detailed API documentation for developers...'},
{'id': 3, 'title': 'Best Practices', 'content': 'Learn best practices for using our platform...'}
]

# Simple search implementation
results = [doc for doc in documents if
query.lower() in doc['title'].lower() or
query.lower() in doc['content'].lower()]

return [
{
'id': str(doc['id']),
'title': doc['title'],
'content': doc['content']
} for doc in results
]

documents_resource = DocumentsResource()

Register resources in src/resources/__init__.py:

# src/resources/__init__.py
from .documents import documents_resource

resources = [
documents_resource
# Add more resources here
]

Running in Development Mode

The template is configured for easy development:

# Start development server with hot reloading
python -m src.main

Building for Production

Prepare your project for production:

# Install production dependencies
pip install -r requirements.txt

# Start in production mode
ENVIRONMENT=production python -m src.main

Testing

The template includes pytest for testing:

# Run all tests
pytest

# Run tests with coverage
pytest --cov=src

Example test for the calculator tool:

# tests/tools/test_calculator.py
import pytest
from src.tools.calculator import calculator_tool

async def test_calculator_add():
result = await calculator_tool.execute({
'operation': 'add',
'a': 5,
'b': 3
})

assert result == {'result': 8}

async def test_calculator_divide_by_zero():
with pytest.raises(ValueError, match='Division by zero'):
await calculator_tool.execute({
'operation': 'divide',
'a': 10,
'b': 0
})

Deployment

Docker Deployment

The template includes a Dockerfile for containerization:

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY src/ ./src/

ENV ENVIRONMENT=production
ENV PORT=3000

EXPOSE 3000

CMD ["python", "-m", "src.main"]

Build and run the Docker container:

# Build Docker image
docker build -t my-python-mcp-server .

# Run Docker container
docker run -p 3000:3000 --env-file .env my-python-mcp-server

Next Steps