Skip to main content

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, version: str = "1.0.0", json_response: bool = True)
  • name: Name of your MCP server
  • version: Version string (default: "1.0.0")
  • 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 APIRouter instance
  • 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

  1. Decorator Registration: When you use @mcp_it.mcp(), the function is registered in an internal registry
  2. Route Analysis: During build(), mcp-it analyzes your FastAPI routes to detect:
    • Path parameters
    • Query parameters
    • Body parameters
    • Pydantic models
  3. Tool Creation: MCP tools are created with proper signatures and type annotations
  4. Internal Proxy: When an MCP tool is called, mcp-it makes an internal ASGI call to your FastAPI route
  5. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_it-0.1.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_it-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file mcp_it-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_it-0.1.0.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

Hashes for mcp_it-0.1.0.tar.gz
Algorithm Hash digest
SHA256 aa35e78dfd3db4825b7e1ec342682c17188e336173c0704414180194c306742b
MD5 60c8603a924002e6918d826a2d4eee61
BLAKE2b-256 d8835608c56a81590783bed721ffbe7f2b1850a9cf47d61b40e73ae1f5d2e0d8

See more details on using hashes here.

File details

Details for the file mcp_it-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_it-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for mcp_it-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 99f300af3dc3ddf52f763a7c390aa4deaaf8c78fa9ba81153bd5031543d348f3
MD5 f756bff263352243050a83e726632644
BLAKE2b-256 f946c28f741e600efe950f14ebb0e1992adbc30e06f1c8c3212870966c7930ac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page