Settings¶
Every key lives in a single REST_FRAMEWORK_MCP dict in your Django settings.
All of them are optional — the defaults below apply when a key is absent.
# settings.py
REST_FRAMEWORK_MCP = {
"ALLOWED_ORIGINS": ["https://app.example.com"],
"REQUIRE_TOOL_PERMISSIONS": True,
}
Reading an unknown key raises KeyError, so a typo surfaces immediately rather
than silently taking a default.
These settings are per-project defaults. Every scalar below can be overridden per server, which is what you want as soon as you mount more than one:
Collaborators are not configured here at all — the auth backend, session
store, SSE broker, server identity and resource URL are passed to
MCPServer(...) in urls.py, because a settings dict can't hold a live
object. Three keys that once named a collaborator by dotted path were removed
and now raise ImproperlyConfigured if still present: AUTH_BACKEND,
SESSION_STORE, AUTH_USER_ADAPTER.
Protocol¶
| Key | Default | What it does |
|---|---|---|
PROTOCOL_VERSIONS |
["2025-11-25", "2025-06-18"] |
Accepted MCP-Protocol-Version values. The first entry is the fallback when the header is absent and not required. |
REQUIRE_PROTOCOL_VERSION_HEADER |
True |
Reject a post-initialize request that omits MCP-Protocol-Version (HTTP 400). Set False for clients that never send it. A header that is present but unsupported is rejected either way — downgrading silently there would mask a real version mismatch. |
SERVER_INFO |
{"name": "djangorestframework-mcp-server"} |
Default serverInfo for initialize. Prefer per-server identity: MCPServer(name=…, version=…, title=…). |
Transport & security¶
| Key | Default | What it does |
|---|---|---|
ALLOWED_ORIGINS |
[] |
Origin allowlist, enforced on every request (mandatory per the MCP spec). ["*"] allows any origin — local development only. |
MAX_REQUEST_BYTES |
1048576 (1 MiB) |
Maximum accepted request body size. |
RESOURCE_URL |
None |
Canonical resource URL for RFC 8707 audience enforcement; None disables it. This is only the default for MCPServer(resource_url=…) — RFC 8707 binds a token to a resource, so each server needs its own URL. Two servers sharing one URL means a token minted for one passes the audience check at the other, which is the exact replay the mechanism prevents. Set it per server; leave this key for the single-server case. |
Tools & output¶
| Key | Default | What it does |
|---|---|---|
DEFAULT_OUTPUT_FORMAT |
"json" |
Format of a tool result's human-readable content[0] text for tools that don't set one: "json", "toon", or "auto" (TOON for uniform lists, JSON otherwise). structuredContent is always JSON. Per-tool output_format= wins. See Ship TOON for large lists. |
INCLUDE_STRUCTURED_CONTENT |
True |
Emit structuredContent on tool results. |
INCLUDE_OUTPUT_SCHEMA |
True |
Advertise outputSchema on tool definitions. |
INCLUDE_VALIDATION_VALUE |
False |
Include the offending arguments dict under data.value in validation errors. Off by default — that dict can carry PII or secrets, which would then flow back to the client and into its logs. |
PAGE_SIZE |
100 |
Maximum items returned by one listing call (tools/list, resources/list, resources/templates/list, prompts/list). Clients page with the opaque cursor echoed in the response. |
One combination is a spec violation
INCLUDE_STRUCTURED_CONTENT and INCLUDE_OUTPUT_SCHEMA are independent,
but advertising outputSchema while suppressing structuredContent is
forbidden by the spec and raises ImproperlyConfigured at request time. If
you turn INCLUDE_STRUCTURED_CONTENT off, turn INCLUDE_OUTPUT_SCHEMA off
too (or set include_output_schema=False per binding). The other direction
— structuredContent without outputSchema — is allowed.
Permissions¶
| Key | Default | What it does |
|---|---|---|
REQUIRE_TOOL_PERMISSIONS |
False |
Registering a tool with no permissions at all (neither spec.permission_classes nor permissions=[…]) raises ImproperlyConfigured instead of emitting UnguardedToolWarning. The warning exists because guarding the viewset — or relying on REST_FRAMEWORK's default permission classes — has no effect over MCP: this package bypasses DRF's view-layer pipeline, so a spec that looks guarded over HTTP ships as an unguarded tool. See Authentication. |
REQUIRE_TOOL_DESCRIPTIONS |
False |
Registering a tool with no description raises ImproperlyConfigured instead of emitting UndescribedToolWarning. The description is the only thing a model reads to decide whether and how to call a tool, so an empty one ships a tool that cannot be used correctly — and tools/list renders it indistinguishably from a documented one. There is deliberately no docstring fallback: a docstring is written for the next developer, not for a model choosing between tools. See Documenting tools. |
FILTER_LISTINGS_BY_PERMISSIONS |
False |
Drop bindings whose permissions deny the caller from tools/list, resources/list, resources/templates/list and prompts/list. Per-binding always_listed=True opts one back in as a discovery aid. |
OAuth¶
| Key | Default | What it does |
|---|---|---|
DCR_ENABLED |
False |
Default for build_oauth_urlpatterns(dcr_enabled=). RFC 7591 dynamic client registration; False makes /oauth/register/ refuse every request with 403. An open DCR endpoint lets anyone create an OAuth client against your authorization server. |
DCR_INITIAL_ACCESS_TOKEN |
None |
Default for build_oauth_urlpatterns(dcr_initial_access_token=). The RFC 7591 §3 initial access token clients must present as Authorization: Bearer …. None means no token check — anyone who can reach the endpoint can register. |
SIMPLEJWT_ACCESS_COOKIE |
"access" |
Default for SimpleJWTCookieAdapter(cookie_name=) ([jwt] extra) — the cookie it reads access tokens from. Matches djangorestframework-simplejwt's documented AUTH_COOKIE default. |
Observability¶
| Key | Default | What it does |
|---|---|---|
RECORD_SERVICE_EXCEPTIONS |
False |
Record a ServiceError raised from a tool callable on the active OpenTelemetry span before mapping it to a JSON-RPC error. Off by default because services often raise ServiceError for routine business-rule denials, which would flood error pipelines. ServiceValidationError is never recorded — it is client input failure, not a server fault. See Observability. |