MCP Server Developer Guide

April 1, 2025 · View on GitHub

This guide explains how to extend the MCP server with custom tools and other functionalities.

Project Structure

The MCP server is organized in a modular fashion:

mcp_server/
├── config/           # Configuration settings
├── core/             # Core server components
├── tools/            # Individual tools
└── utils/            # Utility functions

Creating a New Tool

To create a new tool for the MCP server, follow these steps:

1. Define Tool Parameters and Results

Create classes for your tool's parameters and results by extending the base classes:

from pydantic import Field
from mcp_server.core.base_tool import ToolParameters, ToolResult

class MyToolParameters(ToolParameters):
    """Parameters for my custom tool."""
    
    input_data: str = Field(..., description="Input data for the tool")
    option: bool = Field(False, description="Optional flag")

class MyToolResult(ToolResult):
    """Results from my custom tool."""
    
    output_data: str = Field(..., description="Output from the tool")
    processing_time: float = Field(..., description="Time taken to process")

2. Implement the Tool Class

Create a new tool class by extending the MCPTool base class:

from typing import ClassVar, Type
from mcp_server.core.base_tool import MCPTool

class MyTool(MCPTool):
    """My custom tool implementation."""
    
    # Tool metadata
    name: ClassVar[str] = "my_tool"
    description: ClassVar[str] = "Description of my custom tool"
    version: ClassVar[str] = "0.1.0"
    parameters_model: ClassVar[Type[ToolParameters]] = MyToolParameters
    result_model: ClassVar[Type[ToolResult]] = MyToolResult
    
    async def execute(self, parameters: MyToolParameters) -> MyToolResult:
        """Execute the tool.
        
        Args:
            parameters: The tool parameters
            
        Returns:
            The tool results
        """
        # Implement your tool's functionality here
        import time
        start_time = time.time()
        
        # Process the input
        output = f"Processed: {parameters.input_data}"
        
        # Calculate processing time
        processing_time = time.time() - start_time
        
        # Return the results
        return MyToolResult(
            output_data=output,
            processing_time=processing_time,
        )

3. Register the Tool

Add your tool to the tool registry in mcp_server/cli.py:

from mcp_server.tools.my_tool import MyTool

def register_tools(tool_registry: ToolRegistry, settings: Settings):
    # Existing tool registrations...
    
    # Register your custom tool
    tool_registry.register_tool(MyTool)

Adding a New Feature

To add a new feature to the MCP server:

  1. Identify which module should contain your feature
  2. Implement the feature following SOLID principles
  3. Add tests for your feature
  4. Update documentation

Testing

We use pytest for testing. Tests are organized in the following directories:

  • tests/unit/: Unit tests for individual components
  • tests/integration/: Integration tests that test multiple components together

To run tests:

# Run all tests
pytest

# Run with coverage
pytest --cov=mcp_server

# Run specific tests
pytest tests/unit/test_my_feature.py

Style Guidelines

This project follows these coding standards:

  • PEP 8 style guide
  • Type hints for all functions and methods
  • Docstrings for all public APIs
  • SOLID principles for code organization

We use several tools to enforce these standards:

  • black for code formatting
  • isort for import sorting
  • mypy for type checking
  • ruff for linting

To check your code:

# Format code
black .

# Sort imports
isort .

# Check types
mypy .

# Lint code
ruff .

Continuous Integration

When submitting a pull request, the CI pipeline will automatically:

  1. Run all tests
  2. Check code formatting
  3. Perform type checking
  4. Run linters

Make sure your code passes all these checks before submitting a PR.