Skip to main content
Glama
by rwxproject

MCP Server Template

A comprehensive, modular template for building Model Context Protocol (MCP) servers using FastMCP with professional architecture, auto-discovery, and flexible deployment options.

๐Ÿš€ Project Overview

This template provides a robust foundation for creating MCP servers with:

  • FastMCP Framework: Built on FastMCP 2.11.3+ for rapid MCP server development

  • Modular Architecture: Clean separation of tools, resources, prompts, and configuration

  • Auto-Discovery Registry: Automatic component registration using registry pattern

  • Multiple Entry Points: Backward compatibility with flexible deployment options

  • Transport Flexibility: Supports streamable HTTP and Server-Sent Events (SSE) transports

  • Comprehensive Testing: Unit and integration test suite structure

  • Development Template: Docker support, structured logging, and configuration management

  • Type Safety: Pydantic models and type hints throughout

  • Extensible Design: Easy to add new tools, resources, and prompts

Version: 0.1.0

๐Ÿƒ Quick Start Guide

Prerequisites

  • Python 3.13+

  • uv (recommended package manager)

1. Clone and Setup

git clone <your-repo> cd mcp-server-template uv venv source .venv/bin/activate uv install

2. Run the Server

Choose your preferred method:

New Modular Way (Recommended):

source .venv/bin/activate && uv run python -m mcp_server

Backward Compatible:

source .venv/bin/activate && uv run python main.py

With Custom Transport:

# Streamable HTTP transport export MCP_TRANSPORT=streamable-http export MCP_PORT=8080 source .venv/bin/activate && uv run python -m mcp_server # Server-Sent Events transport export MCP_TRANSPORT=sse export MCP_PORT=8081 source .venv/bin/activate && uv run python -m mcp_server

3. Test Connection

# Run diagnostic test source .venv/bin/activate && uv run python diagnosis_test.py # Run verification test source .venv/bin/activate && uv run python verification_test.py

๐Ÿ“ฆ Installation Instructions

Development Installation

# Clone the repository git clone <your-repo-url> cd mcp-server-template # Create and activate virtual environment uv venv source .venv/bin/activate # Install dependencies uv install # Install development dependencies uv install --group dev

Production Installation

# Install from source uv install git+<your-repo-url> # Or from local directory uv install .

๐Ÿ”ง Available Tools

Arithmetic Tools

  • add: Add two integers together

  • subtract: Subtract two integers

Weather Tools

  • get_current_weather: Get current weather information for a location

Note: Weather tool uses OpenWeatherMap API. Set WEATHER_API_KEY environment variable for real data, or it will use mock data for development.

๐Ÿ”ง Usage Examples

1. Default Mode

# Standard streamable HTTP mode source .venv/bin/activate && uv run python -m mcp_server

2. Streamable HTTP Server Mode

# Run as streamable HTTP server export MCP_TRANSPORT=streamable-http export MCP_HOST=0.0.0.0 export MCP_PORT=8080 source .venv/bin/activate && uv run python -m mcp_server

3. Server-Sent Events (SSE) Mode

# Run as SSE server export MCP_TRANSPORT=sse export MCP_HOST=0.0.0.0 export MCP_PORT=8081 source .venv/bin/activate && uv run python -m mcp_server

4. Development Mode with Debug Logging

# Enable debug logging export MCP_LOG_LEVEL=DEBUG export MCP_ENVIRONMENT=development source .venv/bin/activate && uv run python -m mcp_server

5. Docker Deployment

# Build image docker build -t mcp-server . # Run container (default mode) docker run -it mcp-server # Run container (Streamable HTTP mode) docker run -e MCP_TRANSPORT=streamable-http -e MCP_PORT=8080 -p 8080:8080 mcp-server # With custom configuration docker run -e MCP_LOG_LEVEL=DEBUG -e MCP_ENVIRONMENT=production -it mcp-server

6. Integration with Claude Desktop

Add to your Claude Desktop MCP configuration:

Default Mode (Recommended):

