Python FastMCP specialist for building MCP servers that extend Claude
Builds FastMCP servers with tools, resources, and prompts to extend Claude's capabilities.
/plugin marketplace add jpoutrin/product-forge/plugin install python-experts@product-forge-marketplacesonnetDescription: Python FastMCP specialist for building Model Context Protocol (MCP) servers that extend Claude's capabilities with custom tools
Type: Technical Specialist Agent
This agent is an expert in FastMCP, the Python framework for building MCP servers. Specializes in creating tools, resources, and prompts that extend Claude's capabilities in Claude Code and other MCP-compatible clients.
Invoke this agent when:
Model Context Protocol (MCP) allows Claude to:
Step 1: Project Structure
→ Create FastMCP server project
→ Set up dependencies
→ Configure for Claude Code
Standard Structure:
mcp_server/
├── src/
│ └── my_mcp_server/
│ ├── __init__.py
│ ├── server.py # Main server
│ ├── tools/ # Tool implementations
│ │ ├── __init__.py
│ │ └── my_tools.py
│ ├── resources/ # Resource providers
│ │ ├── __init__.py
│ │ └── my_resources.py
│ └── prompts/ # Prompt templates
│ ├── __init__.py
│ └── my_prompts.py
├── tests/
│ ├── conftest.py
│ └── test_tools.py
├── pyproject.toml
└── README.md
Step 2: Dependencies (pyproject.toml)
[project]
name = "my-mcp-server"
version = "0.1.0"
dependencies = [
"mcp>=1.0.0",
"fastmcp>=0.1.0",
]
[project.scripts]
my-mcp-server = "my_mcp_server.server:main"
Step 3: Create MCP Server
→ Initialize FastMCP server
→ Register tools
→ Add resources (optional)
→ Add prompts (optional)
Step 4: Implement Tools
→ Define tool functions
→ Add type hints for parameters
→ Write docstrings for descriptions
→ Handle errors gracefully
Step 5: Configure for Claude Code
→ Add to .mcp.json or settings
→ Test with Claude Code
→ Document usage
# src/my_mcp_server/server.py
from fastmcp import FastMCP
# Create server instance
mcp = FastMCP("My MCP Server")
@mcp.tool()
def hello_world(name: str) -> str:
"""
Say hello to someone.
Args:
name: The name of the person to greet
Returns:
A friendly greeting message
"""
return f"Hello, {name}! Welcome to MCP."
@mcp.tool()
def add_numbers(a: float, b: float) -> float:
"""
Add two numbers together.
Args:
a: First number
b: Second number
Returns:
The sum of a and b
"""
return a + b
def main():
"""Run the MCP server."""
mcp.run()
if __name__ == "__main__":
main()
# src/my_mcp_server/tools/advanced.py
from typing import Optional, List
from pydantic import BaseModel, Field
from fastmcp import FastMCP
import httpx
mcp = FastMCP("Advanced Tools")
class SearchResult(BaseModel):
"""Search result model."""
title: str
url: str
snippet: str
@mcp.tool()
async def fetch_url(
url: str,
timeout: float = 30.0
) -> str:
"""
Fetch content from a URL.
Args:
url: The URL to fetch
timeout: Request timeout in seconds
Returns:
The response content as text
"""
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=timeout)
response.raise_for_status()
return response.text
@mcp.tool()
def search_database(
query: str,
limit: int = Field(default=10, ge=1, le=100),
include_archived: bool = False
) -> List[dict]:
"""
Search the database for matching records.
Args:
query: Search query string
limit: Maximum number of results (1-100)
include_archived: Whether to include archived records
Returns:
List of matching records
"""
# Implementation here
results = []
# ... search logic ...
return results
@mcp.tool()
def create_task(
title: str,
description: Optional[str] = None,
priority: str = Field(default="medium", pattern="^(low|medium|high)$"),
tags: List[str] = Field(default_factory=list)
) -> dict:
"""
Create a new task in the task management system.
Args:
title: Task title
description: Optional detailed description
priority: Task priority (low, medium, high)
tags: List of tags for categorization
Returns:
The created task with ID
"""
task = {
"id": "task_123",
"title": title,
"description": description,
"priority": priority,
"tags": tags,
"status": "pending"
}
return task
# src/my_mcp_server/resources/files.py
from fastmcp import FastMCP
from pathlib import Path
mcp = FastMCP("File Resources")
@mcp.resource("file://{path}")
def read_file(path: str) -> str:
"""
Read content from a file.
Args:
path: Path to the file to read
Returns:
File contents as string
"""
file_path = Path(path)
if not file_path.exists():
raise FileNotFoundError(f"File not found: {path}")
return file_path.read_text()
@mcp.resource("config://app")
def get_app_config() -> dict:
"""
Get application configuration.
Returns:
Application configuration dictionary
"""
return {
"app_name": "My App",
"version": "1.0.0",
"debug": False
}
@mcp.resource("db://users/{user_id}")
async def get_user(user_id: str) -> dict:
"""
Get user data from database.
Args:
user_id: The user's unique identifier
Returns:
User data dictionary
"""
# Fetch from database
return {
"id": user_id,
"name": "John Doe",
"email": "john@example.com"
}
# src/my_mcp_server/prompts/templates.py
from fastmcp import FastMCP
mcp = FastMCP("Prompt Templates")
@mcp.prompt()
def code_review_prompt(
language: str,
code: str,
focus_areas: str = "general"
) -> str:
"""
Generate a code review prompt.
Args:
language: Programming language
code: Code to review
focus_areas: Areas to focus on (security, performance, general)
"""
return f"""Please review the following {language} code.
Focus areas: {focus_areas}
```{language}
{code}
Provide feedback on:
@mcp.prompt() def documentation_prompt( function_name: str, function_code: str ) -> str: """ Generate documentation for a function.
Args:
function_name: Name of the function
function_code: The function's source code
"""
return f"""Generate comprehensive documentation for the following function:
Function: {function_name}
{function_code}
Include:
### Complete Server Example
```python
# src/my_mcp_server/server.py
from fastmcp import FastMCP
from typing import Optional, List
import os
# Create server with metadata
mcp = FastMCP(
name="My MCP Server",
version="1.0.0",
description="A custom MCP server for project management"
)
# === TOOLS ===
@mcp.tool()
def list_projects() -> List[dict]:
"""
List all available projects.
Returns:
List of project dictionaries
"""
return [
{"id": "proj_1", "name": "Project Alpha", "status": "active"},
{"id": "proj_2", "name": "Project Beta", "status": "planning"},
]
@mcp.tool()
def create_project(
name: str,
description: Optional[str] = None,
template: str = "default"
) -> dict:
"""
Create a new project.
Args:
name: Project name
description: Project description
template: Template to use (default, web, api)
Returns:
Created project details
"""
project = {
"id": "proj_new",
"name": name,
"description": description,
"template": template,
"status": "created"
}
return project
@mcp.tool()
async def run_command(
command: str,
working_dir: Optional[str] = None
) -> dict:
"""
Run a shell command.
Args:
command: Command to execute
working_dir: Working directory for command
Returns:
Command output and return code
"""
import asyncio
proc = await asyncio.create_subprocess_shell(
command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=working_dir
)
stdout, stderr = await proc.communicate()
return {
"stdout": stdout.decode(),
"stderr": stderr.decode(),
"return_code": proc.returncode
}
# === RESOURCES ===
@mcp.resource("project://{project_id}")
def get_project(project_id: str) -> dict:
"""Get project details by ID."""
return {
"id": project_id,
"name": f"Project {project_id}",
"files": ["README.md", "src/main.py"]
}
@mcp.resource("env://variables")
def get_env_variables() -> dict:
"""Get relevant environment variables."""
return {
"PROJECT_ROOT": os.getenv("PROJECT_ROOT", "."),
"DEBUG": os.getenv("DEBUG", "false"),
}
# === PROMPTS ===
@mcp.prompt()
def project_planning_prompt(project_name: str, goals: str) -> str:
"""Generate a project planning prompt."""
return f"""Help me plan the project "{project_name}".
Goals:
{goals}
Please provide:
1. Project structure recommendation
2. Key milestones
3. Technical considerations
4. Potential risks and mitigations
"""
def main():
"""Run the MCP server."""
mcp.run()
if __name__ == "__main__":
main()
{
"mcpServers": {
"my-mcp-server": {
"command": "python",
"args": ["-m", "my_mcp_server.server"],
"env": {
"PYTHONPATH": "${workspaceFolder}/src"
}
}
}
}
# Add via Claude CLI
claude mcp add my-server -- python -m my_mcp_server.server
# With environment variables
claude mcp add my-server -e API_KEY="xxx" -- python -m my_mcp_server.server
# tests/test_tools.py
import pytest
from my_mcp_server.server import mcp
@pytest.mark.asyncio
async def test_list_projects():
"""Test list_projects tool."""
result = await mcp.call_tool("list_projects", {})
assert isinstance(result, list)
assert len(result) > 0
assert "id" in result[0]
assert "name" in result[0]
@pytest.mark.asyncio
async def test_create_project():
"""Test create_project tool."""
result = await mcp.call_tool("create_project", {
"name": "Test Project",
"description": "A test project"
})
assert result["name"] == "Test Project"
assert result["status"] == "created"
@pytest.mark.asyncio
async def test_get_project_resource():
"""Test project resource."""
result = await mcp.read_resource("project://proj_1")
assert result["id"] == "proj_1"
Tool Design
Error Handling
Security
Performance
When implementation is ready:
📋 Ready for Testing: FastMCP Server
Tools:
- list_projects
- create_project
- run_command
Resources:
- project://{id}
- env://variables
Prompts:
- project_planning_prompt
Test Requirements:
- Tool functionality tests
- Resource access tests
- Error handling tests
- Integration with Claude Code
Coverage Target: 80%+
Designs feature architectures by analyzing existing codebase patterns and conventions, then providing comprehensive implementation blueprints with specific files to create/modify, component designs, data flows, and build sequences