Transform any FastAPI server into an MCP server
Project description
mcp-it
Transform any FastAPI server into an MCP (Model Context Protocol) server.
mcp-it allows you to seamlessly convert your FastAPI routes into MCP tools. Decorate your FastAPI endpoints with @mcp_it.mcp() and your API becomes an MCP server that can be used with MCP-compatible clients.
Features
- Minimal Code Changes: Convert existing FastAPI routes to MCP tools with a simple decorator
- Automatic Parameter Detection: Automatically detects path, query, and body parameters from your FastAPI routes - no boilerplate reimplementation
- Header Forwarding: Maps and preserves headers from MCP requests to your FastAPI endpoints
- Dependency Injection: Full support for FastAPI's dependency injection system
- Pydantic Models: Full integration with Pydantic models for request/response validation
- Multiple Transports: Support for both sse and streamable-http transports
- Type Safety: Maintains type hints and annotations for proper MCP tool introspection
- Auto Docs: Automatically documents the MCP tools with your functions docstrings
Installation
pip install mcp-it
Quick Start
from fastapi import FastAPI, APIRouter
from mcpit import MCPIt
# Create your FastAPI app
app = FastAPI()
# Initialize MCPIt
mcp_it = MCPIt("My API Tools", json_response=True)
# Decorate your routes with @mcp_it.mcp()
@app.post("/multiply")
@mcp_it.mcp(mode='tool', description="Multiply two numbers")
def multiply(a: float, b: float):
"""Multiplies two numbers together."""
return {"result": a * b}
# Build and mount the MCP server
mcp_it.build(app.router, transport='streamable-http', mount_path="/mcp")
# Your MCP server is now available at /mcp
Usage
Basic Example
from fastapi import FastAPI, APIRouter
from mcpit import MCPIt
from pydantic import BaseModel, Field
app = FastAPI()
router = APIRouter()
mcp_it = MCPIt("Calculator Tools", json_response=True)
class CalculationInput(BaseModel):
a: float = Field(..., description="The first number")
b: float = Field(..., description="The second number")
@router.post("/add")
@mcp_it.mcp(mode='tool', name="add", description="Add two numbers")
def add(input: CalculationInput):
"""Adds two numbers together."""
return {"result": input.a + input.b}
mcp_it.build(router, transport='streamable-http', mount_path="/mcp")
app.include_router(router)
With Authentication
mcp-it automatically forwards headers from MCP requests, so your authentication dependencies work seamlessly:
from fastapi import Header, Depends
from typing import Optional
def fake_auth_dependency(authorization: Optional[str] = Header(None)):
"""Validate authorization header"""
if authorization:
return True
return False
@router.get("/protected")
@mcp_it.mcp(mode='tool', description="Protected endpoint")
def protected_route(auth_result: bool = Depends(fake_auth_dependency)):
"""A protected route that requires authentication."""
return {"message": "Access granted", "authenticated": auth_result}
With Dependency Injection
Full support for FastAPI's dependency injection:
class BasicService:
def __init__(self):
self.counter = 0
def increment(self) -> int:
self.counter += 1
return self.counter
service = BasicService()
def get_service() -> BasicService:
return service
from typing import Annotated
from fastapi import Depends
ServiceDep = Annotated[BasicService, Depends(get_service)]
@router.get("/increment")
@mcp_it.mcp(mode='tool', description="Increment counter")
def increment(service: ServiceDep):
"""Increment the counter using dependency injection."""
return {"count": service.increment()}
Path and Query Parameters
mcp-it automatically detects and handles path and query parameters:
@router.get("/users/{user_id}/posts")
@mcp_it.mcp(mode='tool', description="Get user posts")
def get_user_posts(user_id: int, limit: int = 10, offset: int = 0):
"""Get posts for a specific user with pagination."""
return {
"user_id": user_id,
"posts": [],
"limit": limit,
"offset": offset
}
API Reference
MCPIt
The main class for creating MCP servers from FastAPI routes.
Constructor
MCPIt(name: str, json_response: bool = True)
- name: Name of your MCP server
- json_response: Whether to return JSON responses (default: True)
Methods
mcp(mode='tool', **kwargs)
Decorator to register a FastAPI route as an MCP capability.
Parameters:
- mode: Type of MCP capability (
'tool','resource', or'prompt') - name: (optional) Custom name for the tool (defaults to function name)
- description: (optional) Tool description (defaults to function docstring)
Example:
@mcp_it.mcp(mode='tool', name="custom_name", description="Custom description")
def my_function():
pass
build(router, transport='streamable-http', mount_path='/mcp')
Builds the MCP server and mounts it to your FastAPI router.
Parameters:
- router: Your FastAPI
APIRouterinstance - transport: Transport type (
'sse'or'streamable-http') - mount_path: Path where the MCP server will be mounted (default:
/mcp)
Example:
mcp_it.build(router, transport='streamable-http', mount_path="/mcp")
How It Works
- Decorator Registration: When you use
@mcp_it.mcp(), the function is registered in an internal registry - Route Analysis: During
build(),mcp-itanalyzes your FastAPI routes to detect:- Path parameters
- Query parameters
- Body parameters
- Pydantic models
- Tool Creation: MCP tools are created with proper signatures and type annotations
- Internal Proxy: When an MCP tool is called,
mcp-itmakes an internal ASGI call to your FastAPI route - Header Forwarding: Headers from MCP requests are automatically forwarded to your endpoints
Transport Modes
Streamable HTTP (Recommended)
mcp_it.build(router, transport='streamable-http', mount_path="/mcp")
- Uses HTTP with streaming support
- Better for production environments
- Supports all HTTP methods
SSE (Server-Sent Events)
mcp_it.build(router, transport='sse', mount_path="/mcp")
- Uses Server-Sent Events for streaming
- Good for real-time updates
- Simpler connection model
Development
Setup
# Clone the repository
git clone https://github.com/enzobjmendonca/mcp-it.git
cd mcp-it
# Install development dependencies
pip install -r requirements.txt
# Install the package in editable mode
pip install -e .
Running Tests
pytest
Examples
See the example.py file in the repository for a complete working example with:
- Multiple route types
- Pydantic models
- Authentication
- Dependency injection
- Path and query parameters
Requirements
- Python 3.8+
- FastAPI
- FastMCP
- httpx
- Pydantic
Contributing
Contributions are more than welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_it-0.1.1.tar.gz.
File metadata
- Download URL: mcp_it-0.1.1.tar.gz
- Upload date:
- Size: 9.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f772bca8bf777375dd2fdea3f0c6d89d66550b3274221b6a780845b4ed18bc59
|
|
| MD5 |
48c8e3ac372dcb6b1623f278eb33a9ca
|
|
| BLAKE2b-256 |
04d084e228a6d2275a71e01fa4e8639615ef5bc257c216155e57ceec8943612c
|
File details
Details for the file mcp_it-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mcp_it-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7c10e3cb8bb3f0965046c1da18ed5f587a69ff5e3eae8fc0ed0bfa67e32b4d4
|
|
| MD5 |
31a249baaa2c7f05d327e5ebe49f9c5d
|
|
| BLAKE2b-256 |
10971b6d8952b7773b7c63655f206ac68b0246be1279cf60846c48b982b96b82
|