{ "mcpServers": { "mcp-server-template": { "command": "uv", "args": ["run", "python", "-m", "mcp_server"], "cwd": "/path/to/your/mcp-server-template" } } }

Streamable HTTP Mode:

{ "mcpServers": { "mcp-server-template": { "url": "http://localhost:8080/mcp", "transport": "streamable-http" } } }

๐Ÿ—๏ธ Architecture Overview

Directory Structure

mcp-server-template/ โ”œโ”€โ”€ src/mcp_server/ # Main package (v0.1.0) โ”‚ โ”œโ”€โ”€ __init__.py # Package initialization & lazy imports โ”‚ โ”œโ”€โ”€ __main__.py # Module entry point โ”‚ โ”œโ”€โ”€ server.py # Core FastMCP server implementation โ”‚ โ”œโ”€โ”€ config/ # Configuration management โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ settings.py # Pydantic settings with environment support โ”‚ โ”‚ โ””โ”€โ”€ logging.py # Structured logging configuration โ”‚ โ”œโ”€โ”€ tools/ # MCP tools โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ base.py # Base tool class โ”‚ โ”‚ โ”œโ”€โ”€ arithmetic.py # Arithmetic tools (add, subtract) โ”‚ โ”‚ โ”œโ”€โ”€ weather.py # Weather tools (get_current_weather) โ”‚ โ”‚ โ””โ”€โ”€ registry.py # Tool auto-discovery registry โ”‚ โ”œโ”€โ”€ resources/ # MCP resources โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ base.py # Base resource class โ”‚ โ”‚ โ”œโ”€โ”€ system.py # System information resources โ”‚ โ”‚ โ””โ”€โ”€ registry.py # Resource auto-discovery registry โ”‚ โ””โ”€โ”€ prompts/ # MCP prompts โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”œโ”€โ”€ base.py # Base prompt class โ”‚ โ”œโ”€โ”€ text_processing.py # Text processing prompts โ”‚ โ””โ”€โ”€ registry.py # Prompt auto-discovery registry โ”œโ”€โ”€ tests/ # Test suite โ”‚ โ”œโ”€โ”€ conftest.py # Shared test fixtures โ”‚ โ”œโ”€โ”€ unit/ # Unit tests โ”‚ โ”‚ โ””โ”€โ”€ test_tools.py โ”‚ โ””โ”€โ”€ integration/ # Integration tests โ”‚ โ””โ”€โ”€ test_client_interactions.py โ”œโ”€โ”€ main.py # Backward compatibility entry โ”œโ”€โ”€ Dockerfile # Container deployment โ”œโ”€โ”€ diagnosis_test.py # Server diagnostic tool โ”œโ”€โ”€ verification_test.py # Server verification tool โ””โ”€โ”€ pyproject.toml # Project configuration

Key Components

1. Server Factory Pattern

Clean server creation with comprehensive configuration:

# Server creation with auto-discovery from mcp_server import create_server server = create_server() # Automatically discovers and registers all components

2. Registry Pattern with Auto-Discovery

All components are automatically discovered and registered:

# Components are automatically found and registered from mcp_server.tools.registry import register_all_tools from mcp_server.resources.registry import register_all_resources from mcp_server.prompts.registry import register_all_prompts # Registration happens automatically in create_server() register_all_tools(mcp) register_all_resources(mcp) register_all_prompts(mcp)

3. Transport-Agnostic Design

Supports multiple transport methods:

# Flexible transport configuration await mcp.run_async( transport=settings.transport, # streamable-http or sse host=settings.host, # configurable host port=settings.port # configurable port )

4. Comprehensive Configuration

Environment-based configuration with validation:

from mcp_server.config.settings import get_settings settings = get_settings() # Loads from environment with defaults # Supports: transport, host, port, log_level, environment, etc.

๐Ÿ”จ Extension Guide

Adding New Tools

  1. Create a new tool file in src/mcp_server/tools/:

