Skip to main content
Glama
fastmcp_dev_guide.md7.11 kB
# FastMCP Server Development Guide - Best Practices ## Overview This document provides steering context and best practices for developing Model Context Protocol (MCP) servers using FastMCP framework. ## Core Principles ### 1. Server Initialization - Use `FastMCP` class as the main entry point - Define server name and optional dependencies during initialization - Keep server configuration minimal and focused ```python from fastmcp import FastMCP mcp = FastMCP("server-name") ``` ### 2. Tool Definition - Use `@mcp.tool()` decorator for exposing functions as tools - Provide clear, descriptive docstrings (used as tool descriptions) - Use type hints for all parameters - Keep tools focused on single responsibilities ```python @mcp.tool() def tool_name(param: str, optional_param: int = 0) -> dict: """Clear description of what this tool does.""" return {"result": "value"} ``` ### 3. Resource Management - Use `@mcp.resource()` for exposing data resources - Define URI patterns clearly - Implement proper resource lifecycle management - Return structured data formats ### 4. Prompts - Use `@mcp.prompt()` for reusable prompt templates - Include parameter validation - Provide clear prompt descriptions - Support dynamic prompt generation ### 5. Error Handling - Implement comprehensive error handling in all tools - Return meaningful error messages - Use appropriate exception types - Log errors for debugging ```python @mcp.tool() def safe_tool(param: str) -> dict: """Tool with proper error handling.""" try: # Tool logic return {"status": "success"} except ValueError as e: return {"error": str(e)} ``` ### 6. Type Safety - Always use type hints for parameters and return values - Leverage Pydantic models for complex data structures - Validate input data before processing - Document expected types in docstrings ### 7. Async Operations - Use async/await for I/O-bound operations - Implement proper async context managers - Handle concurrent requests appropriately - Avoid blocking operations in async tools ```python @mcp.tool() async def async_tool(url: str) -> dict: """Async tool for I/O operations.""" async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.json() ``` ### 8. Configuration Management - Use environment variables for sensitive data - Implement configuration validation at startup - Provide sensible defaults - Document all configuration options ### 9. Testing - Write unit tests for all tools - Test error conditions - Mock external dependencies - Validate tool schemas ### 10. Documentation - Document all tools with clear docstrings - Include parameter descriptions - Provide usage examples - Maintain README with setup instructions ## Server Structure Best Practices ### Minimal Server Structure ``` project/ ├── server.py # Main server implementation ├── requirements.txt # Dependencies └── README.md # Documentation ``` ### Modular Server Structure ``` project/ ├── server.py # Server entry point ├── tools/ # Tool implementations │ ├── __init__.py │ └── tool_module.py ├── resources/ # Resource handlers ├── config.py # Configuration ├── requirements.txt └── README.md ``` ## Tool Design Patterns ### Single Responsibility Each tool should do one thing well: ```python @mcp.tool() def get_user(user_id: str) -> dict: """Retrieve user by ID.""" return fetch_user(user_id) @mcp.tool() def update_user(user_id: str, data: dict) -> dict: """Update user information.""" return update_user_data(user_id, data) ``` ### Parameter Validation ```python @mcp.tool() def process_data(value: int, mode: str = "default") -> dict: """Process data with validation.""" if value < 0: raise ValueError("Value must be non-negative") if mode not in ["default", "advanced"]: raise ValueError("Invalid mode") return {"processed": True} ``` ### Structured Returns ```python @mcp.tool() def fetch_data(query: str) -> dict: """Return structured data.""" return { "data": [...], "metadata": { "count": 10, "timestamp": "2025-10-09T11:40:00Z" } } ``` ## Security Best Practices 1. **Input Validation**: Validate all inputs before processing 2. **Secrets Management**: Never hardcode credentials 3. **Rate Limiting**: Implement rate limits for resource-intensive operations 4. **Access Control**: Validate permissions where applicable 5. **Sanitization**: Sanitize user inputs to prevent injection attacks ## Performance Optimization 1. **Caching**: Cache frequently accessed data 2. **Lazy Loading**: Load resources only when needed 3. **Connection Pooling**: Reuse connections for external services 4. **Batch Operations**: Support batch processing where applicable 5. **Timeouts**: Set appropriate timeouts for external calls ## Deployment Considerations 1. **Dependencies**: Pin dependency versions in requirements.txt 2. **Environment**: Support multiple environments (dev, staging, prod) 3. **Logging**: Implement structured logging 4. **Monitoring**: Add health check endpoints 5. **Graceful Shutdown**: Handle shutdown signals properly ## Common Patterns ### Context Manager Pattern ```python class ResourceManager: async def __aenter__(self): # Setup return self async def __aexit__(self, exc_type, exc_val, exc_tb): # Cleanup pass ``` ### Factory Pattern ```python def create_tool_handler(config: dict): """Factory for creating tool handlers.""" return ToolHandler(config) ``` ### Dependency Injection ```python mcp = FastMCP("server", dependencies=["external-service"]) ``` ## Debugging Tips 1. Enable verbose logging during development 2. Use descriptive error messages 3. Implement request/response logging 4. Add debug tools for inspection 5. Use type checkers (mypy) during development ## Version Control 1. Use semantic versioning 2. Maintain CHANGELOG.md 3. Tag releases appropriately 4. Document breaking changes ## Example: Complete Minimal Server ```python from fastmcp import FastMCP mcp = FastMCP("example-server") @mcp.tool() def greet(name: str) -> dict: """Greet a user by name.""" return {"message": f"Hello, {name}!"} @mcp.tool() async def fetch_data(url: str) -> dict: """Fetch data from URL.""" # Implementation return {"data": "..."} if __name__ == "__main__": mcp.run() ``` ## Resources - FastMCP Documentation: https://gofastmcp.com - MCP Specification: https://modelcontextprotocol.io - Python Type Hints: https://docs.python.org/3/library/typing.html ## Checklist for New Servers - [ ] Clear server name and purpose - [ ] All tools have type hints - [ ] Comprehensive docstrings - [ ] Error handling implemented - [ ] Input validation in place - [ ] Tests written - [ ] README documentation - [ ] Environment variables documented - [ ] Dependencies pinned - [ ] Security review completed

Latest Blog Posts

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/n-ochs/best-practice-mcp'

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