A demonstration MCP (Model Context Protocol) server showcasing best practices for tool implementation, input validation, response formatting, pagination, and error handling.
This is a dummy MCP server built with Python and FastMCP that demonstrates:
- Best Practice Tool Design: Following MCP guidelines for naming, annotations, and structure
- Input Validation: Using Pydantic v2 models with comprehensive field constraints
- Multiple Response Formats: Supporting both JSON (machine-readable) and Markdown (human-readable) outputs
- Pagination: Implementing offset-based pagination with clear metadata
- Character Limits: Respecting character limits with graceful truncation
- Error Handling: Providing clear, actionable error messages
- Type Safety: Full type hints throughout the codebase
Get the current date and time.
Parameters:
timezone(optional): Timezone for display (default: "UTC")response_format(optional): Output format ("markdown" or "json")
Example:
{
"timezone": "UTC",
"response_format": "json"
}Annotations: Read-only, Idempotent
Perform basic mathematical operations (add, subtract, multiply, divide).
Parameters:
operation: Mathematical operation ("add", "subtract", "multiply", "divide")a: First numberb: Second numberresponse_format(optional): Output format ("markdown" or "json")
Example:
{
"operation": "add",
"a": 5.0,
"b": 3.0,
"response_format": "json"
}Annotations: Read-only, Idempotent
Search for dummy items with pagination and filtering.
Parameters:
query(optional): Search query to filter itemslimit(optional): Maximum results to return (1-100, default: 20)offset(optional): Number of results to skip for pagination (default: 0)response_format(optional): Output format ("markdown" or "json")
Example:
{
"query": "development",
"limit": 10,
"offset": 0,
"response_format": "json"
}Annotations: Read-only, Idempotent
Create a new dummy item.
Parameters:
name: Name of the item (1-100 characters, required)description(optional): Description of the item (max 500 characters)tags(optional): List of tags (max 10 tags)response_format(optional): Output format ("markdown" or "json")
Example:
{
"name": "Project Alpha",
"description": "New Q1 project",
"tags": ["development", "priority-1"],
"response_format": "json"
}Annotations: Non-destructive write operation
Format text using various transformation options.
Parameters:
text: Text to format (1-10000 characters, required)format_type: Formatting to apply ("uppercase", "lowercase", "title", "reverse")
Example:
{
"text": "hello world",
"format_type": "uppercase"
}Annotations: Read-only, Idempotent
-
Install Python 3.10 or higher
-
Install uv (fast Python package installer):
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or with pip
pip install uv# Install dependencies using uv
uv sync
# Or install manually
uv pip install -e .The server uses stdio transport by default, which is suitable for command-line tools and subprocess integration:
# Run with uv (recommended - manages dependencies automatically)
uv run server.py
# Or run directly if dependencies are installed
python3 server.pyYou can test the server using the MCP Inspector tool:
# With uv (recommended)
npx @modelcontextprotocol/inspector uv run server.py
# Or without uv
npx @modelcontextprotocol/inspector python3 server.pyAdd this configuration to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Using uv (recommended):
{
"mcpServers": {
"dummy": {
"command": "uv",
"args": [
"--directory",
"/path/to/dummy-mcp",
"run",
"server.py"
]
}
}
}Or without uv:
{
"mcpServers": {
"dummy": {
"command": "python3",
"args": ["/path/to/dummy-mcp/server.py"]
}
}
}dummy-mcp/
├── server.py # Main MCP server implementation
├── pyproject.toml # Project metadata and dependencies (uv)
├── requirements.txt # Python dependencies (legacy, optional)
└── README.md # This file
Pydantic Models: All tool inputs are validated using Pydantic v2 models with:
- Field constraints (min/max length, ranges)
- Custom validators
- Type safety
- Automatic error messages
Shared Utilities: Common functionality is extracted into reusable functions:
_generate_dummy_items(): Generate test data_filter_items(): Filter items by query_format_items_markdown(): Format as Markdown_format_items_json(): Format as JSON_check_character_limit(): Enforce character limits
Tool Annotations: All tools include proper annotations:
readOnlyHint: Indicates if tool modifies statedestructiveHint: Indicates if modifications are destructiveidempotentHint: Indicates if repeated calls have same effectopenWorldHint: Indicates if tool interacts with external systems
This server follows MCP best practices:
- Server Naming:
dummy_mcpfollows Python convention{service}_mcp - Tool Naming: Snake_case with service prefix (e.g.,
dummy_get_time) - Response Formats: Supports both JSON and Markdown
- Pagination: Implements offset-based pagination with metadata
- Character Limits: 25,000 character limit with graceful truncation
- Input Validation: Comprehensive Pydantic models
- Error Handling: Clear, actionable error messages
- Documentation: Comprehensive docstrings with examples
- Type Safety: Full type hints throughout
- Code Reusability: Shared utilities for common operations
Check Python syntax:
python3 -m py_compile server.py# Install dev dependencies
uv sync --all-extras
# Run tests (when available)
uv run pytestThe implementation includes:
- Type hints throughout
- Comprehensive docstrings
- Pydantic validation
- Error handling
- Shared utilities for DRY code
This is a demonstration project for educational purposes.