# src/mcp_server/tools/my_tool.py from typing import Any from fastmcp import FastMCP from .base import BaseTool class MyTool(BaseTool): """Example tool that processes text input.""" def __init__(self): super().__init__(name="my_tool") def register_with_mcp(self, mcp: FastMCP) -> None: """Register tools with FastMCP instance.""" @mcp.tool() async def process_text(text: str) -> str: """Process text input and return formatted result. Args: text: Input text to process Returns: Processed text in uppercase """ self._log_tool_call("process_text", text=text) return f"Processed: {text.upper()}" self.logger.info("Registered my_tool: process_text") # The tool is automatically discovered by the registry!
  1. The tool is automatically registered - no manual registration needed!

  2. Advanced tool with validation:

from typing import Dict, Any from fastmcp import FastMCP from .base import BaseTool class ValidatedTool(BaseTool): """Example tool with validation using FastMCP decorators""" def __init__(self): super().__init__(name="validated") def register_with_mcp(self, mcp: FastMCP) -> None: @mcp.tool() async def process_data(value: int, name: str) -> Dict[str, Any]: """Process data with validation. Args: value: Integer value to process name: Name to include in result Returns: Processed data dictionary """ if not (0 <= value <= 100): raise ValueError("Value must be between 0-100") if not name or not name.strip(): raise ValueError("Name cannot be empty") return {"value": value, "name": name.strip(), "processed": True} self.logger.info("Registered validated tool: process_data")

Adding New Resources

  1. Create a resource file in src/mcp_server/resources/:

# src/mcp_server/resources/my_resource.py import json from typing import Any from .base import BaseResource class MyResource(BaseResource): """Example resource that provides data.""" uri_template = "my://data/{category}" name = "My Data Resource" description = "Provides categorized data" mime_type = "application/json" async def read(self, category: str = "default") -> str: """Read resource data for the given category.""" data = { "category": category, "items": [f"item-{i}" for i in range(1, 6)], "timestamp": "2024-01-01T00:00:00Z" } return json.dumps(data, indent=2) # Automatically discovered by the registry!

Adding New Prompts

  1. Create a prompt file in src/mcp_server/prompts/:

# src/mcp_server/prompts/my_prompt.py from typing import Any, List from fastmcp import FastMCP from .base import BasePrompt class MyPrompt(BasePrompt): """Example prompt for content generation.""" def __init__(self): super().__init__(name="my_prompt") def register_with_mcp(self, mcp: FastMCP) -> None: """Register prompts with FastMCP instance.""" @mcp.prompt() async def generate_content(topic: str, format: str = "markdown") -> str: """Generate structured content about a topic. Args: topic: The topic to generate content about format: Output format (markdown, text, etc.) Returns: Generated content in the specified format """ self._log_prompt_call("generate_content", topic=topic, format=format) if format == "markdown": return f"""# {topic} ## Overview This is an overview of {topic}. ## Key Points - Point 1 about {topic} - Point 2 about {topic} - Point 3 about {topic} ## Conclusion Summary of {topic}. """ else: return f"Content about {topic} in {format} format" self.logger.info("Registered my_prompt: generate_content") # Automatically discovered by the registry!

๐Ÿงช Testing

Running Tests

# All tests source .venv/bin/activate && uv run pytest # Unit tests only source .venv/bin/activate && uv run pytest tests/unit/ -v # Integration tests only source .venv/bin/activate && uv run pytest tests/integration/ -v # Specific test file source .venv/bin/activate && uv run pytest tests/unit/test_tools.py -v # With coverage source .venv/bin/activate && uv run pytest --cov=src/mcp_server --cov-report=html # Parallel execution source .venv/bin/activate && uv run pytest -n auto

Test Structure

tests/ โ”œโ”€โ”€ conftest.py # Shared test fixtures โ”œโ”€โ”€ unit/ # Unit tests โ”‚ โ””โ”€โ”€ test_tools.py # Tool testing โ””โ”€โ”€ integration/ # Integration tests โ””โ”€โ”€ test_client_interactions.py # End-to-end tests

Writing Tests

Example unit test for tools:

import pytest from mcp_server.tools.arithmetic import ArithmeticTools @pytest.mark.asyncio async def test_arithmetic_tools(): tools = ArithmeticTools() # Test direct methods assert tools.add_numbers(5, 3) == 8 assert tools.subtract_numbers(10, 4) == 6 @pytest.mark.asyncio async def test_weather_tools(): from mcp_server.tools.weather import WeatherTools tools = WeatherTools() # Weather tool would require proper MCP setup for full testing # This is a simplified example assert tools._use_mock_data() == True # Default is mock data

Example integration test:

import pytest from mcp_server import create_server @pytest.mark.asyncio async def test_server_creation(): server = create_server() assert server is not None # Test component registration # This would require proper async setup in real tests assert server is not None # Verify tools are available (actual implementation would vary) # The server would have add, subtract, get_current_weather tools

โš™๏ธ Configuration

Environment Variables

Variable

Default

Description

MCP_TRANSPORT

streamable-http

Transport method (streamable-http, sse)

MCP_HOST

0.0.0.0

Server host for network transports

MCP_PORT

8080

Server port for network transports

MCP_LOG_LEVEL

INFO

Logging level (DEBUG, INFO, WARNING, ERROR)

MCP_LOG_FORMAT

[%(levelname)s]: %(message)s

Log format string

MCP_ENVIRONMENT

development

Environment (development, production, testing)

MCP_SERVER_NAME

MCP Server Template

Server identification name

MCP_VERSION

0.1.0

Server version

PORT

-

Cloud Run compatible port override

Configuration Examples

Development Configuration:

export MCP_ENVIRONMENT=development export MCP_LOG_LEVEL=DEBUG export MCP_TRANSPORT=streamable-http

Streamable HTTP Server Configuration:

export MCP_TRANSPORT=streamable-http export MCP_HOST=0.0.0.0 export MCP_PORT=8080 export MCP_ENVIRONMENT=production export MCP_LOG_LEVEL=INFO

Server-Sent Events Configuration:

export MCP_TRANSPORT=sse export MCP_HOST=0.0.0.0 export MCP_PORT=8081 export MCP_ENVIRONMENT=production

Advanced Configuration

The settings system supports complex configuration scenarios:

# src/mcp_server/config/settings.py from pydantic import BaseModel, Field from typing import Literal class Settings(BaseModel): # Server Configuration server_name: str = "MCP Server Template" host: str = "0.0.0.0" port: int = 8080 transport: Literal["streamable-http", "sse"] = "streamable-http" # Logging Configuration log_level: str = "INFO" log_format: str = "[%(levelname)s]: %(message)s" # Environment Configuration environment: Literal["development", "production", "testing"] = "development" version: str = "0.1.0" model_config = { "env_prefix": "MCP_", "case_sensitive": False, "env_file": ".env", "env_file_encoding": "utf-8" }

๐Ÿš€ Deployment

Docker Deployment

  1. Build the image:

docker build -t my-mcp-server .
  1. Run with different transports:

# Default mode docker run -it my-mcp-server # Streamable HTTP mode docker run -e MCP_TRANSPORT=streamable-http -e MCP_HOST=0.0.0.0 -e MCP_PORT=8080 -p 8080:8080 my-mcp-server # Server-Sent Events mode docker run -e MCP_TRANSPORT=sse -e MCP_HOST=0.0.0.0 -e MCP_PORT=8081 -p 8081:8081 my-mcp-server # With custom environment docker run -e MCP_LOG_LEVEL=DEBUG -e MCP_ENVIRONMENT=production -it my-mcp-server
  1. Docker Compose:

version: '3.8' services: mcp-server-default: build: . environment: - MCP_TRANSPORT=streamable-http - MCP_LOG_LEVEL=INFO stdin_open: true tty: true mcp-server-http: build: . environment: - MCP_TRANSPORT=streamable-http - MCP_HOST=0.0.0.0 - MCP_PORT=8080 - MCP_LOG_LEVEL=INFO ports: - "8080:8080" mcp-server-sse: build: . environment: - MCP_TRANSPORT=sse - MCP_HOST=0.0.0.0 - MCP_PORT=8081 - MCP_LOG_LEVEL=INFO ports: - "8081:8081"

Production Deployment

  1. System Service (systemd example):

