django-admin-fastmcp
django-admin-fastmcp
Многоразовое Django-приложение, которое предоставляет админку Django как MCP-сервер, построенный на FastMCP.
Каждый вызов инструмента выполняется от имени сотрудника, которому принадлежит bearer-токен. Каждый вызов инструмента сначала запрашивает разрешение у ModelAdmin. Суперпользователь может делать всё, что суперпользователь может делать в админке. Сотрудник может делать ровно то, что этот сотрудник может делать в админке, и не больше.
SPEC.md — это полная спецификация.
Как это работает
Три правила определяют пакет:
Нет параллельной системы разрешений. Авторизация делегируется методам
ModelAdmin:has_view_permission,has_add_permission,has_change_permission,has_delete_permission,get_queryset,get_readonly_fieldsиget_actions. Переопределениеget_queryset, которое скрывает строки, скрывает их и от MCP.Нет параллельной поверхности данных. Записи проходят через собственную
ModelFormиsave_modelадминки, а затем записываютLogEntry. Страница истории админки остаётся правдивой.Отказ по умолчанию. Каждый неразрешённый поиск, отсутствующий
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
}Смонтируйте конечные точки 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 документ должен находиться в корне, потому что клиент выводит его URL из издателя, а конечные точки должны располагаться на том же сайте, что и админка, потому что страница согласия использует cookie сессии админки.
Примените миграции:
python manage.py migrate django_admin_fastmcpБольше ничего. Никакой регистрации по моделям, никаких миксинов, никаких декораторов. Сервер предоставляет то, что уже предоставляет админка.
Подключение клиента
Запустите сервер (см. Развертывание), затем зарегистрируйте его:
# Claude Code
claude mcp add --transport http acme-admin https://<host>/admin/mcpИспользуйте путь без завершающего слэша. /admin/mcp/ отвечает редиректом 307 на /admin/mcp, и не каждый клиент следует редиректу на POST.
Никакого токена, никакого заголовка. Первый вызов запускает стандартный поток MCP OAuth:
Клиент открывает ваш браузер на странице авторизации на сайте Django.
Ваша cookie сессии админки идентифицирует вас. Если вы вышли из системы, сначала появится обычный вход в админку.
Страница согласия показывает имя клиента и что означает одобрение. Вы одобряете.
Клиент получает свои токены и подключается. Он обновляет их самостоятельно.
Любой MCP-клиент, который говорит на потоковом HTTP с OAuth, работает так же, например Cursor или FastMCP Client.
Правила доступа:
Любой сотрудник может авторизовать клиента только для себя.
Разрешение действует с вашими собственными правами админки, никогда не больше. Нет отдельной системы разрешений: кто может изменять модель в админке, тот может изменять её через MCP, когда сервер перечисляет эту модель в
WRITABLE_MODELS.Refresh-токены истекают через
REFRESH_TOKEN_TTL_DAYS(по умолчанию 90), поэтому повторное согласие происходит так часто. Отзыв — это действие админки в списке изменений разрешений.
Инструменты
Одиннадцать общих инструментов, смонтированных в пространстве имён admin, поэтому имена проводов — admin_list_models и так далее. Каждый принимает model как "app_label.ModelName". Список инструментов статичен. Что меняется для каждого пользователя — это то, что каждый инструмент позволяет этому пользователю видеть и делать.
Чтение
Инструмент | Аргументы | Возвращаемое значение |
| нет | Каждая доступная модель, которую этот вызывающий может просматривать, с флагами разрешений. |
|
| Поля, отображение списка, фильтры, поля поиска, поля только для чтения и доступные действия. |
|
| Строки плюс |
|
| Один сериализованный экземпляр. |
|
| Записи журнала админки для этого объекта, сначала новые. |
|
| Записи журнала админки, ограниченные вызывающим, если вызывающий не суперпользователь. |
Запись
Инструменты записи требуют, чтобы модель была указана в WRITABLE_MODELS; ваши собственные права админки решают остальное, для каждой модели и каждого объекта. Модель вне списка отказывает в любой записи и любом действии, кто бы ни вызывал. Оставьте чувствительные модели вне списка, например журнал событий, и ни один MCP-клиент никогда не сможет в них писать.
Инструмент | Аргументы | Поведение |
|
| Проверяет через форму админки, затем сохраняет и записывает в журнал. |
|
| Частичное обновление. Поля только для чтения игнорируются. |
|
| Без |
|
| Выполняет действие админки. Без |
|
| Разрешает значение внешнего ключа в первичный ключ, ища в связанной модели. |
Каждая возвращаемая строка несёт pk как строку и admin_url, чтобы агент мог передать человеку ссылку в реальную админку.
Настройки
Все ключи находятся в словаре ADMIN_FASTMCP. Неизвестный ключ — ошибка при запуске.
Ключ | По умолчанию | Значение |
|
| Имя, которое рекламирует MCP-сервер. |
|
| Точечный путь к |
|
| Белый список |
|
| Чёрный список. Поддерживает |
|
| Модели, которые принимают записи. Пусто означает отсутствие записей, кто бы ни вызывал. |
|
| Имена инструментов, полностью удалённые из каталога. |
|
| Подстрока в именах полей. Значения читаются как |
|
| Ограничение размера страницы для |
|
| Ограничение |
|
| Время жизни access-токена. Клиенты обновляют его с помощью refresh-токена. |
|
| Время жизни refresh-токена. Повторное согласие происходит так часто. |
|
| Публичный URL сайта Django. Это издатель OAuth, и MCP-сервер называет его своим сервером авторизации. |
|
| Публичный URL конечной точки MCP. |
Установите SITE_URL и MCP_URL для любого реального развертывания. MCP_URL — единственный источник трёх вещей, которые должны совпадать: путь, по которому обслуживается конечная точка, resource, который рекламирует обнаружение, и аудитория, к которой привязан каждый токен. Его путь по умолчанию — /admin/mcp. Проверка при запуске отказывает в MCP_URL без пути, потому что тогда весь origin был бы объявлен защищённым ресурсом.
Настройки для каждого ModelAdmin
Установите их в классе ModelAdmin, миксин не нужен:
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 fieldsREDACT_FIELDS имеет приоритет над mcp_fields. Явное перечисление поля пароля не раскрывает его.
Безопасность
MCP-сервер админки для суперпользователя — это удалённая оболочка над производственной базой данных, управляемая языковой моделью. Ограничения:
WRITABLE_MODELSпо умолчанию пуст, поэтому ни одна модель не принимает записи, пока развертывание не назовёт её. Всё остальное — ваши обычные разрешения Django, запрашиваемые черезModelAdminпри каждом вызове.Access-токены недолговечны. Хранятся только солёные хэши, поэтому утёкшая строка базы данных не может быть воспроизведена.
delete_objectиrun_actionпо умолчанию показывают предпросмотр и ничего не меняют доconfirm=True.Каждая мутация записывает
LogEntry, приписанный пользователю разрешения, с именем клиента в сообщении об изменении, например"Changed status. Via MCP (client: Claude Code).". Запись, которая не может записатьLogEntry, откатывается.Собственные модели пакета,
sessions.Sessionиauthtoken.Tokenникогда не раскрываются, что бы ни говорили настройки.Держите
auth.Permissionиauth.GroupвнеWRITABLE_MODELS. Агент, который может выдавать разрешения, может выйти за пределы модели разрешений.
Развертывание
Отдельный процесс. Запустите MCP-сервер рядом с вашим проектом Django:
python manage.py admin_mcp_serveОн обслуживает путь из MCP_URL, который по умолчанию /admin/mcp, на порту из MCP_URL, или 8765, если этот URL не указывает порт. Оба можно переопределить с помощью --host и --port. Ничего в вашей существующей конфигурации обслуживания не меняется. Направьте /admin/mcp через ваш ingress на этот порт и убедитесь, что заголовок Authorization проходит.
Смонтированный (M3). Смонтируйте сервер по адресу /admin/mcp внутри asgi.py вашего проекта. Одно ограничение: диспетчеризация по точному пути. Конечные точки OAuth находятся непосредственно под тем же префиксом (/admin/mcp/authorize и другие), и Django должен продолжать их обслуживать, поэтому диспетчер, который отправляет всё под /admin/mcp в FastMCP, поглотил бы их. Рецепт поставляется с вехой 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Лицензия
MIT
This server cannot be installed
Maintenance
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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