Skip to main content
Glama
edelvalle

django-admin-fastmcp

by edelvalle

django-admin-fastmcp

一个可复用的 Django 应用,将 Django admin 暴露为 MCP 服务器,基于 FastMCP 构建。

每次工具调用都会以后台用户(即该 bearer token 的拥有者)身份执行。每次工具调用都会先向 ModelAdmin 请求权限。超级用户可以做到超级用户在 admin 中能做的所有事。staff 用户 则只能做到该 staff 用户在 admin 中能做的事,除此之外没有任何额外权限。

SPEC.md 是完整规范。

工作原理

三条规则定义了整个包:

  1. 没有另一套并行的权限系统。 授权全部委托给 ModelAdmin 的方法: has_view_permissionhas_add_permissionhas_change_permissionhas_delete_permissionget_querysetget_readonly_fieldsget_actions。 如果覆写了 get_queryset 来隐藏某些行,那么这些行对 MCP 也同样隐藏。

  2. 没有另一套数据面。 写入操作走 admin 自己的 ModelFormsave_model,然后记录 LogEntry。admin 的历史页面保持真实。

  3. 默认拒绝。 任何无法解析的查找、缺失的 ModelAdmin、未知的动作、未知的字段 以及未知的工具调用,都会被拒绝。

安装

uv add django-admin-fastmcp

把应用加入你的设置:

INSTALLED_APPS = [
    ...,
    "django.contrib.admin",
    "django_admin_fastmcp",
]

ADMIN_FASTMCP = {
    "SERVER_NAME": "acme-admin",
    "EXCLUDE_MODELS": ("auth.Permission", "auth.Group"),
    "WRITABLE_MODELS": (),          # empty means no writes at all
}

在同 admin 站点下绑定 OAuth 端点:

# urls.py
urlpatterns = [
    # RFC 8414 fixes this one at the site root.
    path("", include("django_admin_fastmcp.well_known_urls")),
    # This prefix is yours to choose. Match it to the path in MCP_URL.
    path("admin/mcp/", include("django_admin_fastmcp.urls")),
    path("admin/", admin.site.urls),
]

本包没有硬编码任何前缀。发现文档中公布的每一个 URL 都来自 reverse(), 所以如果项目把端点挂载在 /backoffice/oauth/,该路径也会出现在发现文档中, 客户端会照着访问。有两条规则:well-known 文档必须位于根路径,因为客户端会凭 issuer 推导出它的 URL;端点也应该和 admin 放在同一个站点,因为同意页面依赖 admin 的会话 cookie。

执行迁移:

python manage.py migrate django_admin_fastmcp

仅此而已。不需要逐模型注册,不需要 mixin,不需要装饰器。服务器会把 admin 已经暴露的 内容原样暴露出来。

连接客户端

运行服务器(参见部署),然后注册它:

# Claude Code
claude mcp add --transport http acme-admin https://<host>/admin/mcp

使用不带尾部斜杠的路径。/admin/mcp/ 会返回 307 重定向到 /admin/mcp,但并不是所有客户端都会在 POST 请求时跟随重定向。

没有 token,也没有请求头。第一次调用就会启动标准的 MCP OAuth 流程:

  1. 客户端在你的浏览器中打开 Django 站点上的授权页面。

  2. 你的 admin 会话 cookie 会识别你的身份。如果已经退出登录,会首先显示普通的 admin 登录页。

  3. 同意页面会显示客户端名称以及批准所代表的意义。你点击批准。

  4. 客户端收到 token 并连接。之后它会自行续约。

任何支持带 OAuth 的 streamable HTTP 的 MCP 客户端都能以相同方式工作, 例如 Cursor,或 FastMCP Client

访问规则:

  • 任何 staff 用户都可以为自己授权客户端,而且只能为自己。

  • 授权记录只拥有你自己 admin 权限,绝不会多。没有其他权限系统: 遵循 admin 中能修改某模型的人,在服务器把该模型列入 WRITABLE_MODELS 后, 也同样能通过 MCP 修改它。

  • 刷新 token 会在 REFRESH_TOKEN_TTL_DAYS(默认 90 天)后过期,因此 重新授权也会按这个频率发生。撤销授权是在授权记录 changelist 中的一项管理操作。

工具

十一个通用工具,挂载在 admin 命名空间下,因此它们的 wire 名称是 admin_list_models 等。每个工具都接受 model,格式为 "app_label.ModelName"。工具列表 是静态的。用户之间的差异只在于每个工具允许使用者看到什么、做什么。

读取

工具

参数

返回

list_models

调用者可以查看的所有已暴露模型,以及权限标记。

describe_model

model

字段、list display、筛选器、搜索字段、只读字段和可用动作。

search_objects

modelqfiltersorder_bypagepage_size

返回行及 totalq 使用 admin 自己的搜索。未知筛选器会报错。

get_object

modelpk

一个序列化后的实例。

object_history

modelpk

该对象的 admin 日志条目,最新在前。

recent_actions

limit

admin 日志条目,默认限定为调用者,调用者为超级用户时除外。

写入

写工具要求模型被列入 WRITABLE_MODELS;剩下的决定权仍然根据你自己的 admin 权限,按模型、按对象进行。列表之外的模型,无论调用者是谁,都会拒绝所有写入操作 和所有动作。把敏感模型留在外面,例如事件日志,这样任何 MCP 客户端都无法向它们写入。

工具

参数

行为

