Skip to main content

backend2mcp

Convert any Python web backend into a fully functional MCP (Model Context Protocol) server automatically, with near-zero developer boilerplate.

What is this?

backend2mcp automatically exposes your existing Python web API routes as MCP tools. No HTTP servers, no proxies, no code generation—just import and run.

Installation

Install the core package:

pip install backend2mcp

Install with framework support:

pip install backend2mcp[fastapi]      # FastAPI support
pip install backend2mcp[flask]         # Flask support
pip install backend2mcp[django]        # Django support
pip install backend2mcp[fastapi,flask] # Multiple frameworks

Quickstart

FastAPI

from fastapi import FastAPI
from backend2mcp.fastapi import MCPAdapter

app = FastAPI()

@app.get("/users/{id}")
async def get_user(id: int):
    return {"id": id, "name": "Satyam"}

MCPAdapter(app).run()

Flask

from flask import Flask
from backend2mcp.flask import MCPAdapter

app = Flask(__name__)

@app.route("/users/<int:id>")
def get_user(id):
    return {"id": id, "name": "Satyam"}

MCPAdapter(app).run()

Django

from django.urls import path
from backend2mcp.django import MCPAdapter

urlpatterns = [
    path("users/<int:id>/", views.get_user),
]

MCPAdapter(urlpatterns=urlpatterns).run()

CLI Usage

# Auto-detect framework
backend2mcp run app:app

# Explicit framework
backend2mcp run app:app --framework fastapi
backend2mcp run app:app --framework flask
backend2mcp run app:app --framework django

Decorator Override

Customize tool behavior with @mcp_tool:

from backend2mcp.fastapi import MCPAdapter, mcp_tool

app = FastAPI()

@app.get("/users/{id}")
@mcp_tool(
    name="get_user",
    description="Get a user by their ID",
    hidden=False
)
async def get_user(id: int):
    return {"id": id}

Tool Naming

Tools are auto-named using a consistent convention:

Route Tool Name
GET /users/{id} get_by_id
POST /search post_search
PUT /users/{id} put_by_id
DELETE /users/{id} delete_by_id

Authentication

backend2mcp provides flexible authentication support through pluggable AuthProvider classes.

No Authentication (Default)

Zero config, no auth required:

adapter = MCPAdapter(app)  # Works without auth

Bearer Token Auth

from backend2mcp.core import BearerAuthProvider

auth = BearerAuthProvider(
    token_header="Authorization",        # Header name
    token_prefix="Bearer",               # Token prefix
    validate_tokens=["secret1", "secr2"] # Optional whitelist
)
adapter = MCPAdapter(app, auth_provider=auth)

API Key Auth

from backend2mcp.core import APIKeyAuthProvider

auth = APIKeyAuthProvider(
    header_name="X-API-Key",     # Header name
    query_param="api_key",       # Query param name
    valid_keys=["key1", "key2"]  # Optional whitelist
)
adapter = MCPAdapter(app, auth_provider=auth)

Custom Headers Injection

from backend2mcp.core import HeaderInjectionAuthProvider

auth = HeaderInjectionAuthProvider(
    static_headers={
        "X-Custom-Header": "value",
        "Authorization": "Bearer static-token"
    }
)
adapter = MCPAdapter(app, auth_provider=auth)

Combining Providers

from backend2mcp.core import (
    BearerAuthProvider,
    APIKeyAuthProvider,
    combine_providers
)

auth = combine_providers(
    BearerAuthProvider(),
    APIKeyAuthProvider()
)
adapter = MCPAdapter(app, auth_provider=auth)

Accessing Auth in Handlers

Auth context is injected into handlers:

from backend2mcp.fastapi import MCPAdapter
from backend2mcp.core import BearerAuthProvider, AuthContext

app = FastAPI()
auth = BearerAuthProvider()

@app.get("/users/{id}")
async def get_user(id: int, auth_context: AuthContext = None):
    headers = auth_context.headers if auth_context else {}
    user = get_user_from_db(id, headers=headers)
    return user

adapter = MCPAdapter(app, auth_provider=auth)

Architecture

backend2mcp/
├── core/              # Shared implementation
│   ├── adapter.py     # BaseAdapter abstract interface
│   ├── auth.py        # Auth providers (Bearer, API Key, etc.)
│   ├── server.py      # MCP server implementation
│   ├── schema.py      # Schema conversion utilities
│   └── exceptions.py  # Structured exceptions
├── fastapi/           # FastAPI adapter
├── flask/             # Flask adapter
├── django/            # Django adapter
└── cli/               # Typer CLI

Core Abstractions

  • BaseAdapter: Abstract interface all framework adapters implement
  • AuthProvider / AuthContext: Pluggable authentication system
  • MCPServer: Handles MCP protocol using official mcp SDK
  • Tool Execution: Direct handler invocation (no HTTP calls)
  • Schema Generation: Pydantic-integrated JSON Schema extraction

Writing a New Adapter

To add support for another framework:

  1. Create backend2mcp/framework/
  2. Implement BaseAdapter interface:
    • get_routes() - Extract all routes from the framework
    • introspect_route() - Convert a route to ToolInfo
    • execute_tool() - Call handler with resolved arguments
    • build_tool_name() - Generate MCP-safe tool names
  3. Export MCPAdapter from the subpackage
from backend2mcp.core.adapter import BaseAdapter, ToolInfo

class MCPAdapter(BaseAdapter):
    def get_routes(self) -> list[tuple]:
        # Your route extraction logic
        pass

    def introspect_route(self, path, method, handler, config) -> ToolInfo:
        # Your schema extraction logic
        pass

    def execute_tool(self, handler, arguments, context=None):
        # Your handler invocation logic
        pass

    def get_app(self):
        # Return underlying framework object
        pass

    def build_tool_name(self, http_method, path):
        # Your naming convention
        pass

Roadmap

Phase Frameworks
Phase 1 (this release) FastAPI, Flask, Django
Phase 2 Express, NestJS, Fastify
Phase 3 Spring Boot, Quarkus
Phase 4 Gin, Fiber, Echo

License

MIT

Metadata

Release files for backend2mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for backend2mcp 0.1.0
File Size Uploaded
backend2mcp-0.1.0.tar.gz 27.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for backend2mcp 0.1.0
File Interpreter ABI Platform
backend2mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 51.2 kB

Release files / backend2mcp-0.1.0.tar.gz

Download URL backend2mcp-0.1.0.tar.gz
Size 27.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ae40f23ad1f64d6d0030796598ab2858a328ac62f9c6e7928309ba6bbd7b6a84
BLAKE2b-256 checksum
How to use checksums
0dedadb689e45786f3e586c2b19bd0a002d12077548aff65b94c5698152355f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release files / backend2mcp-0.1.0-py3-none-any.whl

Download URL backend2mcp-0.1.0-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd233a922b998f3e406ab42bb8c6b8f21dab7d99ba21c8bf2fe1898858abd29a
BLAKE2b-256 checksum
How to use checksums
ad561c64ac2405b05cb7bd308f58eebef1c03e236fbaf8548323f58b3079e59a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page