Enhanced Tool Registry¶
One of the core advantages of Awesome MCP FastAPI is its enhanced tool registry system, which automatically discovers, documents, and exposes your FastAPI endpoints as MCP tools.
How It Works¶
The tool registry works through several key components:
- Decorator System: The
@auto_tool
decorator marks FastAPI endpoints as MCP tools - Route Scanner: Automatically discovers all decorated endpoints in your application
- Schema Generator: Creates rich JSON schemas from Python type annotations and docstrings
- Registry API: Exposes tools through both FastAPI endpoints and MCP protocol interfaces
Key Benefits¶
1. Automatic Documentation Generation¶
The tool registry automatically generates documentation in two formats:
- MCP Tool Schemas: Compatible with all MCP clients (like Claude)
- OpenAPI/Swagger: For human developers to explore and test
This dual documentation approach ensures both AI models and humans can discover and understand your tools.
2. Enhanced Type Information¶
Unlike standard MCP, our tool registry extracts rich type information from:
- Function signatures: Parameter types and return types
- Pydantic models: All field types, constraints, and validations
- Field extra information: Examples, descriptions, and constraints
This results in more accurate schema generation and better client experiences.
3. Docstring Processing¶
The registry intelligently processes Python docstrings to:
- Extract parameter descriptions
- Generate example values
- Document return values
- Provide usage notes
4. Production-Ready Features¶
- Caching: Tool schemas are cached for performance
- Hot Reloading: New tools are discovered when added
- Error Handling: Robust error handling for schema generation
- Logging: Detailed logging for debugging
Using the Tool Registry¶
Binding to Your App¶
First, bind the tool registry to your FastAPI app:
from fastapi import FastAPI
from awesome_mcp_fastapi import bind_app_tools
app = FastAPI()
bind_app_tools(app) # This registers the tool registry
This creates the following endpoints:
/tools/all
: Lists all registered tools with their schemas/tools/scan
: Manually triggers a scan for new tools
Marking Endpoints as Tools¶
Use the @auto_tool
decorator to mark FastAPI endpoints as MCP tools:
from awesome_mcp_fastapi import auto_tool
@auto_tool(
name="tool-name", # Unique tool identifier
description="Tool description", # Optional, falls back to docstring
tags=["category1", "category2"], # Optional, for organization
example_input={"param": "value"}, # Optional example input
example_output={"result": "value"} # Optional example output
)
@app.post("/api/endpoint") # Regular FastAPI route decorator
async def my_endpoint(param1: str, param2: int):
"""
Endpoint docstring - will be used for documentation.
Will be parsed to extract parameter descriptions and examples.
"""
# Implementation
return {"result": "value"}
Tool Discovery Process¶
The tool registry:
- Scans all routes in your FastAPI application
- Identifies routes decorated with
@auto_tool
- Analyzes function signatures and docstrings
- Generates input and output schemas
- Registers tools in the MCP protocol
- Exposes tool listing through the API
Advanced Schema Generation¶
The schema generator has several advanced capabilities:
from pydantic import BaseModel, Field
from enum import Enum
from typing import List, Optional
class Status(str, Enum):
"""Processing status enum"""
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
FAILED = "failed"
class JobResult(BaseModel):
"""Result of a background job"""
id: str = Field(..., description="Unique job identifier")
status: Status = Field(..., description="Current job status")
progress: float = Field(0.0, description="Progress percentage", ge=0.0, le=100.0)
results: Optional[List[str]] = Field(None, description="Job results if completed")
class Config:
schema_extra = {
"example": {
"id": "job_12345",
"status": "completed",
"progress": 100.0,
"results": ["result1", "result2"]
}
}
@auto_tool(
name="get-job-status",
description="Check the status of a background job",
tags=["jobs"]
)
@app.get("/api/jobs/{job_id}", response_model=JobResult)
async def get_job_status(job_id: str):
"""
Get the current status of a background job.
Parameters:
- job_id: The unique identifier of the job
Returns:
The current job status and results if completed.
"""
# Implementation
return JobResult(
id=job_id,
status=Status.COMPLETED,
progress=100.0,
results=["example result"]
)
From this code, the registry will automatically generate:
- A rich input schema with the job_id parameter
- A complete output schema with all JobResult fields
- Proper Enum value handling
- Examples from the Pydantic Config
- Descriptions from Field definitions and docstrings
Customizing the Registry¶
You can customize the tool registry behavior with options:
bind_app_tools(
app,
prefix="/custom-path", # Custom endpoint prefix (default: /tools)
scan_on_startup=True, # Auto-scan on startup
enable_api=True, # Enable API endpoints
cache_ttl=60 # Schema cache TTL in seconds
)
Internals: Schema Processing¶
The tool registry employs sophisticated techniques to generate schemas:
Input Schema Generation¶
- Analyzes function parameters
- Identifies query, path, and body parameters
- Extracts types, defaults, and constraints
- Processes Pydantic models recursively
- Adds examples and descriptions
Output Schema Generation¶
- Identifies response_model from route decorators
- Falls back to return type annotations
- Processes Pydantic response models
- Extracts example responses
- Adds rich field descriptions
Performance Considerations¶
The tool registry is designed for production performance:
- Lazy Loading: Tools are scanned only when needed
- Caching: Schema generation results are cached
- Minimal Overhead: Negligible impact on request handling
- Optimized Processing: Efficient schema generation
Next Steps¶
- Learn about advanced tool patterns
- Understand schema generation details
- Explore integration with MCP clients