Django MCP Server is a Django extension to easily enable AI Agents to interact with Django Apps through the Model Context Protocol. It works equally well on WSGI and ASGI.
This is a Django MCP framework/example server with significant quality gaps. The server exposes 14 tools, many with adequate schemas but with serious naming conflicts, incomplete descriptions, and security/composition concerns. Of the 14 tools, 6 are read-only model queries with minimal description variation, 2 tools have identical names/purposes (delete_location, delete_location_viewset; list_locations, list_locations_viewset), and 4 are CRUD operations with varying quality. Tool descriptions range from generic ('ModelQueryToolset for querying X model') to moderately helpful ('Increment the count of a bird species by a specified amount and returns the new count'). Parameter schemas are present for all tools but descriptions are sparse or absent for aggregation pipeline parameters. No tool has error handling guidance, no tool declares required permissions, and the composition includes problematic duplicates that force LLM disambiguation. STDIO transport caps the overall score despite adequate schema coverage.
ModelQueryToolset for querying Bird model with CSV output format
ModelQueryToolset for querying City model
ModelQueryToolset for querying City model
ModelQueryToolset for querying Location model
ModelQueryToolset for querying Location model
API endpoint to create a Location instance
A tool to delete a location
Duplicate tools with unclear distinction. delete_location and delete_location_viewset perform the same action; list_locations and list_locations_viewset are identical in purpose. This forces LLMs to disambiguate between functionally equivalent tools, wasting reasoning and inviting wrong tool selection.
Generic, non-descriptive names and descriptions for aggregation query tools. 'LocationTool', 'LocationQuery', 'CityTool', 'CityQuery' are generic and do not clearly distinguish purpose. Description 'ModelQueryToolset for querying Location model' is vague; LLMs cannot infer when to use LocationTool vs LocationQuery. No mention of whether these support filtering, pagination, sorting, or return format.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 31 | - | v1 |
Another tool to delete a location
Get the latest bird news
Find the ID of a bird species by its name or part of name. Returns the count
Increment the count of a bird species by a specified amount and returns the new count. The first argument is the species name, the second is the amount to increment with (1) by default.
A tool to list all locations
Another tool to list all locations
API endpoint to retrieve, update or delete a Location instance
Parameter 'pipeline' lacks clear description. Documented only as 'MongoDB-style aggregation pipeline for querying' with no guidance on valid stages, required structure, or expected format. LLMs cannot understand what to pass without studying external pipeline DSL spec (PIPELINE_DSL_SPEC in code). Parameter description should include allowed stages and simple examples.
No error handling guidance in any tool description. When a query fails (invalid pipeline, missing field, permission denied), there is no recovery hint. LLMs receive raw errors and cannot self-correct.
Destructive tools (delete_location, delete_location_viewset) lack confirmation or dry-run capability. No description warns of irreversible side effects. Agents can accidentally delete records without safety gate.
No permission declarations or scope hints. Tools like delete_location do not document required permissions (e.g., 'requires write:location'). No audit trail or logging configuration visible to declare which operations are logged.
Query tools return all fields from models. No pagination or result limiting documented. Returning unbounded result sets (e.g., all locations, all cities) risks context window exhaustion and token waste. Descriptions do not mention pagination support or result caps.
'delete_location_viewset' and 'list_locations_viewset' have poor naming. '_viewset' suffix is an implementation detail (Django REST Framework term) not a user-facing concept. This exposes internal framework structure and forces LLMs to reason about framework internals.
Output schemas not documented in tool descriptions. Callers cannot know what fields the response will contain. For example, does 'increment_species' return {name, count} or {id, species_name, count, timestamp}? LLMs must guess or trial-and-error.