Metadata-Version: 2.4
Name: backend2mcp
Version: 0.1.0
Summary: Convert any Python web backend into a fully functional MCP server automatically
Project-URL: homepage, https://github.com/SatyamSingh8306/backend2mcp
Project-URL: repository, https://github.com/SatyamSingh8306/backend2mcp
Author-email: backend2mcp Contributors <contributors@backend2mcp.dev>
License: MIT
License-File: LICENSE
Keywords: django,fastapi,flask,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Framework :: Flask
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Requires-Dist: mcp>=1.1.2
Requires-Dist: pydantic>=2.10.0
Requires-Dist: typer>=0.14.0
Provides-Extra: dev
Requires-Dist: black>=24.10.0; extra == 'dev'
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: django>=5.2.0; extra == 'dev'
Requires-Dist: djangorestframework>=3.15.0; extra == 'dev'
Requires-Dist: fastapi>=0.115.0; extra == 'dev'
Requires-Dist: flask>=3.1.0; extra == 'dev'
Requires-Dist: httpx>=0.28.0; extra == 'dev'
Requires-Dist: isort>=5.13.0; extra == 'dev'
Requires-Dist: mypy>=1.14.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Provides-Extra: django
Requires-Dist: django>=5.2.0; extra == 'django'
Requires-Dist: djangorestframework>=3.15.0; extra == 'django'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.115.0; extra == 'fastapi'
Requires-Dist: uvicorn>=0.32.0; extra == 'fastapi'
Provides-Extra: flask
Requires-Dist: flask>=3.1.0; extra == 'flask'
Description-Content-Type: text/markdown

# 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:

```bash
pip install backend2mcp
```

Install with framework support:

```bash
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

```python
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

```python
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

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

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

MCPAdapter(urlpatterns=urlpatterns).run()
```

## CLI Usage

```bash
# 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`:

```python
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:

```python
adapter = MCPAdapter(app)  # Works without auth
```

### Bearer Token Auth

```python
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

```python
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

```python
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

```python
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:

```python
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

```python
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