Skip to main content

Convert any Python web backend into a fully functional MCP server automatically

Project description

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

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

backend2mcp-0.1.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

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

backend2mcp-0.1.0-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: backend2mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 27.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for backend2mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ae40f23ad1f64d6d0030796598ab2858a328ac62f9c6e7928309ba6bbd7b6a84
MD5 beab6f1e45fd472ad91fca2d38dbcebf
BLAKE2b-256 0dedadb689e45786f3e586c2b19bd0a002d12077548aff65b94c5698152355f4

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for backend2mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cd233a922b998f3e406ab42bb8c6b8f21dab7d99ba21c8bf2fe1898858abd29a
MD5 3de865e8b3f084133d134056698a73cb
BLAKE2b-256 ad561c64ac2405b05cb7bd308f58eebef1c03e236fbaf8548323f58b3079e59a

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