Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Django Server

БесплатноНе проверен

A Django MCP server that exposes tools and resources to AI agents using simple decorators, with auto-discovery, type safety, and custom authentication.

GitHubEmbed

Описание

A Django MCP server that exposes tools and resources to AI agents using simple decorators, with auto-discovery, type safety, and custom authentication.

README

Full MCP (Model Context Protocol) server implementation for Django. Expose tools and resources to AI agents with simple decorators.

Features

  • 🚀 Simple decorators - @mcp_tool, @mcp_resource, @mcp_prompt
  • 🔄 Auto-discovery - Automatically finds mcp_tools.py in all Django apps
  • 📝 Type-safe - Generates JSON Schema from Python type hints
  • 🎯 MCP compliant - Full JSON-RPC 2.0 implementation (spec 2025-06-18)
  • 🔒 Custom auth - Plug in any token-based authentication backend
  • 👤 User context - Authenticated user injected automatically into tools
  • 🔧 Zero config - Works out of the box

Installation

pip install mcp-django-server

Quick Start

1. Add to INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    ...
    'mcp_server',
]

# Optional configuration
MCP_SERVER_NAME = "My Django MCP Server"
MCP_SERVER_VERSION = "1.0.0"

# Auth backend (see Authentication section)
# MCP_AUTH_BACKEND = 'myapp.mcp.auth.TokenAuth'

# Public methods — skip auth (default: initialize + notifications/initialized)
# MCP_PUBLIC_METHODS = ['initialize', 'notifications/initialized']

# Rate limiting via Django cache (calls per period in seconds)
# MCP_RATE_LIMIT = {"calls": 100, "period": 60}

2. Include URLs

# urls.py
from django.urls import path, include

urlpatterns = [
    ...
    path('', include('mcp_server.urls')),
]

3. Create tools

Create mcp_tools.py in any Django app:

# myapp/mcp_tools.py
from mcp_server import mcp_tool, mcp_resource
from .models import Product

@mcp_tool(
    name="search_products",
    description="Search products by name and category"
)
def search_products(query: str, category: str = None, limit: int = 10):
    """Search products - automatically exposed via /mcp/ endpoint."""
    qs = Product.objects.filter(name__icontains=query)
    if category:
        qs = qs.filter(category=category)
    return [
        {"id": p.id, "name": p.name, "price": str(p.price)}
        for p in qs[:limit]
    ]

@mcp_resource(
    uri="catalog://products/{id}",
    name="Product",
    description="Full product details",
    mime_type="application/json"
)
def get_product(id: int):
    """Get product by ID - exposed as MCP resource."""
    p = Product.objects.get(pk=id)
    return {
        "id": p.id,
        "name": p.name,
        "description": p.description,
        "price": str(p.price)
    }

4. Test it

# Initialize
curl -X POST http://localhost:8000/mcp/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","clientInfo":{"name":"test"}}}'

# List tools
curl -X POST http://localhost:8000/mcp/ \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

# Call tool
curl -X POST http://localhost:8000/mcp/ \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_products","arguments":{"query":"laptop"}}}'

Authentication

Custom auth backend

Set MCP_AUTH_BACKEND in settings.py to require token authentication on every MCP request.

# settings.py
MCP_AUTH_BACKEND = 'myapp.mcp.auth.TokenAuth'

The class must implement authenticate(token: str) -> User | None:

# myapp/mcp/auth.py
class TokenAuth:
    def authenticate(self, token):
        from django.contrib.auth import get_user_model
        User = get_user_model()
        try:
            return User.objects.get(mcp_token=token)
        except User.DoesNotExist:
            return None

When configured, every request must include Authorization: Bearer <token>. A missing or invalid token returns HTTP 401.

User context in tools

If your tool function declares a user parameter, the authenticated user is injected automatically. The user parameter is excluded from the MCP input schema (not visible to clients).

@mcp_tool(description="Get my listings")
def get_my_listings(user):
    return list(Listing.objects.filter(owner=user).values())

Conditional tools

Use condition= to expose a tool only when a predicate on the user is satisfied. The tool is hidden from tools/list and blocked in tools/call when the condition returns False.

@mcp_tool(
    description="Publish a listing",
    condition=lambda user: hasattr(user, 'seller_profile')
)
def publish_listing(user, listing_id: int):
    ...

Hooks

Override MCPView methods to add custom logic without touching the core dispatch:

