A production-ready Model Context Protocol (MCP) server template built with FastMCP on Starlette. This server runs on port 8000 (configurable), supports custom Starlette middlewares, and includes example tools to demonstrate MCP functionality.
- Framework: FastMCP with Starlette
- Transport: HTTP and STDIO support
- Server: Uvicorn ASGI server
- Port: 8000 (configurable via PORT environment variable)
- Middleware: CORS enabled by default, extensible middleware stack
.
├── Dockerfile
├── docker-compose.yml
├── License
├── main.py
├── README.md
├── requirements.txt
├── src/
│ ├── __init__.py
│ ├── tools.py
│ └── utils/
└── tests/
└── test.py
- MCP server implementation using FastMCP and Starlette
- HTTP and STDIO transport protocols
- Custom HTTP endpoints for health checks, server info, and tool listing
- Interactive web-based documentation
- Extensible middleware support
- Example MCP tools demonstrating core functionality
- Python 3.11 or higher
- pip package manager
- Docker (optional, for containerized deployment)
Install dependencies:
pip install -r requirements.txtStart the server with HTTP transport:
python main.pyThe server will be available at http://localhost:8000 (or the port specified in your PORT environment variable).
Use the provided script to run automated tests before deployment:
./scripts/test-and-run.shThis workflow will:
- Build and execute tests in isolated containers
- Halt deployment if any tests fail
- Build and start the production service only if all tests pass
# Execute test suite
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit --exit-code-from test
# Deploy production service after successful tests
docker compose up --build -d# Deploy without running tests
docker compose up --build -d
# Alternative: Direct Docker commands
docker build -t macrosense-mcp .
docker run --rm -p 8000:8000 macrosense-mcp# Stop and remove containers
docker compose down
docker compose -f docker-compose.test.yml downEdit the cors_middleware configuration in main.py to customize CORS settings or add additional Starlette middlewares to the middleware stack.
PORT: Server port (default: 8000)MONGODB_URI: MongoDB connection stringHOST: Bind address (default: 0.0.0.0)
GET /- Redirects to/docsGET /health- Health check endpoint for monitoringGET /info- Server metadata and tool informationGET /tools- List all available MCP tools with descriptionsGET /docs- Interactive API documentationPOST /mcp- Primary MCP protocol endpoint
Tools are defined in src/tools.py. Use the @mcp.tool() decorator to register new tools.
Performs addition of two numeric values.
Parameters:
number1(float): First operandnumber2(float): Second operand
Returns:
{
"result": <sum>
}Example Usage:
@mcp.tool()
def add_numbers(number1: float, number2: float) -> dict:
"""Calculate the sum of two numbers"""
return {"result": sum([number1, number2])}The project uses pytest with asyncio support for asynchronous test execution. All tests are located in the tests/ directory.
Execute the complete test suite:
pytestRun with verbose output:
pytest -vUsing virtual environment directly:
.venv/bin/python -m pytest tests/test.py -vThe pyproject.toml file contains pytest configuration:
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = "-v --tb=short"Tests utilize FastMCP's in-memory client for fast, deterministic testing:
import pytest
from fastmcp.client import Client
from main import mcp
@pytest.fixture
async def mcp_client():
"""Fixture that provides a FastMCP client for testing."""
async with Client(mcp) as client:
yield client
async def test_add_numbers(mcp_client: Client):
"""Test add_numbers tool."""
result = await mcp_client.call_tool(
name="add_numbers",
arguments={"number1": 1, "number2": 2}
)
assert result.data["result"] == 3The test suite includes:
- test_server_info: Validates server initialization and metadata
- test_list_tools: Verifies tool registration
- test_add_numbers: Parametrized tests covering multiple input scenarios (7 test cases)
- test_add_numbers_with_negative_numbers: Negative value handling
- test_add_numbers_with_floats: Floating-point precision validation
All tests adhere to FastMCP testing standards:
- Single behavior per test
- Self-contained setup
- Clear intent with descriptive names
- Effective assertions with error messages
For integration testing with external MCP clients, use MCP Inspector or similar tools that support HTTP transport to connect to http://localhost:8000.