Skip to main content

Static analysis + MCP server for Django models. Sidebar tree, ER diagrams, and JSON output for terminals and AI coding agents.

Project description

django-orm-lens

PyPI Python Downloads License

Static analysis + MCP server for Django models. Terminal- and AI-agent-friendly.

Listed in the official MCP Registry as io.github.FROWNINGdev/django-orm-lens.

Ships with a zero-dependency parser, a JSON/Markdown/table CLI, and an optional MCP (Model Context Protocol) server so any AI coding agent — Cursor, Aider, Continue, and any other MCP client — can navigate your Django schema without importing Django or spinning up your app.

Companion to the Django ORM Lens VS Code extension.


Install

# Core CLI (zero third-party deps)
pip install django-orm-lens

# With the MCP server (adds the `mcp` package)
pip install "django-orm-lens[mcp]"

Requires Python 3.9+. Works on Linux, macOS, and Windows.


CLI usage

# Scan a Django project for models (JSON, Markdown, or table)
django-orm-lens scan -f json
django-orm-lens scan -f markdown
django-orm-lens scan -f table

# Describe one model
django-orm-lens describe blog.Post
django-orm-lens describe Post -f json

# Compact hover card (great for pipeing into your editor)
django-orm-lens hover blog.Post

# Flat list — pipes into fzf, grep, etc.
django-orm-lens list | fzf

# ER diagram — Mermaid (default), DBML, D2, or PlantUML
django-orm-lens er > schema.mmd
django-orm-lens er -f dbml > schema.dbml     # paste into dbdiagram.io
django-orm-lens er -f d2 > schema.d2         # render: d2 schema.d2 schema.svg
django-orm-lens er -f plantuml > schema.puml

# Diff two schema dumps (exit 1 on changes — CI-friendly)
django-orm-lens diff before.json after.json

# Static analyzers — text, json, sarif, or github annotation output
django-orm-lens nplusone --format github     # N+1 findings as PR annotations
django-orm-lens migration-risk -f sarif      # SARIF for GitHub Code Scanning
django-orm-lens suggest-indexes blog.Post    # Meta.indexes proposals from usage
django-orm-lens signals                      # sender→signal→handler graph
django-orm-lens migration-deps blog -f mermaid   # per-app migration DAG
django-orm-lens cascade blog.Author          # delete blast radius by on_delete

Every command accepts --path <dir> and repeatable --exclude <glob>. Defaults skip migrations/, venv/, .venv/, env/, and node_modules/.


MCP server — for AI coding agents

The MCP server exposes ten read-only tools that any MCP-compatible agent can call while it edits your Django project:

Tool Purpose
list_apps Every Django app in the workspace with model counts
list_models Flat app.Model list, optional app filter
describe_model Full field / relation / Meta detail for one model
find_relations Inbound + outbound relations for one model
cascade_preview Blast radius of one delete(), grouped by on_delete
er_diagram ER diagram — mermaid / dbml / d2 / plantuml
describe_migration_dependency Per-app migration DAG: roots, leaves, cross-app deps
suggest_indexes Meta.indexes proposals from observed QuerySet usage
signal_graph Sender→signal→handler graph from @receiver decorators
nplusone_scan Static N+1 findings for the whole workspace

Start the server manually

django-orm-lens-mcp     # dedicated entry point
# or
django-orm-lens mcp     # subcommand

Workspace resolution (py-1.3.0+). Priority: explicit workspace_root argument on the tool call → DJANGO_ORM_LENS_ROOT env var → current working directory. If none resolves to a Django project (manage.py, django in pyproject.toml, or any models.py) you get a structured error envelope back — {"error": "WORKSPACE_NOT_DJANGO", "hint": "…"} — instead of an empty list, so the agent knows what to do next.

Optional sandbox: set DJANGO_ORM_LENS_ALLOWED_ROOTS (;-separated on Windows, :-separated elsewhere) to a whitelist of prefixes; any path outside them is rejected with WORKSPACE_NOT_ALLOWED.

