Skip to main content

MCP server providing comprehensive Django Unfold documentation for AI agents

Project description

PyPI version Python versions MCP Compatible License

๐Ÿ”ฎ 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

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

  1. Embedded documentation โ€” All docs are stored as Python strings in docs.py rather than fetched at runtime. This ensures zero latency, offline operation, and version-locked accuracy.

  2. 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.

  3. Full-text search โ€” The unfold_search_docs tool scans all sections by keyword, so agents can find relevant docs even when they don't know the exact tool name.

  4. 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.

  5. 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

  1. Add a new section to the DOCS dictionary in src/mcp_django_unfold/docs.py
  2. Create a corresponding @mcp.tool() function in src/mcp_django_unfold/server.py
  3. 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

  1. Update version in pyproject.toml
  2. Update __version__ in src/mcp_django_unfold/__init__.py
  3. Commit, tag, and push:
git add -A
git commit -m "release: v0.2.0"
git tag v0.2.0
git push origin main --tags
  1. 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

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/new-docs-section
  3. Make your changes to docs.py and server.py
  4. Test with MCP Inspector
  5. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_django_unfold-0.1.0.tar.gz (64.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_django_unfold-0.1.0-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

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

Hashes for mcp_django_unfold-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cba631ecab3ac263dbe396d932bb4a590a452b4c579e1ad0d5a19b6d95de2817
MD5 600ea5a4196daf3171c6ecc9b218d31a
BLAKE2b-256 2f7538ffe7f37a49bbf07e9b25f1f635358cc31f6767aa43e441430724f37f89

See more details on using hashes here.

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

Hashes for mcp_django_unfold-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac2c5538794ac52acf5b41b9ba70b13ff48fb67fa0114297744f40a053883214
MD5 2e7f013d3217e87dd0878468e42f1e55
BLAKE2b-256 1ca2b17584a6f52472ffd07549ff0c3c08ee1a21e52c580164d98445769e98ad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page