# /etc/systemd/system/mcp-server.service [Unit] Description=MCP Server After=network.target [Service] Type=simple User=mcp WorkingDirectory=/opt/mcp-server Environment=MCP_TRANSPORT=streamable-http Environment=MCP_HOST=0.0.0.0 Environment=MCP_PORT=8080 Environment=MCP_LOG_LEVEL=INFO Environment=MCP_ENVIRONMENT=production ExecStart=/opt/mcp-server/.venv/bin/python -m mcp_server Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
  1. Process Manager (PM2 example):

{ "name": "mcp-server", "script": "python", "args": ["-m", "mcp_server"], "cwd": "/opt/mcp-server", "interpreter": "/opt/mcp-server/.venv/bin/python", "env": { "MCP_TRANSPORT": "streamable-http", "MCP_HOST": "0.0.0.0", "MCP_PORT": "8080", "MCP_LOG_LEVEL": "INFO", "MCP_ENVIRONMENT": "production" } }
  1. Kubernetes Deployment:

apiVersion: apps/v1 kind: Deployment metadata: name: mcp-server spec: replicas: 3 selector: matchLabels: app: mcp-server template: metadata: labels: app: mcp-server spec: containers: - name: mcp-server image: my-mcp-server:latest env: - name: MCP_TRANSPORT value: "streamable-http" - name: MCP_HOST value: "0.0.0.0" - name: MCP_PORT value: "8080" - name: MCP_ENVIRONMENT value: "production" ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: mcp-server-service spec: selector: app: mcp-server ports: - port: 80 targetPort: 8080 type: LoadBalancer

๐Ÿ‘ฅ Development

Development Setup

# Clone and setup git clone <repo-url> cd mcp-server-template uv venv source .venv/bin/activate uv install --group dev # Set development environment export MCP_ENVIRONMENT=development export MCP_LOG_LEVEL=DEBUG

Code Quality

# Format and lint code source .venv/bin/activate && uv run ruff check src tests --fix source .venv/bin/activate && uv run ruff format src tests # Type checking (mypy not included in current dependencies) # Add mypy to dev dependencies if type checking is needed # Run all quality checks source .venv/bin/activate && uv run pytest && uv run ruff check src tests

Contributing Guidelines

  1. Fork and clone the repository

  2. Create a feature branch: git checkout -b feature/my-feature

  3. Set development environment: export MCP_ENVIRONMENT=development

  4. Write tests for new functionality

  5. Ensure all tests pass: source .venv/bin/activate && uv run pytest

  6. Run linting: source .venv/bin/activate && uv run ruff check src tests --fix

  7. Test different transports: Test streamable-http and sse modes

  8. Commit changes: Follow conventional commits

  9. Submit a pull request

Development Workflows

Testing Different Transports:

# Test default streamable HTTP mode export MCP_TRANSPORT=streamable-http && source .venv/bin/activate && uv run python -m mcp_server # Test SSE mode export MCP_TRANSPORT=sse && export MCP_PORT=8081 && source .venv/bin/activate && uv run python -m mcp_server

Component Development:

# Verify tool registration source .venv/bin/activate && uv run python -c " from mcp_server.tools.registry import get_all_tools print([tool.__class__.__name__ for tool in get_all_tools()]) " # Test new components source .venv/bin/activate && uv run python diagnosis_test.py

๐Ÿ› Troubleshooting

Common Issues

  1. Server not starting:

    # Check Python version python --version # Should be 3.13+ # Check dependencies source .venv/bin/activate && uv pip list # Check with debug logging export MCP_LOG_LEVEL=DEBUG source .venv/bin/activate && uv run python -m mcp_server
  2. Transport-specific issues:

    # Streamable HTTP transport issues export MCP_TRANSPORT=streamable-http export MCP_HOST=localhost export MCP_PORT=8080 curl http://localhost:8080/health # Test endpoint # SSE transport issues export MCP_TRANSPORT=sse export MCP_PORT=8081 # Test with SSE client
  3. Components not registered:

    # Verify component discovery source .venv/bin/activate && uv run python -c "

