djangorestframework-mcp-server
Exposes Django REST Framework services and selectors as MCP tools and resources, allowing MCP clients to invoke service mutations and read selector-backed data from a Django application.
Adds OpenTelemetry instrumentation for MCP tool calls, resource reads, and prompt gets, emitting spans such as mcp.tools.call, mcp.resources.read, and mcp.prompts.get when the OpenTelemetry extra is installed.
Provides a cross-worker Redis-backed SSE broker and replay buffer for multi-worker ASGI deployments, enabling session notifications and Last-Event-ID resume over Redis.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
django-spec-mcp
Serve django-service-specs
services and selectors as a Model Context Protocol
(MCP) server, conforming to MCP 2026-07-28 and 2025-11-25 (Streamable HTTP).
Coming from djangorestframework-mcp-server (drf-mcp)? Read
Moving from drf-mcp before the first deploy:
the settings key, the stored names and the registration calls all change.
Idea
Register kernel specs directly. The unit of registration is a ServiceSpec
or a SelectorSpec from django-service-specs, not a view: the spec says what
an operation takes, who may run it and what it returns, and this package serves
it over MCP. The same spec can be served by any other transport on the kernel.
from dataclasses import dataclass
from django.urls import path
from django_service_specs import (
DataclassPresenter,
DataclassValidator,
Parameter,
Parameters,
SelectorKind,
SelectorSpec,
ServiceSpec,
Unrestricted,
)
from django_spec_mcp import MCPServer
@dataclass
class InvoiceInput:
number: str
amount_cents: int
@dataclass
class InvoiceOutput:
id: int
number: str
amount_cents: int
server = MCPServer(name="my-app", auth_backend=my_auth_backend)
server.register_tool(
ServiceSpec(
service=create_invoice, # def create_invoice(*, number, amount_cents)
validator=DataclassValidator(InvoiceInput),
presenter=DataclassPresenter(InvoiceOutput),
permissions=[Unrestricted()],
),
name="invoices.create",
description="Create an invoice.",
)
server.register_resource(
SelectorSpec(
kind=SelectorKind.RETRIEVE,
selector=get_invoice, # def get_invoice(*, pk)
reads=Parameters([Parameter("pk", "integer", required=True)]),
presenter=DataclassPresenter(InvoiceOutput),
permissions=[Unrestricted()],
),
name="invoice",
uri_template="invoices://{pk}",
)
urlpatterns = [path("mcp/", server.urls)]See the quickstart for the full end-to-end recipe.
Services (mutations) and selectors (reads) → MCP tools, through
register_tool; the spec's class says which kind of tool it is.A
RETRIEVEselector → an MCP resource, throughregister_resource.A single
/mcpendpoint speaks Streamable HTTP. The/.well-known/oauth-protected-resourceendpoint comes mounted alongside.
Related MCP server: django-mcp-inspector
What ships
Tools —
tools/list,tools/callforregister_tool, over a kernelServiceSpec(mutations) orSelectorSpec(reads, with an optionalFilterSet, ordering and pagination).register_tools(registry, overrides=...)registers every spec in a kernelSpecRegistry.Server-supplied arguments —
server_arguments=ServerArguments(values=..., withheld=...)at registration answers a declared argument for the caller: the name leaves the tool's schema, a caller's value for it is dropped and logged by name, and the binding is checked when it is registered. Route and query values a tool asks for are read from the spec's ownreads.Resources —
resources/list,resources/templates/list,resources/readagainst a kernelRETRIEVESelectorSpec, presented by its own presenter; RFC 6570 templated URIs whose variables are the spec's reads.Prompts —
prompts/list,prompts/getagainst render callables returning strings,PromptMessages, or async coroutines.In-process transport surface — call tools without an HTTP round-trip:
MCPServer.call_tool/acall_toolandlist_tools/alist_toolsdrive the same dispatch and permission checks as the wire path, for embedding in agent bridges, toolsets, or management commands.unavailable_tools/aunavailable_toolsname each tool the listing leaves out with the reason, so a bridge can tell its model why one is missing.Tool annotations — pass
annotations=at registration (or rely on the read/mutation default) to advertise MCP hints likereadOnlyHint/destructiveHintontools/list.Generic
_meta— passmeta=at registration to populate the base protocol's free-form_metaobject on a tool, resource, or prompt's listing entry (and on thecontentsofresources/read). Passed through verbatim, so protocol extensions have somewhere to live.Interactive views (MCP Apps) —
register_ui_resource(...)declares an HTML view with typed CSP / permission metadata;ui=UIToolMeta(...)on a tool links its result to that view, and a host renders it inline in the chat. The render payload is thestructuredContentyou already emit, and a view's owntools/calls inherit your auth, permissions and rate limits. An extension over base MCP, so no protocol bump. We declare; the host sandboxes and renders.Pluggable auth — an
MCPAuthBackendverifies the bearer token;AllowAnyBackend(dev only) ships, andbearer_challengebuilds the 401 challenge a backend of your own answers with. A tool or resource is guarded by its spec's own kernelpermissions, andscopes=at registration adds an OAuth scope gate.RFC 8707 audience binding through
audience_matches, which a backend calls; RFC 9728 PRM served from the configured backend.Per-binding rate limits —
MCPRateLimitProtocol withFixedWindowRateLimit,SlidingWindowRateLimit, andTokenBucketRateLimitimplementations shipped.Async POST/DELETE + GET-side SSE push — sync
urlsfor WSGI,async_urlsfor ASGI;MCPServer.notify(session_id, payload)pushes JSON-RPC frames on the session's SSE stream. Per-workerInMemorySSEBrokeror cross-workerRedisSSEBroker(behind[redis]);Last-Event-IDresume viaInMemorySSEReplayBuffer/RedisSSEReplayBuffer.OpenTelemetry instrumentation —
mcp.tools.call,mcp.resources.read,mcp.prompts.getspans (no-op without the[otel]extra installed).Origin allowlist + protocol-version validation + session lifecycle per the transport rules of both revisions.
2026-07-28and later declare version, identity and capabilities on every request and hold no session;2025-11-25and earlier negotiate once throughinitialize. Both are served concurrently on one endpoint, because a legacy client has no fall-forward mechanism.
Install
pip install django-spec-mcp # base install
pip install "django-spec-mcp[redis]" # +Redis SSE broker for multi-worker ASGI
pip install "django-spec-mcp[otel]" # +OpenTelemetry instrumentation
pip install "django-spec-mcp[redis,otel]" # everything…or with uv:
uv add django-spec-mcp # base install
uv add "django-spec-mcp[redis]" # +Redis SSE broker for multi-worker ASGI
uv add "django-spec-mcp[otel]" # +OpenTelemetry instrumentation
uv add "django-spec-mcp[redis,otel]" # everythingTry it
Install mcp-inspector and point it at your dev server:
npx @modelcontextprotocol/inspector --url http://localhost:8000/mcp/Inspector lists tools, fills in arguments from the generated JSON Schema, and walks the OAuth auth flow against your configured Authorization Server.
Documentation
Quickstart — copy-pasteable end-to-end.
Moving from drf-mcp — what a project on drf-mcp changes to move across.
Concepts — tools vs resources, sessions, tool results.
Authentication — backends, permissions, audience binding, bring-your-own AS recipe.
Recipes — focused cookbook entries.
Reference — autodocs for every public symbol.
License
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Host any HTTP API as a standard MCP server; auto-distribute to 12+ mainstream agent platforms.
Remote MCP server exposing SMI Aware tools, resources, and skills over Streamable HTTP.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceIntegrates MCP tool hosting into Django applications, enabling easy definition and serving of MCP tools, resources, and prompts via ASGI with support for URL path parameters and logging.988 PyPI72MIT
- FlicenseNot gradedqualityDmaintenanceExposes Django runtime information (settings, apps, URLs, models, migrations) as MCP resources for AI agents to inspect a live Django project without static analysis.-
- AlicenseNot gradedqualityCmaintenanceExposes Django REST Framework APIs as MCP tools for AI agents via the Model Context Protocol, with automatic discovery and security.17 PyPI1MIT
- AlicenseNot gradedqualityAmaintenanceA Django-native MCP application and tool registration framework inspired by Celery, providing async tool definitions, autodiscovery, and stdio/Streamable HTTP serving built on the official MCP Python SDK.2MIT