Register it with an agent

Cursor — add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "django-orm-lens": {
      "command": "django-orm-lens-mcp",
      "env": { "DJANGO_ORM_LENS_ROOT": "/abs/path/to/your/project" }
    }
  }
}

Any MCP client — same shape, generic tool. Point command at the installed django-orm-lens-mcp binary. Two ways to tell it which Django project to scan:

  1. Set DJANGO_ORM_LENS_ROOT in env — the whole session uses one project. Simplest for single-repo workflows.
  2. Pass workspace_root on each tool call — the agent switches projects per call. Useful for mono-repos and multi-workspace setups.

The tool signatures include workspace_root: str = "" as an optional parameter, so any agent inspecting tools/list sees it and can supply it.


CI gates

diff and nplusone exit 1 on findings; migration-risk exits 1 on critical findings (--exit-zero for report-only). Two annotation-ready formats: --format github prints ::warning/::error workflow commands (PR annotations with no extra permissions), --format sarif emits SARIF 2.1.0 for github/codeql-action/upload-sarif.

pre-commit users get two ready-made hooks:

repos:
  - repo: https://github.com/FROWNINGdev/django-orm-lens
    rev: py-v1.5.1
    hooks:
      - id: django-orm-lens-nplusone
      - id: django-orm-lens-migration-risk

GitHub Actions users get a composite action: uses: FROWNINGdev/django-orm-lens@action-v1 with command: / format: inputs.


Why?

Django's ORM is Python, and Python is dynamic. AI agents that only see models.py as raw text miss:

  • which fields belong to which model;
  • the direction and cardinality of every relation;
  • what Meta.ordering, unique_together, and constraints actually contain;
  • which app owns which model when the project uses split models/ packages.

django-orm-lens gives them a static, deterministic, JSON view of the schema — no Django boot, no database, no side effects. And you get a nice CLI for humans too.


Programmatic API

from django_orm_lens import scan_workspace

index = scan_workspace(".")
for app in index.apps:
    for model in app.models:
        print(f"{app.name}.{model.name}{len(model.fields)} fields")

# The full parsed tree serialises to the same JSON schema the VS Code
# extension emits, so tools can share it interchangeably.
import json
json.dumps(index.to_dict(), indent=2)

Links

MIT licensed.

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

django_orm_lens-1.5.1.tar.gz (113.8 kB view details)

Uploaded Source

Built Distribution

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

django_orm_lens-1.5.1-py3-none-any.whl (73.4 kB view details)

Uploaded Python 3

File details

Details for the file django_orm_lens-1.5.1.tar.gz.

File metadata

  • Download URL: django_orm_lens-1.5.1.tar.gz
  • Upload date:
  • Size: 113.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for django_orm_lens-1.5.1.tar.gz
Algorithm Hash digest
SHA256 75805623ba4f3fab09369fb25445a9313f61b0615a6931d7727f2e2ea93d6f3d
MD5 6def1690576beb437666ab01c95aab4a
BLAKE2b-256 6879556fa30e6d57a76ec3fbd90449270c102b04f0d0fb7252fa122beb938b39

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_orm_lens-1.5.1.tar.gz:

Publisher: publish-pypi.yml on FROWNINGdev/django-orm-lens

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_orm_lens-1.5.1-py3-none-any.whl.

File metadata

  • Download URL: django_orm_lens-1.5.1-py3-none-any.whl
  • Upload date:
  • Size: 73.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for django_orm_lens-1.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 431cdab24aaff6d4974beb33f5e2b7fa515b393c59d851fb8045b10210cd11a2
MD5 addf035a0a33014a9e875849f676a659
BLAKE2b-256 ee4ab73575cbd7cb22bab127a3bbf009169f7a934dea96c13907466ab36ecb1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_orm_lens-1.5.1-py3-none-any.whl:

Publisher: publish-pypi.yml on FROWNINGdev/django-orm-lens

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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