from mcp_server import create_server server = create_server() print('Server created successfully with all components') "

4. **Docker issues**: ```bash # Check container logs docker logs <container-id> # Interactive debugging docker run -it --entrypoint /bin/bash my-mcp-server # Test different transports docker run -e MCP_TRANSPORT=streamable-http -e MCP_PORT=8080 -p 8080:8080 my-mcp-server

Debug Mode

Enable comprehensive debugging:

export MCP_LOG_LEVEL=DEBUG export MCP_ENVIRONMENT=development source .venv/bin/activate && uv run python -m mcp_server

Health Checks

Use the provided diagnostic tools:

# Basic functionality test source .venv/bin/activate && uv run python diagnosis_test.py # Full verification test source .venv/bin/activate && uv run python verification_test.py # Test specific transport export MCP_TRANSPORT=streamable-http && source .venv/bin/activate && uv run python verification_test.py

๐Ÿ”ง FastMCP Features

This template leverages FastMCP's powerful capabilities:

Multi-Transport Support

# Automatic transport detection and configuration await mcp.run_async( transport="streamable-http", # Streamable HTTP server mode transport="sse" # Server-Sent Events mode )

Automatic Type Validation

from fastmcp import tool @tool async def validated_function(count: int, name: str) -> dict: """FastMCP handles automatic type conversion and validation.""" return {"count": count, "name": name}

Built-in Error Handling

# FastMCP provides comprehensive error handling try: result = await tool.execute(params) except ValidationError as e: logger.error(f"Validation error: {e}") except Exception as e: logger.error(f"Execution error: {e}")

Lazy Loading for Performance

# The template uses lazy imports for optimal startup def create_server(): from .server import create_server as _create_server return _create_server()

๐Ÿ“„ Dependencies

Core Dependencies

  • fastmcp (>=2.11.3): FastMCP framework for rapid MCP server development

  • httpx (>=0.28.1): HTTP client for external API integration

  • pydantic (>=2.0.0): Data validation and settings management

Development Dependencies

  • pytest (>=8.4.1): Testing framework with async support

  • pytest-asyncio (>=0.23.0): Async testing support for pytest

  • ruff (>=0.12.10): Fast Python linter and formatter

  • ipykernel (>=6.30.1): Jupyter kernel for interactive development

๐Ÿ†• What's New in v0.1.0

  • Multi-Transport Support: Streamable HTTP and Server-Sent Events transport options

  • Environment-Based Configuration: Comprehensive settings management with MCP_ prefixes

  • Registry Pattern: Automatic component discovery and registration

  • Structured Logging: Configurable logging formats with proper levels

  • Development Template: Docker support with Python 3.13, structured for extension

  • FastMCP Integration: Built on the latest FastMCP framework

  • Lazy Loading: Optimized startup performance with lazy imports

  • Flexible Deployment: Multiple deployment options and configurations

๐Ÿ“„ License

[Your License Here]

๐Ÿค Support


Happy building with MCP and FastMCP! ๐Ÿš€

-
security - not tested
F
license - not found
-
quality - not tested

Related MCP Servers

  • -
    security
    F
    license
    -
    quality
    A feature-rich Model Context Protocol server built with FastMCP that provides various tools including basic utilities, network services, file operations, encryption tools, and system information functions.
    Last updated -
  • A
    security
    F
    license
    A
    quality
    A minimal MCP server template with hot reload support that helps developers quickly set up and build Model Context Protocol servers with example tool implementations.
    Last updated -
    3
  • -
    security
    -
    license
    -
    quality
    A template for building Model Context Protocol servers that connect to company REST APIs using FastMCP, providing authentication handling, error management, and example tools for common API operations.
    Last updated -
    MIT License
  • A
    security
    A
    license
    A
    quality
    A lightweight framework for building and running Model Context Protocol (MCP) servers using FastMCP, providing tools for development, debugging, and server management.
    Last updated -
    4
    MIT License

View all related MCP servers

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rwxproject/mcp-server-template'

If you have feedback or need assistance with the MCP directory API, please join our Discord server