Skip to main content

Django views that wrap MCP stdio servers and expose them over Streamable HTTP

Project description

django-mcp-wrapper

PyPI Tests Changelog License

Django views that wrap MCP stdio servers and expose them over Streamable HTTP.

Installation

pip install django-mcp-wrapper

For OAuth 2.0 support (Claude for Web, dynamic client registration):

pip install django-mcp-wrapper[oauth]

Quick Start

Define a wrapper class and mount it at a URL path:

# mcp_wrappers.py
from django_mcp_wrapper import StdioMcpWrapper

class FileSystemMcp(StdioMcpWrapper):
    command = "npx"
    args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
# urls.py
from django.urls import path
from .mcp_wrappers import FileSystemMcp

urlpatterns = [
    path("mcp", FileSystemMcp.as_view()),
]

Override get_command(), get_args(), or get_env() for per-request customization:

class DynamicMcp(StdioMcpWrapper):
    command = "npx"

    def get_args(self):
        directory = os.environ.get("MCP_DIR", os.getcwd())
        return ["-y", "@modelcontextprotocol/server-filesystem", directory]

Mount multiple wrappers at different paths:

urlpatterns = [
    path("desktop/mcp", DesktopMcp.as_view()),
    path("project/mcp", ProjectMcp.as_view()),
]

Authentication

API Key

Override authenticate() to add request-level auth. Return None to allow the request, or an HttpResponse to reject it:

class SecureMcp(StdioMcpWrapper):
    command = "npx"
    args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

    def authenticate(self, request):
        valid_keys = {"my-secret-key"}
        if request.GET.get("apiKey") not in valid_keys:
            return HttpResponse("Invalid API key", status=401)
        return None

See examples/apikey/ for a full working example.

OAuth 2.0 with Dynamic Client Registration (Claude for Web)

For MCP clients that use OAuth (like Claude for Web), django-mcp-wrapper provides RFC 9728 protected resource metadata and bearer token validation, with RFC 7591 dynamic client registration via django-oauth-toolkit-dcr, all backed by django-oauth-toolkit:

# mcp_wrappers.py
from django_mcp_wrapper import StdioMcpWrapper
from django_mcp_wrapper.oauth import bearer_token_authenticate

class OAuthMcp(StdioMcpWrapper):
    command = "npx"
    args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

    def authenticate(self, request):
        return bearer_token_authenticate(request)
# urls.py
from django_mcp_wrapper.oauth import oauth_urlpatterns

urlpatterns = [
    path("mcp", OAuthMcp.as_view()),
    *oauth_urlpatterns(
        resource_url="https://yourserver.com/mcp",
        authorization_server_url="https://yourserver.com/o",
    ),
]

This wires up:

  • /.well-known/oauth-protected-resource/mcp — resource metadata (RFC 9728)
  • /o/register/ — dynamic client registration (RFC 7591, via django-oauth-toolkit-dcr)
  • /o/authorize/, /o/token/ — authorization code + PKCE flow (django-oauth-toolkit)

See examples/oauth/ for a full working example with settings.

Development

cd django-mcp-wrapper
python -m venv venv
source venv/bin/activate
pip install -e '.[dev]'
python -m pytest

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

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

Source Distribution

django_mcp_wrapper-0.1.tar.gz (14.9 kB view details)

Uploaded Source

Built Distribution

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

django_mcp_wrapper-0.1-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file django_mcp_wrapper-0.1.tar.gz.

File metadata

  • Download URL: django_mcp_wrapper-0.1.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for django_mcp_wrapper-0.1.tar.gz
Algorithm Hash digest
SHA256 31f3064b508460d128a0de08d0fc573067ad2a7ce89f84300b6ca835d519e036
MD5 543db8b5e8fc6fad084a2f05057b04db
BLAKE2b-256 094bb338e73a6041a2a1cd8c748af19800f8ebf87ca3b6e917a7693002853104

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_mcp_wrapper-0.1.tar.gz:

Publisher: publish.yml on player1537-playground/django-mcp-wrapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_mcp_wrapper-0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_mcp_wrapper-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 59806420b4fe50290292b7af30354df06789fc4a043866e7c2b0dcdf68d948a1
MD5 a4e251c2b092a1ebf07abe0da46d858b
BLAKE2b-256 eb24a5ff0b09ba51ad0cd36352d6703fb5d0a1c5e9080d50b133918c43e97e56

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_mcp_wrapper-0.1-py3-none-any.whl:

Publisher: publish.yml on player1537-playground/django-mcp-wrapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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