A comprehensive template for building custom Model Context Protocol (MCP) servers in Python. This template provides a modular, extensible architecture with support for both stdio and SSE (Server-Sent Events) modes, making it easy to create powerful MCP servers for various use cases.
# Clone or download this template
git clone <your-repo-url>
cd mcp-template-server
# Install core dependencies
pip install -r requirements.txt
# For development (optional)
pip install -r requirements-dev.txtsource .venv/bin/activate
# Run in stdio mode (default) - for MCP clients like Claude Desktop
python -m mcp_template_server
# Run in SSE mode for web applications
python -m mcp_template_server --mode sse --port 8080
# Enable debug logging
python -m mcp_template_server --debugAdd this configuration to your MCP client (e.g., Claude Desktop):
{
  "mcpServers": {
    "template": {
      "command": "python",
      "args": ["-m", "mcp_template_server"],
      "disabled": false,
      "autoApprove": []
    }
  }
}The template includes several example tools to demonstrate different patterns:
Simple text echo functionality for testing.
{
  "name": "echo",
  "description": "Echo back the provided text",
  "parameters": {
    "text": "Text to echo",
    "prefix": "Optional prefix"
  }
}Basic arithmetic operations.
{
  "name": "calculator",
  "description": "Perform arithmetic operations",
  "parameters": {
    "operation": "add|subtract|multiply|divide",
    "a": "First number",
    "b": "Second number"
  }
}Get current time in different timezones.
{
  "name": "current_time",
  "description": "Get current time in specified timezone",
  "parameters": {
    "timezone": "Timezone name (default: UTC)",
    "format": "iso|human|both"
  }
}Make HTTP GET requests (demonstrates async operations).
{
  "name": "http_get",
  "description": "Make HTTP GET requests",
  "parameters": {
    "url": "URL to request",
    "timeout": "Request timeout in seconds",
    "headers": "Optional HTTP headers"
  }
}The template uses a modular tool handler system:
from mcp_template_server.tools.toolhandler import ToolHandler
from mcp.types import Tool, TextContent
class MyCustomTool(ToolHandler):
    def __init__(self):
        super().__init__("my_tool")
    
    def get_tool_description(self) -> Tool:
        return Tool(
            name=self.name,
            description="Description of my tool",
            inputSchema={
                "type": "object",
                "properties": {
                    "param": {"type": "string", "description": "Parameter description"}
                },
                "required": ["param"]
            }
        )
    
    async def run_tool(self, args: dict) -> Sequence[TextContent]:
        # Validate arguments
        self.validate_required_args(args, ["param"])
        
        # Tool logic here
        result = f"Processed: {args['param']}"
        
        return [TextContent(type="text", text=result)]- Create a new tool handler in src/mcp_template_server/tools/:
# my_new_tool.py
from .toolhandler import ToolHandler
from mcp.types import Tool, TextContent
from collections.abc import Sequence
class MyNewToolHandler(ToolHandler):
    def __init__(self):
        super().__init__("my_new_tool")
    
    def get_tool_description(self) -> Tool:
        # Define your tool schema
        pass
    
    async def run_tool(self, args: dict) -> Sequence[TextContent]:
        # Implement your tool logic
        pass- Register the tool in server.py:
# In register_all_tools() function
from .tools.my_new_tool import MyNewToolHandler
def register_all_tools() -> None:
    add_tool_handler(MyNewToolHandler())
    # ... other toolsFor MCP clients like Claude Desktop:
python -m mcp_template_serverFor web applications:
python -m mcp_template_server --mode sse --host 0.0.0.0 --port 8080SSE endpoints:
- GET /sse- SSE connection endpoint
- POST /messages/- Message endpoint for tool requests
You can use environment variables for configuration:
# Set log level
export MCP_LOG_LEVEL=DEBUG
# Set default server mode
export MCP_MODE=sse
# Set default port for SSE mode
export MCP_PORT=3000The server supports configurable logging:
from mcp_template_server.utils import setup_logging
# Basic setup
setup_logging(level="INFO")
# Debug mode
setup_logging(level="DEBUG", debug=True)For web applications, you can use the SSE mode:
All tools inherit from ToolHandler:
- __init__(tool_name: str): Initialize with unique tool name
- get_tool_description() -> Tool: Return MCP tool schema (abstract)
- run_tool(args: dict) -> Sequence[Content]: Execute tool logic (abstract)
- validate_required_args(args: dict, required: List[str]): Validate required arguments
- validate_string_arg(args: dict, field: str, min_length: int): Validate string argument
- add_tool_handler(handler: ToolHandler): Register a tool handler
- get_tool_handler(name: str) -> ToolHandler: Get tool handler by name
- register_all_tools(): Register all available tools
- run_server(mode: str, host: str, port: int, debug: bool): Start the server
- 
Import errors - Ensure all dependencies are installed: pip install -r requirements.txt
- Check Python version: requires Python 3.9+
 
- Ensure all dependencies are installed: 
- 
SSE mode not working - Check firewall settings for the specified port
- Verify CORS settings if accessing from a different domain
 
- 
MCP client connection issues - Verify Python path in MCP client configuration
- Check that the server starts without errors
- Ensure no other process is using the same port (SSE mode)
 
- 
Tool execution errors - Check tool argument validation
- Review server logs with --debugflag
- Verify async/await usage in tool implementations
 
- Fork the repository
- Create a feature branch: git checkout -b feature-name
- Make your changes
- Add tests for new functionality
- Run the test suite: pytest
- Commit your changes: git commit -am 'Add feature'
- Push to the branch: git push origin feature-name
- Submit a pull request
# Install development dependencies
pip install -r requirements-dev.txt
# Install pre-commit hooks (optional)
pre-commit install
# Run full test suite
pytest --cov=src/mcp_template_server
# Check code quality
black --check src/ tests/
flake8 src/ tests/
mypy src/This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the MCP Weather Server architecture
- Built on the Model Context Protocol specification
- Uses the MCP Python SDK