django-drf-mcp
Automatically exposes Django REST Framework endpoints as MCP tools with zero configuration, supporting multiple transports and authentication.
README
django-drf-mcp
Add MCP (Model Context Protocol) to any Django REST Framework project. Auto-discovers all DRF endpoints and exposes them as MCP tools — zero boilerplate.
Features
- Zero config — add
"django_drf_mcp"toINSTALLED_APPS, include the URLs, done - Auto-discovery — every DRF ViewSet/APIView becomes an MCP tool automatically
- Endpoint filtering — include or exclude specific endpoints with
METHOD:PATHglob patterns - Multiple transports — STDIO, SSE, Streamable HTTP, or embedded Django view
- Authentication — pass auth headers (Token, JWT, Basic, API key) to MCP tool calls via
HEADERSsetting - DRF-integrated MCP view — the
/mcp/endpoint is a DRFAPIView, inheriting authentication and permissions fromREST_FRAMEWORKsettings - MCP Docs UI — interactive Swagger-style docs for your MCP tools at
/mcp/docs - DRF Swagger UI — optional built-in Swagger UI and OpenAPI schema endpoints
- Fully configurable — control every feature via a single
DJANGO_MCPsettings dict - Auto-configures drf-spectacular — no manual setup needed
Installation
pip install django-drf-mcp
Dependencies (installed automatically)
- Django >= 4.0
- Django REST Framework
- drf-spectacular
- FastMCP >= 2.0.0
- fastmcp-docs
- httpx
Quick Start
1. Add to INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
...
"rest_framework",
"django_drf_mcp",
]
drf-spectacularis auto-injected — you don't need to add it yourself.
2. Include URLs
# urls.py
from django.urls import path, include
urlpatterns = [
...
path("", include("django_drf_mcp.urls")),
]
That's it. The MCP endpoint is now live at /mcp/.
3. Enable MCP Docs UI (requires ASGI)
For interactive documentation of your MCP tools, replace your asgi.py:
# asgi.py
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
from django_drf_mcp.asgi import get_asgi_application
application = get_asgi_application()
Run with an ASGI server:
uvicorn myproject.asgi:application --host 0.0.0.0 --port 8000
MCP Docs will be available at /mcp/docs.
Transports
STDIO (Claude Code / Claude Desktop)
python manage.py runmcp --transport stdio
SSE
python manage.py runmcp --transport sse --host 0.0.0.0 --port 8001
Streamable HTTP
python manage.py runmcp --transport streamable-http --host 0.0.0.0 --port 8001
Embedded Django View
The MCP protocol is also served at /mcp/ as a DRF APIView — no separate process needed. Supports GET (health check) and POST (JSON-RPC). Inherits authentication and permission classes from REST_FRAMEWORK settings.
MCP Client Configuration
STDIO
{
"mcpServers": {
"my-app": {
"command": "python",
"args": ["manage.py", "runmcp", "--transport", "stdio"]
}
}
}
With a remote Django server:
{
"mcpServers": {
"my-app": {
"command": "python",
"args": ["manage.py", "runmcp", "--transport", "stdio", "--base-url", "https://my-app.example.com"]
}
}
}
Streamable HTTP — Embedded (same port as Django)
The /mcp/ Django view serves MCP on the same port as your app (e.g. 8000):
{
"mcpServers": {
"my-app": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp/"
}
}
}
With authentication:
{
"mcpServers": {
"my-app": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp/",
"headers": {
"Authorization": "Token abc123..."
}
}
}
}
Streamable HTTP — Standalone (separate port)
runmcp --transport streamable-http starts a standalone FastMCP server (e.g. port 8001) that proxies tool calls to Django on port 8000:
{
"mcpServers": {
"my-app": {
"type": "streamable-http",
"url": "http://localhost:8001/mcp"
}
}
}
With authentication:
{
"mcpServers": {
"my-app": {
"type": "streamable-http",
"url": "http://localhost:8001/mcp",
"headers": {
"Authorization": "Token abc123..."
}
}
}
}
SSE — Standalone (separate port)
runmcp --transport sse starts a standalone FastMCP server (e.g. port 8001) that proxies tool calls to Django on port 8000:
{
"mcpServers": {
"my-app": {
"type": "sse",
"url": "http://localhost:8001/sse"
}
}
}
With authentication:
{
"mcpServers": {
"my-app": {
"type": "sse",
"url": "http://localhost:8001/sse",
"headers": {
"Authorization": "Token abc123..."
}
}
}
}
Note: The client
headersauthenticate the MCP client to the MCP endpoint. The server-sideDJANGO_MCP["HEADERS"]setting (see Authentication) authenticates MCP tool calls to the Django API. When using DRF authentication, configure both for full security.
Settings
All configuration is optional. Add a DJANGO_MCP dict to your settings.py:
DJANGO_MCP = {
# --- Server ---
"NAME": "django-drf-mcp", # MCP server name
"BASE_URL": "http://localhost:8000", # Django server URL
"MCP_PATH": "/mcp/", # MCP endpoint path
# --- Endpoint Filtering ---
"INCLUDE": [], # Only expose matching METHOD:PATH patterns
"EXCLUDE": [], # Remove matching METHOD:PATH patterns
# --- Authentication ---
"HEADERS": {}, # HTTP headers sent with every MCP tool call
"INTERNAL_TOKEN": "", # Shared secret for MCP internal requests (optional)
# --- MCP Docs UI ---
"MCP_DOCS_ENABLED": True, # Enable/disable /mcp/docs
"MCP_DOCS_TITLE": None, # Docs page title (defaults to NAME)
"MCP_DOCS_DESCRIPTION": None, # Docs description (defaults to OpenAPI description)
"MCP_DOCS_VERSION": None, # Docs version (defaults to OpenAPI version)
"MCP_DOCS_EMOJI": None, # Emoji shown before the title
"MCP_DOCS_LINKS": [], # Extra links: [{"text": "...", "url": "..."}]
"MCP_DOCS_ENABLE_CORS": True, # Enable CORS on docs routes
"MCP_DOCS_VERBOSE": True, # Show tools load during server startup
# --- DRF Swagger / Schema ---
"SWAGGER_ENABLED": False, # Enable Swagger UI + OpenAPI schema endpoints
"SCHEMA_PATH": "/api/schema/", # Schema endpoint path
"SWAGGER_PATH": "/api/docs/", # Swagger UI path
}
Settings Reference
| Setting | Type | Default | Description |
|---|---|---|---|
NAME |
str |
"django-drf-mcp" |
MCP server name, shown in health check and docs |
BASE_URL |
str |
"http://localhost:8000" |
URL of the running Django server. Used as the base URL for proxying MCP tool calls and injected into the OpenAPI schema servers list |
MCP_PATH |
str |
"/mcp/" |
Path where the MCP endpoint is mounted |
INCLUDE |
list |
[] |
Only expose endpoints matching these METHOD:PATH glob patterns. Empty = include all |
EXCLUDE |
list |
[] |
Remove endpoints matching these METHOD:PATH glob patterns. Applied after INCLUDE |
HEADERS |
dict |
{} |
HTTP headers sent with every MCP tool call (e.g. {"Authorization": "Token ..."}) |
INTERNAL_TOKEN |
str |
"" |
Shared secret for MCP internal requests. If empty, a per-process auto-generated token is used. Set this for multi-worker or standalone runmcp deployments |
MCP_DOCS_ENABLED |
bool |
True |
Enable the MCP Docs UI (Starlette-based, requires ASGI) |
MCP_DOCS_TITLE |
str|None |
None |
Docs page title. Falls back to NAME |
MCP_DOCS_DESCRIPTION |
str|None |
None |
Docs description. Falls back to the OpenAPI schema description |
MCP_DOCS_VERSION |
str|None |
None |
Docs version string. Falls back to the OpenAPI schema version |
MCP_DOCS_EMOJI |
str|None |
None |
Emoji displayed before the docs title |
MCP_DOCS_LINKS |
list |
[] |
Extra links shown in docs. Each item: {"text": "...", "url": "..."} |
MCP_DOCS_ENABLE_CORS |
bool |
True |
Enable CORS on the MCP Docs routes |
MCP_DOCS_VERBOSE |
bool |
True |
Show tools load during server startup |
SWAGGER_ENABLED |
bool |
False |
Enable the DRF Swagger UI and OpenAPI schema endpoints |
SCHEMA_PATH |
str |
"/api/schema/" |
Path for the OpenAPI schema endpoint |
SWAGGER_PATH |
str |
"/api/docs/" |
Path for the Swagger UI endpoint |
Example: Full Configuration
DJANGO_MCP = {
"NAME": "products-api",
"BASE_URL": "http://localhost:8000",
"MCP_PATH": "/mcp/",
"HEADERS": {
"Authorization": "Token abc123...",
},
"MCP_DOCS_ENABLED": True,
"MCP_DOCS_TITLE": "Products MCP Tools",
"MCP_DOCS_DESCRIPTION": "MCP tools for the Products API",
"MCP_DOCS_EMOJI": "\U0001f6d2",
"MCP_DOCS_LINKS": [
{"text": "Admin", "url": "/admin/"},
{"text": "GitHub", "url": "https://github.com/myorg/myrepo"},
],
"MCP_DOCS_ENABLE_CORS": True,
"MCP_DOCS_VERBOSE": False,
"SWAGGER_ENABLED": True,
}
Example: Minimal (disable docs)
DJANGO_MCP = {
"NAME": "my-api",
"BASE_URL": "https://my-api.example.com",
"MCP_DOCS_ENABLED": False,
}
Endpoint Filtering
Control which DRF endpoints are exposed as MCP tools using INCLUDE and EXCLUDE patterns.
Patterns use the format "METHOD:PATH" with glob-style wildcards (*):
# Only expose GET endpoints under /api/
DJANGO_MCP = {
"INCLUDE": ["GET:/api/*"],
}
# Expose everything except DELETE operations
DJANGO_MCP = {
"EXCLUDE": ["DELETE:*"],
}
# Expose /api/ endpoints, but exclude DELETE on users
DJANGO_MCP = {
"INCLUDE": ["*:/api/*"],
"EXCLUDE": ["DELETE:/api/users/*"],
}
METHOD— HTTP method (GET,POST,PUT,PATCH,DELETE) or*for any methodPATH— URL path with*wildcard (e.g./api/*,/api/users/{id}/)- Method matching is case-insensitive
- If
INCLUDEis empty (default), all endpoints are included - If
EXCLUDEis empty (default), nothing is excluded - When both are set,
INCLUDEis applied first, thenEXCLUDEremoves from the result
Authentication
If your DRF endpoints require authentication, there are two layers to configure:
1. Server-side: MCP tool calls to the Django API
Configure the HEADERS setting so MCP tool HTTP calls include credentials:
# DRF TokenAuthentication
DJANGO_MCP = {
"HEADERS": {
"Authorization": "Token abc123...",
},
}
# JWT (e.g. SimpleJWT)
DJANGO_MCP = {
"HEADERS": {
"Authorization": "Bearer eyJ...",
},
}
# Basic Auth
DJANGO_MCP = {
"HEADERS": {
"Authorization": "Basic dXNlcjpwYXNz",
},
}
# Custom API key header
DJANGO_MCP = {
"HEADERS": {
"X-API-Key": "my-secret-key",
},
}
These headers are passed to the underlying httpx.AsyncClient and included in every HTTP request made by MCP tools to your Django API.
SessionAuthentication & MCP Internal Requests
SessionAuthentication uses cookies and CSRF tokens — neither of which the MCP internal proxy has. If your views use SessionAuthentication, MCP tool calls will get 403 Forbidden.
django-drf-mcp solves this with a built-in shared secret. The library automatically generates a per-process cryptographic token and injects it into every internal MCP proxy request via the X-MCP-Internal-Token header.
To use this feature, you must add the IsMCPInternalRequest permission class to any view you want MCP tools to access. Without it, the token header is ignored and normal authentication applies.
Add it to your views using the | (OR) operator:
from rest_framework.permissions import IsAuthenticated
from django_drf_mcp.permissions import IsMCPInternalRequest
class MyViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated | IsMCPInternalRequest]
This means:
- Browser users — must be authenticated via session (or any other auth method)
- MCP tool calls — bypass session auth via the auto-injected secret token
The token is 256-bit cryptographically random and regenerated on every server restart. External clients cannot guess it.
Multi-worker & standalone runmcp deployments
The auto-generated token is per-process. If the MCP proxy and your DRF views run in different processes (e.g., runmcp standalone mode, or gunicorn with multiple workers behind a load balancer), set a shared INTERNAL_TOKEN:
DJANGO_MCP = {
"INTERNAL_TOKEN": "your-shared-secret-here", # Use a strong random value
}
When INTERNAL_TOKEN is set, it is used instead of the auto-generated per-process token. All workers and the runmcp process must share the same value.
Tip: Generate a strong token with
python -c "import secrets; print(secrets.token_urlsafe(32))".
2. Client-side: MCP client to the /mcp/ endpoint
The embedded /mcp/ view is a DRF APIView and inherits DEFAULT_AUTHENTICATION_CLASSES and DEFAULT_PERMISSION_CLASSES from REST_FRAMEWORK settings. If your DRF config requires authentication globally, MCP clients must also send auth headers:
{
"mcpServers": {
"my-app": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp/",
"headers": {
"Authorization": "Token abc123..."
}
}
}
}
Full authentication example
# settings.py
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.TokenAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
}
DJANGO_MCP = {
"NAME": "my-api",
"HEADERS": {
"Authorization": "Token abc123...",
},
}
// .mcp.json (MCP client)
{
"mcpServers": {
"my-api": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp/",
"headers": {
"Authorization": "Token abc123..."
}
}
}
}
Endpoints
| Path | Description | Controlled by |
|---|---|---|
/mcp/ |
MCP protocol endpoint (JSON-RPC) | MCP_PATH |
/mcp/docs |
MCP Docs UI | MCP_DOCS_ENABLED |
/mcp/openapi.json |
MCP OpenAPI schema | MCP_DOCS_ENABLED |
/mcp/api/tools |
MCP tools JSON API (list) | MCP_DOCS_ENABLED |
/mcp/api/tools/{tool_name} |
MCP tool detail JSON API | MCP_DOCS_ENABLED |
/mcp/favicon |
MCP Docs favicon | MCP_DOCS_ENABLED |
/api/schema/ |
DRF OpenAPI schema (YAML) | SWAGGER_ENABLED |
/api/docs/ |
DRF Swagger UI | SWAGGER_ENABLED |
How It Works
django_drf_mcpauto-injectsdrf-spectacularintoINSTALLED_APPSand configuresDEFAULT_SCHEMA_CLASS- On startup, it generates an OpenAPI schema from all registered DRF views
- The base URL is injected into the OpenAPI schema
serverslist - FastMCP converts each API endpoint into an MCP tool via
OpenAPIProvider - An
httpx.AsyncClientis created with the configuredBASE_URLandHEADERSfor proxying tool calls - Tools are served via STDIO, SSE, Streamable HTTP, or the embedded Django view
- When running under ASGI,
fastmcp-docsprovides interactive documentation at/mcp/docs
Management Command
python manage.py runmcp [options]
| Option | Default | Description |
|---|---|---|
--transport |
stdio |
Transport type: stdio, sse, streamable-http |
--host |
0.0.0.0 |
Bind host (for sse / streamable-http) |
--port |
8001 |
Bind port (for sse / streamable-http) |
--base-url |
from settings | Override BASE_URL for proxying API calls |
Requirements
- Python >= 3.10
- Django >= 4.0
- Django REST Framework
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。