MCP server providing comprehensive Django Unfold documentation for AI agents
Project description
๐ฎ MCP Django Unfold
A Model Context Protocol (MCP) server that gives AI agents complete, accurate knowledge of the Django Unfold admin theme โ so they can implement it without hallucination.
Built with the MCP Python SDK (FastMCP), this server exposes 25 documentation tools covering every feature, configuration option, and third-party integration of Django Unfold. Compatible with Claude Desktop, VS Code GitHub Copilot, Cursor, and any MCP-compatible client.
๐ Table of Contents
- Why This Exists
- Architecture
- Project Structure
- Quick Start
- Client Configuration
- Available Tools
- How It Was Built
- Development Guide
- Production Deployment
- Dev โ Prod Pipeline
- Contributing
- License
๐ก Why This Exists
AI coding agents (Claude, Copilot, Cursor) frequently hallucinate when generating Django Unfold code โ inventing non-existent settings, using wrong import paths, or missing critical ordering requirements in INSTALLED_APPS. This MCP server solves that by providing:
- Verified documentation โ every code example is sourced directly from the official Django Unfold docs
- Complete coverage โ 24 documentation sections spanning installation to advanced integrations
- Instant access โ AI agents call tools and get authoritative answers in milliseconds
- Search โ full-text search across all documentation sections
๐๏ธ Architecture
System Overview
%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#6366f1', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#818cf8', 'lineColor': '#a5b4fc', 'secondaryColor': '#1e1b4b', 'tertiaryColor': '#312e81', 'background': '#0f0d1a', 'mainBkg': '#1e1b4b', 'nodeBorder': '#818cf8', 'clusterBkg': '#1a1744', 'clusterBorder': '#4f46e5', 'titleColor': '#ffffff', 'edgeLabelBackground': '#1e1b4b', 'textColor': '#e0e7ff', 'noteTextColor': '#ffffff', 'noteBkgColor': '#312e81'}}}%%
flowchart TB
subgraph clients["๐ฅ๏ธ MCP Clients"]
direction LR
claude["Claude Desktop"]
vscode["VS Code Copilot"]
cursor["Cursor / Other IDE"]
custom["Custom MCP Client"]
end
subgraph transport["๐ก Transport Layer"]
stdio["stdio (stdin/stdout)"]
end
subgraph server["โ๏ธ MCP Server โ mcp-django-unfold"]
direction TB
fastmcp["FastMCP Runtime\n(mcp Python SDK)"]
subgraph tools["๐ง 25 Documentation Tools"]
direction LR
core["Core Tools\nโโโโโโโโโ\nunfold_get_started\nunfold_configuration\nunfold_actions\nunfold_filters\nunfold_decorators"]
ui["UI Tools\nโโโโโโโโโ\nunfold_components\nunfold_inlines\nunfold_widgets\nunfold_tabs\nunfold_dashboard"]
adv["Advanced Tools\nโโโโโโโโโ\nunfold_pages\nunfold_styles_scripts\nunfold_features_overview\nunfold_complete_example\nunfold_search_docs"]
integ["Integration Tools\nโโโโโโโโโ\nimport_export\nguardian\nsimple_history\ncelery_beat\nmodeltranslation\nmoney ยท constance\nlocation ยท djangoql\njson_widget"]
end
subgraph docs["๐ Documentation Store"]
docsmod["docs.py\nโโโโโโโโโ\nDOCS dict\n24 sections\nFull code examples"]
end
end
clients -->|"JSON-RPC over stdio"| transport
transport --> fastmcp
fastmcp --> tools
tools --> docs
style clients fill:#1e1b4b,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style transport fill:#312e81,stroke:#818cf8,stroke-width:2px,color:#e0e7ff
style server fill:#0f172a,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style tools fill:#1a1744,stroke:#4f46e5,stroke-width:1px,color:#e0e7ff
style docs fill:#1a1744,stroke:#4f46e5,stroke-width:1px,color:#e0e7ff
style claude fill:#312e81,stroke:#818cf8,color:#ffffff
style vscode fill:#312e81,stroke:#818cf8,color:#ffffff
style cursor fill:#312e81,stroke:#818cf8,color:#ffffff
style custom fill:#312e81,stroke:#818cf8,color:#ffffff
style stdio fill:#312e81,stroke:#818cf8,color:#ffffff
style fastmcp fill:#4f46e5,stroke:#818cf8,color:#ffffff
style core fill:#312e81,stroke:#6366f1,color:#e0e7ff
style ui fill:#312e81,stroke:#6366f1,color:#e0e7ff
style adv fill:#312e81,stroke:#6366f1,color:#e0e7ff
style integ fill:#312e81,stroke:#6366f1,color:#e0e7ff
style docsmod fill:#312e81,stroke:#6366f1,color:#e0e7ff
Request Flow
%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#6366f1', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#818cf8', 'lineColor': '#a5b4fc', 'secondaryColor': '#1e1b4b', 'tertiaryColor': '#312e81', 'background': '#0f0d1a', 'mainBkg': '#1e1b4b', 'nodeBorder': '#818cf8', 'clusterBkg': '#1a1744', 'clusterBorder': '#4f46e5', 'titleColor': '#ffffff', 'edgeLabelBackground': '#1e1b4b', 'textColor': '#e0e7ff'}}}%%
sequenceDiagram
participant C as ๐ฅ๏ธ AI Client
participant T as ๐ก stdio Transport
participant S as โ๏ธ FastMCP Server
participant TM as ๐ง Tool Manager
participant D as ๐ Docs Store
Note over C,D: Tool Discovery Phase
C->>T: initialize request
T->>S: JSON-RPC handshake
S-->>T: server capabilities (25 tools)
T-->>C: tool list + descriptions
Note over C,D: Tool Invocation Phase
C->>T: tools/call: unfold_configuration
T->>S: dispatch to handler
S->>TM: lookup "unfold_configuration"
TM->>D: DOCS["configuration"]
D-->>TM: full markdown content
TM-->>S: documentation string
S-->>T: tool result (content)
T-->>C: configuration docs
Note over C,D: Search Phase
C->>T: tools/call: unfold_search_docs("sidebar")
T->>S: dispatch to handler
S->>TM: lookup "unfold_search_docs"
TM->>D: scan ALL_SECTIONS for "sidebar"
D-->>TM: matching sections
TM-->>S: aggregated results
S-->>T: tool result (matches)
T-->>C: search results
๐ Project Structure
%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#6366f1', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#818cf8', 'lineColor': '#a5b4fc', 'secondaryColor': '#1e1b4b', 'tertiaryColor': '#312e81', 'background': '#0f0d1a', 'mainBkg': '#1e1b4b', 'nodeBorder': '#818cf8', 'clusterBkg': '#1a1744', 'clusterBorder': '#4f46e5', 'titleColor': '#ffffff', 'edgeLabelBackground': '#1e1b4b', 'textColor': '#e0e7ff'}}}%%
graph TB
subgraph root["๐ฆ mcp-django-unfold/"]
pyproject["pyproject.toml\nโโโโโโโโโ\nname ยท version\ndependencies\nentry point\nhatch build"]
dockerfile["Dockerfile\nโโโโโโโโโ\npython:3.12-slim\npip install\nENTRYPOINT"]
readme["README.md"]
lock["uv.lock"]
subgraph src["src/mcp_django_unfold/"]
init["__init__.py\nโโโโโโโโโ\n__version__"]
server_py["server.py\nโโโโโโโโโ\nFastMCP init\n25 @mcp.tool()\nmain() entry"]
docs_py["docs.py\nโโโโโโโโโ\nDOCS dict\n24 doc sections\nALL_SECTIONS list"]
end
end
pyproject -->|"entry point"| server_py
server_py -->|"imports"| docs_py
server_py -->|"imports"| init
dockerfile -->|"pip install ."| pyproject
style root fill:#0f172a,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style src fill:#1a1744,stroke:#4f46e5,stroke-width:2px,color:#e0e7ff
style pyproject fill:#312e81,stroke:#818cf8,color:#ffffff
style dockerfile fill:#312e81,stroke:#818cf8,color:#ffffff
style readme fill:#312e81,stroke:#818cf8,color:#ffffff
style lock fill:#312e81,stroke:#818cf8,color:#ffffff
style init fill:#4f46e5,stroke:#818cf8,color:#ffffff
style server_py fill:#4f46e5,stroke:#a78bfa,stroke-width:2px,color:#ffffff
style docs_py fill:#4f46e5,stroke:#a78bfa,stroke-width:2px,color:#ffffff
mcp-django-unfold/
โโโ pyproject.toml # Package metadata, dependencies, build config
โโโ Dockerfile # Container image for production
โโโ .dockerignore # Docker build exclusions
โโโ .gitignore # Git exclusions
โโโ README.md # This file
โโโ LICENSE # MIT license
โโโ uv.lock # Dependency lock file
โโโ src/
โโโ mcp_django_unfold/
โโโ __init__.py # Package init + version
โโโ server.py # FastMCP server + 25 tool definitions
โโโ docs.py # Complete documentation content (24 sections)
| File | Purpose |
|---|---|
server.py |
FastMCP server initialization, all 25 @mcp.tool() handlers, and main() entry point |
docs.py |
DOCS dictionary containing 24 full documentation sections with code examples |
pyproject.toml |
Package name, version, Python โฅ3.11, mcp[cli] dependency, hatchling build |
Dockerfile |
Production-ready container using python:3.12-slim |
๐ Quick Start
Option 1: uvx (recommended โ zero install)
uvx mcp-django-unfold
Option 2: pip install
pip install mcp-django-unfold
mcp-django-unfold
Option 3: Docker
docker build -t mcp-django-unfold .
docker run -i --rm mcp-django-unfold
โ๏ธ Client Configuration
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"django-unfold": {
"command": "uvx",
"args": ["mcp-django-unfold"]
}
}
}
VS Code (GitHub Copilot)
Add to your project's .vscode/mcp.json:
{
"servers": {
"django-unfold": {
"command": "uvx",
"args": ["mcp-django-unfold"]
}
}
}
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"django-unfold": {
"command": "uvx",
"args": ["mcp-django-unfold"]
}
}
}
Docker-based Configuration
For any client that supports Docker:
{
"mcpServers": {
"django-unfold": {
"command": "docker",
"args": ["run", "-i", "--rm", "mcp-django-unfold"]
}
}
}
๐ง Available Tools
Core Documentation
| Tool | Description |
|---|---|
unfold_get_started |
Installation, INSTALLED_APPS ordering, ModelAdmin setup |
unfold_configuration |
Complete UNFOLD settings dict โ every option with examples |
unfold_actions |
Global, row, detail & submit line actions with icons/variants |
unfold_filters |
Dropdown, numeric, date, text, autocomplete filters |
unfold_decorators |
@display decorator โ labels, headers, dropdowns |
UI & Layout
| Tool | Description |
|---|---|
unfold_components |
Dashboard components โ card, chart, button, table, progress... |
unfold_inlines |
Stacked, tabular, nonrelated & sortable inlines |
unfold_widgets |
Form widgets โ ArrayWidget, switches, WYSIWYG, all input types |
unfold_tabs |
Changelist tab navigation |
unfold_dashboard |
Custom dashboard with DASHBOARD_CALLBACK |
unfold_pages |
Custom admin pages with class-based views |
unfold_styles_scripts |
Custom CSS/JS, Tailwind 3.x & 4.x setup |
Third-party Integrations
| Tool | Description |
|---|---|
unfold_integration_import_export |
django-import-export forms and admin setup |
unfold_integration_guardian |
django-guardian object-level permissions |
unfold_integration_simple_history |
django-simple-history model tracking |
unfold_integration_celery_beat |
django-celery-beat task scheduling admin |
unfold_integration_modeltranslation |
django-modeltranslation with language flags |
unfold_integration_money |
django-money (auto-styled) |
unfold_integration_constance |
django-constance dynamic settings |
unfold_integration_location_field |
django-location-field map widget |
unfold_integration_djangoql |
djangoql advanced search (auto-styled) |
unfold_integration_json_widget |
django-json-widget (auto-styled) |
Meta
| Tool | Description |
|---|---|
unfold_features_overview |
Complete feature list and technology stack |
unfold_complete_example |
Full working project โ settings, models, admin, templates |
unfold_search_docs |
Full-text search across all 24 documentation sections |
๐งฑ How It Was Built
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Protocol | Model Context Protocol | Standardized AI โ tool communication |
| SDK | mcp Python SDK (FastMCP) | Server framework with @mcp.tool() decorator pattern |
| Transport | stdio (stdin/stdout) | Local process communication โ fast, no network overhead |
| Build | Hatchling | Modern Python build backend |
| Runtime | Python โฅ 3.11 | Type hints, modern syntax |
| Package | uvx / pip | Zero-install execution via uvx |
| Container | Docker (python:3.12-slim) |
Production-ready deployment |
Design Decisions
-
Embedded documentation โ All docs are stored as Python strings in
docs.pyrather than fetched at runtime. This ensures zero latency, offline operation, and version-locked accuracy. -
One tool per topic โ Each documentation section gets its own MCP tool with a descriptive docstring. AI agents can discover and call exactly the tool they need.
-
Full-text search โ The
unfold_search_docstool scans all sections by keyword, so agents can find relevant docs even when they don't know the exact tool name. -
stdio transport โ Chosen for local-first usage. The server starts as a child process of the AI client โ no ports, no network config, no auth needed.
-
src layout โ Standard Python packaging layout (
src/mcp_django_unfold/) with hatchling build for clean wheel generation and PyPI publishing.
๐ ๏ธ Development Guide
Prerequisites
- Python 3.11+
- uv (recommended) or pip
Setup
# Clone the repository
git clone https://github.com/danangharissetiawan/mcp-django-unfold.git
cd mcp-django-unfold
# Install dependencies in a virtual environment
uv sync
Run Locally
# Run the server directly
uv run mcp-django-unfold
Test with MCP Inspector
The MCP Inspector lets you interactively browse and call tools:
npx @modelcontextprotocol/inspector uv run mcp-django-unfold
This opens a web UI where you can:
- See all 25 registered tools
- Read each tool's description and parameters
- Execute tools and inspect the returned documentation
Verify the Server
# Quick smoke test โ check tools load
uv run python -c "
from mcp_django_unfold.server import mcp
print(f'Server: {mcp.name}')
print(f'Tools: {len(mcp._tool_manager._tools)}')
"
# Expected output:
# Server: django_unfold_mcp
# Tools: 25
Adding Documentation
- Add a new section to the
DOCSdictionary insrc/mcp_django_unfold/docs.py - Create a corresponding
@mcp.tool()function insrc/mcp_django_unfold/server.py - The search tool (
unfold_search_docs) will automatically index the new section
Code Style
# Format
uv run ruff format src/
# Lint
uv run ruff check src/
๐ข Production Deployment
Publish to PyPI
# Build the package
uv build
# This creates dist/mcp_django_unfold-0.1.0.tar.gz and .whl
# Upload to PyPI
uv publish
# Or with twine:
# twine upload dist/*
Once published, anyone can run it instantly:
uvx mcp-django-unfold
Docker
# Build
docker build -t mcp-django-unfold .
# Run (interactive mode required for stdio)
docker run -i --rm mcp-django-unfold
# Tag and push to a registry
docker tag mcp-django-unfold ghcr.io/danangharissetiawan/mcp-django-unfold:latest
docker push ghcr.io/danangharissetiawan/mcp-django-unfold:latest
Version Bump Workflow
- Update
versioninpyproject.toml - Update
__version__insrc/mcp_django_unfold/__init__.py - Commit, tag, and push:
git add -A
git commit -m "release: v0.2.0"
git tag v0.2.0
git push origin main --tags
- Build and publish:
uv build && uv publish
๐ Dev โ Prod Pipeline
%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#6366f1', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#818cf8', 'lineColor': '#a5b4fc', 'secondaryColor': '#1e1b4b', 'tertiaryColor': '#312e81', 'background': '#0f0d1a', 'mainBkg': '#1e1b4b', 'nodeBorder': '#818cf8', 'clusterBkg': '#1a1744', 'clusterBorder': '#4f46e5', 'titleColor': '#ffffff', 'edgeLabelBackground': '#1e1b4b', 'textColor': '#e0e7ff'}}}%%
graph LR
subgraph dev["๐ ๏ธ Development"]
code["Write Code"]
test["Test with\nMCP Inspector"]
local["Run Local\nuv run mcp-django-unfold"]
end
subgraph build["๐ฆ Build & Publish"]
hatch["uv build\n.tar.gz + .whl"]
twine["uv publish\nto PyPI"]
docker_build["docker build\n-t mcp-django-unfold ."]
end
subgraph prod["๐ Production Use"]
uvx["uvx mcp-django-unfold"]
pip_install["pip install\nmcp-django-unfold"]
docker_run["docker run -i --rm\nmcp-django-unfold"]
end
code --> test
test --> local
local -->|"ready"| hatch
hatch --> twine
hatch --> docker_build
twine --> uvx
twine --> pip_install
docker_build --> docker_run
style dev fill:#1a1744,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style build fill:#1a1744,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style prod fill:#1a1744,stroke:#6366f1,stroke-width:2px,color:#e0e7ff
style code fill:#312e81,stroke:#818cf8,color:#ffffff
style test fill:#312e81,stroke:#818cf8,color:#ffffff
style local fill:#312e81,stroke:#818cf8,color:#ffffff
style hatch fill:#4f46e5,stroke:#818cf8,color:#ffffff
style twine fill:#4f46e5,stroke:#818cf8,color:#ffffff
style docker_build fill:#4f46e5,stroke:#818cf8,color:#ffffff
style uvx fill:#059669,stroke:#34d399,stroke-width:2px,color:#ffffff
style pip_install fill:#059669,stroke:#34d399,stroke-width:2px,color:#ffffff
style docker_run fill:#059669,stroke:#34d399,stroke-width:2px,color:#ffffff
| Stage | Command | What Happens |
|---|---|---|
| Dev | uv sync |
Install deps locally in .venv |
| Dev | uv run mcp-django-unfold |
Run server for local testing |
| Dev | npx @modelcontextprotocol/inspector ... |
Interactive tool browser |
| Build | uv build |
Generate .tar.gz + .whl in dist/ |
| Publish | uv publish |
Upload to PyPI |
| Prod | uvx mcp-django-unfold |
Zero-install run from PyPI |
| Prod | docker run -i --rm mcp-django-unfold |
Containerized run |
๐ค Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feat/new-docs-section - Make your changes to
docs.pyandserver.py - Test with MCP Inspector
- Submit a pull request
๐ License
MIT โ see LICENSE for details.
Built with โค๏ธ for the Django Unfold community
Django Unfold ยท Model Context Protocol ยท MCP Python SDK
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 mcp_django_unfold-0.1.0.tar.gz.
File metadata
- Download URL: mcp_django_unfold-0.1.0.tar.gz
- Upload date:
- Size: 64.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cba631ecab3ac263dbe396d932bb4a590a452b4c579e1ad0d5a19b6d95de2817
|
|
| MD5 |
600ea5a4196daf3171c6ecc9b218d31a
|
|
| BLAKE2b-256 |
2f7538ffe7f37a49bbf07e9b25f1f635358cc31f6767aa43e441430724f37f89
|
File details
Details for the file mcp_django_unfold-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_django_unfold-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac2c5538794ac52acf5b41b9ba70b13ff48fb67fa0114297744f40a053883214
|
|
| MD5 |
2e7f013d3217e87dd0878468e42f1e55
|
|
| BLAKE2b-256 |
1ca2b17584a6f52472ffd07549ff0c3c08ee1a21e52c580164d98445769e98ad
|