# myapp/views.py
from mcp_server.views import MCPView
import logging

logger = logging.getLogger(__name__)

class AuditedMCPView(MCPView):

    def before_dispatch(self, method, user):
        logger.info("MCP call: method=%s user=%s", method, getattr(user, 'pk', None))

    def after_tool_call(self, user, tool_name, result, duration_ms):
        logger.info("Tool %s completed in %.1fms for user %s", tool_name, duration_ms, user)
# urls.py
from myapp.views import AuditedMCPView
urlpatterns = [
    path('mcp/', AuditedMCPView.as_view()),
]

Rate Limiting

Enable per-user (or per-IP for anonymous) rate limiting via Django's cache:

# settings.py
MCP_RATE_LIMIT = {"calls": 100, "period": 60}  # 100 requests per 60 seconds

Returns HTTP 429 with a JSON-RPC error when the limit is exceeded.

API Reference

@mcp_tool

Register a function as an MCP tool.

@mcp_tool(name="tool_name", description="Tool description")
def my_tool(param1: str, param2: int = 10):
    return {"result": "value"}

Parameters:

  • name (str, optional): Tool name. Defaults to function name.
  • description (str): Tool description for AI agents.
  • condition (callable, optional): (user) -> bool. When set, the tool is only listed/callable when the condition is satisfied for the current user.

Type Hints:

  • Function type hints are automatically converted to JSON Schema
  • Supported types: str, int, float, bool, list, dict
  • Parameters without defaults are marked as required
  • The user parameter (if present) is injected by the auth layer and excluded from the schema

@mcp_resource

Register a function as an MCP resource.

@mcp_resource(
    uri="catalog://items/{id}",
    name="Item",
    description="Item details",
    mime_type="application/json"
)
def get_item(id: int):
    return {"id": id, "data": "..."}

Parameters:

  • uri (str): Resource URI template with {param} placeholders
  • name (str, optional): Resource name. Defaults to function name.
  • description (str): Resource description
  • mime_type (str): MIME type. Default: "application/json"

@mcp_prompt

Register a function as an MCP prompt template.

@mcp_prompt(
    name="analyze",
    description="Analyze data",
    arguments=[
        {"name": "data_id", "description": "Data ID", "required": True}
    ]
)
def analyze_prompt(data_id: int):
    return f"Analyze data with ID: {data_id}"

MCP Endpoints

Once installed, your Django app exposes:

  • POST /mcp/ - Main MCP JSON-RPC 2.0 endpoint

Supported methods:

  • initialize - Initialize MCP session
  • tools/list - List all registered tools
  • tools/call - Execute a tool
  • resources/list - List all resources
  • resources/read - Read a resource
  • prompts/list - List all prompts
  • prompts/get - Get a prompt

Integration with django-mcp-discovery

If you have django-mcp-discovery installed, this package automatically updates the /.well-known/mcp-server manifest with registered tools.

Examples

Django ORM Tool

@mcp_tool(description="Get user by email")
def get_user(email: str):
    from django.contrib.auth import get_user_model
    User = get_user_model()
    user = User.objects.get(email=email)
    return {
        "id": user.id,
        "email": user.email,
        "name": user.get_full_name()
    }

External API Tool

@mcp_tool(description="Get weather forecast")
def get_weather(city: str):
    import requests
    response = requests.get(f"https://api.weather.com/{city}")
    return response.json()

File Resource

@mcp_resource(
    uri="files://{path}",
    description="Read file content",
    mime_type="text/plain"
)
def read_file(path: str):
    with open(path, 'r') as f:
        return f.read()

License

MIT

Links

from github.com/99rig/django-mcp-server

Установить Django Server в Claude Desktop, Claude Code, Cursor

Рекомендуется · одна команда, все IDE
unyly install mcp-django-server

Ставит в Claude Desktop, Claude Code, Cursor и VS Code — сам разбирается с npx, uvx и сборкой из исходников.

Впервые? Поставь CLI: curl -fsSL https://unyly.org/install | sh

Или настроить вручную

Выполни в терминале:

claude mcp add mcp-django-server -- uvx mcp-django-server

FAQ

Django Server MCP бесплатный?

Да, Django Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Django Server?

Нет, Django Server работает без API-ключей и переменных окружения.

Django Server — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Django Server в Claude Desktop, Claude Code или Cursor?

Открой Django Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Django Server with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории ai