create_object

modeldata

通过 admin 表单验证,然后保存并记录日志。

update_object

modelpkdata

部分更新。只读字段会被忽略。

delete_object

modelpkconfirm

没有 confirm 时,返回精确的删除级联结果,且不作出任何更改。

run_action

modelactionpksconfirm

运行 admin 动作。没有 confirm 时可返回预览。

autocomplete

modelfieldq

通过搜索关联模型,把外键值解析为主键值。

每个返回的行都会带上字符串形式的 pkadmin_url,因此 agent 可以把 一个进入真实 admin 的链接交给人类用户。

设置

所有键都放在 ADMIN_FASTMCP 字典中。未知的键会在启动时触发错误。

默认值

含义

SERVER_NAME

"django-admin"

MCP 服务器对外公布的名称。

ADMIN_SITE

"django.contrib.admin.site"

AdminSite 的点分路径。

MODELS

()

白名单,格式为 "app_label.ModelName"。非空时,其他模型一律不暴露。

EXCLUDE_MODELS

()

黑名单。支持 "app_label.*"

WRITABLE_MODELS

()

接受写入的模型。为空表示无论谁调用都不允许写入。

DISABLED_TOOLS

()

从工具目录中完全移除的工具名称。

REDACT_FIELDS

("password", "token", "secret", "api_key", "private_key")

对字段名称做子字符串匹配。匹配到的字段值显示为 "[redacted]"

MAX_PAGE_SIZE

200

search_objects 页大小的上限。

MAX_PKS

1000

每次 run_actionpks 数量的上限。

ACCESS_TOKEN_TTL_MINUTES

60

访问令牌的有效期。客户端使用刷新令牌续期。

REFRESH_TOKEN_TTL_DAYS

90

刷新令牌的有效期。达到这一时长就需要重新授权。

SITE_URL

"http://127.0.0.1:8000"

Django 站点的公开 URL。它是 OAuth issuer,MCP 服务器也将它标记为授权服务器。

MCP_URL

"http://127.0.0.1:8765/admin/mcp"

MCP 端点的公开 URL。

任何真实部署都必须设置 SITE_URLMCP_URLMCP_URL 是三件必须一致的事的 唯一定义来源:端点实际服务的路径、发现文档公布的 resource,以及每个令牌绑定的 audience。其路径默认为 /admin/mcp。启动检查会拒绝一个不带路径的 MCP_URL, 因为那样的话整个源会被作为受保护资源公布。

每个 ModelAdmin 的配置项

把以下配置放在某个 ModelAdmin 类上,不需要 mixin:

class InvoiceAdmin(admin.ModelAdmin):
    mcp_expose = False                     # hide this model from MCP entirely
    mcp_fields = ("number", "total")       # allowlist of serialized fields
    mcp_exclude_fields = ("internal_note",)  # denylist of serialized fields

REDACT_FIELDS 优先于 mcp_fields。即使你显式列出密码字段, 也不会把它暴露出去。

安全

一个对超级用户开放的 admin MCP 服务器,就是一个由语言模型驱动的、架在生产数据库上的 远程 shell。护栏如下:

  • WRITABLE_MODELS 默认是空的,因此在部署时显式列出之前,没有模型会接受写入。 其余的一切都是你常规的 Django 权限,每次调用都会通过 ModelAdmin 进行询问。

  • 访问令牌有效期很短。数据库只保存加盐哈希,因此即使数据库行泄露 也无法被重放。

  • delete_objectrun_action 默认只预览,直到 confirm=True 才会有动作。

  • 每一次变更都会记录一条 LogEntry,归属到授权用户,并且在变更消息中携带 客户端的名称,例如 "Changed status. Via MCP (client: Claude Code)."。如果一次写入 无法记录 LogEntry,则该写入会回滚。

  • 本包自身的模型、sessions.Sessionauthtoken.Token 永远不会暴露, 无论设置如何。

  • 不要把 auth.Permissionauth.Group 放进 WRITABLE_MODELS。 能够授予权限的 agent 可以逃出权限模型。

部署

独立进程。 在 Django 项目旁边运行 MCP 服务器:

python manage.py admin_mcp_serve

它从 MCP_URL 中取得路径,也就是默认的 /admin/mcp,并使用 MCP_URL 中的端口; 如果 URL 中没有端口则使用 8765。两者都可以用 --host--port 覆盖。 你现有的任何服务配置都不需要改变。把 /admin/mcp 通过 ingress 路由到该端口, 并确保 Authorization 头被传递过来。

挂载(M3)。 在项目的 asgi.py 中将服务器挂载到 /admin/mcp。 有一个约束:必须按完整路径进行分发。OAuth 端点也位于同一个前缀之下 (/admin/mcp/authorize 等),Django 必须继续为它们提供服务, 因此如果你把 /admin/mcp 下的所有内容都交给 FastMCP,会把那些 OAuth 端点 全部吞掉。本配方随里程碑 M3 提供。

服务器是无状态的,因此负载均衡器后面的任何实例都能承担任何请求。

开发

make install     # bootstrap uv, pin Python, install dependencies
make test        # run the permission matrix
make check       # format, lint, typecheck, and test
make migrate     # migrate the test project
make serve       # run the MCP server against the test project on :8765/admin/mcp
make help        # everything else

License

MIT

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP server for AI dialogue using various LLM models via AceDataCloud

  • An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform

  • Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/edelvalle/django-admin-fastmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server