MCP (Model Context Protocol) adapter for django-admin-rest-api. A wire-protocol-only layer that lets agents reach the existing REST API — no new functionality, permissions, or validation.
Project description
django-admin-mcp-api
The Model Context Protocol adapter for the Django admin.
Let AI agents drive your ModelAdmin — with your existing auth, permissions, and validation.
Install in 30 seconds
pip install django-admin-mcp-api
# settings.py
INSTALLED_APPS += [
"django_admin_rest_api",
"django_admin_mcp_api",
]
# urls.py
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("django_admin_rest_api.urls")), # REST
path("mcp/", include("django_admin_mcp_api.urls")), # MCP
]
Your admin now answers JSON-RPC at POST /mcp/. Same session, same CSRF,
same permissions. Agents can list, retrieve, create, update, destroy,
run actions, autocomplete, browse history, and more — through one
endpoint your ModelAdmin already controls.
Why use it
- Plug-and-play. Three lines in
settings.py, oneinclude()inurls.py. Nothing else to configure. - Same admin, new surface. Reuses your
ModelAdminas the only source of truth for permissions, querysets, forms, and serialization. The MCP layer adds zero new functionality. - Auth that already works. Django session + CSRF +
AdminSite.has_permission. No tokens, no parallel permission system, no surprises. - Schema-validated. Every
tools/callis validated against the tool's JSON Schema before it reaches your database. Malformed calls fail fast with a json-pointer path of the offending field. - Stable contract. Wire shape is semver-protected (
docs/api-contract.md§7). Backward-compatible additions only until v2. - 74 tests, 91% coverage. Includes end-to-end integration against the real REST API.
How it fits
django-admin-mcp-api is one of three sibling packages that share the
same admin core. Pick the protocol that fits your client:
| Package | Protocol | PyPI | When to use it |
|---|---|---|---|
django-admin-react |
React SPA over HTTP/JSON | django-admin-react |
A humans-and-mice frontend that replaces the HTML admin. |
django-admin-rest-api |
HTTP REST/JSON | django-admin-rest-api 1.0.0 |
A REST surface for non-Django clients or other UIs. |
django-admin-mcp-api (this repo) |
MCP JSON-RPC | django-admin-mcp-api 1.0.0 |
An MCP server for AI agents (Claude, Cursor, custom). |
All three reuse your existing ModelAdmin. No fork, no parallel models, no migrations.
The 16 tools
Each MCP tool is a 1:1 mirror of a django-admin-rest-api endpoint —
that's the whole design.
| MCP tool | What it does | rest-api endpoint |
|---|---|---|
admin.registry |
List every model the user can see | GET /api/v1/registry/ |
admin.schema |
Full admin metadata schema | GET /api/v1/schema/ |
admin.recent_actions |
The user's own LogEntry feed |
GET /api/v1/recent-actions/ |
admin.list |
A page of list-view results | GET /api/v1/<app>/<model>/ |
admin.retrieve |
A single object's detail view | GET /api/v1/<app>/<model>/<pk>/ |
admin.add_form |
Create-page field descriptors | GET /api/v1/<app>/<model>/add/ |
admin.create |
Create one object | POST /api/v1/<app>/<model>/ |
admin.update |
Partial-update one object | PATCH /api/v1/<app>/<model>/<pk>/ |
admin.destroy |
Delete one object | DELETE /api/v1/<app>/<model>/<pk>/ |
admin.bulk_update |
Apply the same patch to many objects | PATCH /api/v1/<app>/<model>/bulk/ |
admin.autocomplete |
Autocomplete a related model | GET /api/v1/<app>/<model>/autocomplete/ |
admin.action |
Run a ModelAdmin.actions action |
POST /api/v1/<app>/<model>/actions/<name>/ |
admin.history |
One object's LogEntry timeline |
GET /api/v1/<app>/<model>/<pk>/history/ |
admin.delete_preview |
Cascade preview before a destroy | GET /api/v1/<app>/<model>/<pk>/delete-preview/ |
admin.set_password |
Set/change a user-like password | POST /api/v1/<app>/<model>/<pk>/password/ |
admin.panel |
A custom panel registered on the ModelAdmin |
GET /api/v1/<app>/<model>/<pk>/panel/<name>/ |
The wire-format details are in docs/api-contract.md.
See it run
Captured against the examples/quickstart/
demo — a fresh pip install, runserver, and python smoke.py. No
mocks. No stubs.
// POST /mcp/ method=initialize
{
"jsonrpc": "2.0", "id": 1,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": { "name": "django-admin", "version": "1.0.0" },
"capabilities": { "tools": { "listChanged": false } }
}
}
// POST /mcp/ method=tools/call name=admin.registry
{
"jsonrpc": "2.0", "id": 1,
"result": {
"content": [{ "type": "json", "json": {
"user": { "id": 1, "username": "admin", "is_staff": true },
"apps": [
{ "app_label": "auth",
"models": [
{ "model_name": "group",
"permissions": { "view": true, "add": true, "change": true, "delete": true } },
{ "model_name": "user",
"permissions": { "view": true, "add": true, "change": true, "delete": true } }
] }
]
} }],
"isError": false,
"status": 200
}
}
The permissions block above comes straight from
ModelAdmin.has_*_permission — the MCP layer doesn't decide a thing
about authorization. That's the prime directive.
What this package will never do
- ❌ Add a new permission system.
- ❌ Bypass CSRF or session auth.
- ❌ Add a feature that isn't in
django-admin-rest-api. - ❌ Touch the database or call
user.has_perm().
If a behaviour isn't in django-admin-rest-api, it isn't here. Period.
That rule is enforced by pre-commit hooks and the test suite (see
tests/test_security.py).
Security at a glance
| Default | Status |
|---|---|
Anonymous request → 401 |
enforced in server/views.py::_auth_gate |
Non-staff request → 403 |
enforced in server/views.py::_auth_gate |
CSRF on POST /mcp/ |
enforced by Django middleware; no view bypasses |
Schema validation on tools/call |
jsonschema Draft 2020-12 against each tool |
No csrf_exempt / no objects.all() / no user.has_perm |
pygrep pre-commit hooks + test suite |
| No token-shaped strings in the repo | gitleaks + pygrep + test suite |
| Bandit, pip-audit, ruff, black, isort, flake8, pylint, mypy | green on every PR via CI |
Full set of invariants: SECURITY.md. Threat model:
docs/threat-model.md. Report a vulnerability
privately here.
Contribute
poetry install
poetry run pytest
poetry run bash scripts/lint.sh
PRs welcome — see CONTRIBUTING.md and the agent contract in CLAUDE.md. The roadmap lives on the project board.
License
MIT — © 2026 Martín Castro Alvarez and django-admin-mcp contributors.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_admin_mcp_api-1.0.0.tar.gz.
File metadata
- Download URL: django_admin_mcp_api-1.0.0.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.7 Darwin/23.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15823d68225af22a5a60f411e0a0c7c0819266e9a8942c8c323dd4bb491ce9d2
|
|
| MD5 |
4b35bd8755e0c1488bb75fd231b6b920
|
|
| BLAKE2b-256 |
e60e03e03b2937c596b660ec08c4f027d58c17a6ca78cf493373aa7f69457e02
|
File details
Details for the file django_admin_mcp_api-1.0.0-py3-none-any.whl.
File metadata
- Download URL: django_admin_mcp_api-1.0.0-py3-none-any.whl
- Upload date:
- Size: 37.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.7 Darwin/23.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53012f99bcab3e2ee49d875185402a7d85122fccd46c1d16822195426d5a487e
|
|
| MD5 |
82c9df7fdaafb018268726b4d008917b
|
|
| BLAKE2b-256 |
33f7d8b61e4105b0a9f48d4bc55c39820ac9a76a85ed7d8a0fca1f49217e9e49
|