Skip to main content
Glama
edelvalle

django-admin-fastmcp

by edelvalle

django-admin-fastmcp

Многоразовое Django-приложение, которое предоставляет админку Django как MCP-сервер, построенный на FastMCP.

Каждый вызов инструмента выполняется от имени сотрудника, которому принадлежит bearer-токен. Каждый вызов инструмента сначала запрашивает разрешение у ModelAdmin. Суперпользователь может делать всё, что суперпользователь может делать в админке. Сотрудник может делать ровно то, что этот сотрудник может делать в админке, и не больше.

SPEC.md — это полная спецификация.

Как это работает

Три правила определяют пакет:

  1. Нет параллельной системы разрешений. Авторизация делегируется методам ModelAdmin: has_view_permission, has_add_permission, has_change_permission, has_delete_permission, get_queryset, get_readonly_fields и get_actions. Переопределение get_queryset, которое скрывает строки, скрывает их и от MCP.

  2. Нет параллельной поверхности данных. Записи проходят через собственную ModelForm и save_model админки, а затем записывают LogEntry. Страница истории админки остаётся правдивой.

  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
}

Смонтируйте конечные точки 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:

  1. Клиент открывает ваш браузер на странице авторизации на сайте Django.

  2. Ваша cookie сессии админки идентифицирует вас. Если вы вышли из системы, сначала появится обычный вход в админку.

  3. Страница согласия показывает имя клиента и что означает одобрение. Вы одобряете.

  4. Клиент получает свои токены и подключается. Он обновляет их самостоятельно.

Любой MCP-клиент, который говорит на потоковом HTTP с OAuth, работает так же, например Cursor или FastMCP Client.

Правила доступа:

  • Любой сотрудник может авторизовать клиента только для себя.

  • Разрешение действует с вашими собственными правами админки, никогда не больше. Нет отдельной системы разрешений: кто может изменять модель в админке, тот может изменять её через MCP, когда сервер перечисляет эту модель в WRITABLE_MODELS.

  • Refresh-токены истекают через REFRESH_TOKEN_TTL_DAYS (по умолчанию 90), поэтому повторное согласие происходит так часто. Отзыв — это действие админки в списке изменений разрешений.

Инструменты

Одиннадцать общих инструментов, смонтированных в пространстве имён admin, поэтому имена проводов — admin_list_models и так далее. Каждый принимает model как "app_label.ModelName". Список инструментов статичен. Что меняется для каждого пользователя — это то, что каждый инструмент позволяет этому пользователю видеть и делать.

Чтение

Инструмент

Аргументы

Возвращаемое значение

list_models

нет

Каждая доступная модель, которую этот вызывающий может просматривать, с флагами разрешений.

describe_model

model

Поля, отображение списка, фильтры, поля поиска, поля только для чтения и доступные действия.

search_objects

model, q, filters, order_by, page, page_size

Строки плюс total. q использует собственный поиск админки. Неизвестный фильтр — ошибка.

get_object

model, pk

Один сериализованный экземпляр.

object_history

model, pk

Записи журнала админки для этого объекта, сначала новые.

recent_actions

limit

Записи журнала админки, ограниченные вызывающим, если вызывающий не суперпользователь.

Запись

Инструменты записи требуют, чтобы модель была указана в WRITABLE_MODELS; ваши собственные права админки решают остальное, для каждой модели и каждого объекта. Модель вне списка отказывает в любой записи и любом действии, кто бы ни вызывал. Оставьте чувствительные модели вне списка, например журнал событий, и ни один MCP-клиент никогда не сможет в них писать.

Инструмент

Аргументы

Поведение

create_object

model, data

Проверяет через форму админки, затем сохраняет и записывает в журнал.

update_object

model, pk, data

Частичное обновление. Поля только для чтения игнорируются.

delete_object

model, pk, confirm

Без confirm возвращает точный каскад удаления и ничего не меняет.

run_action

model, action, pks, confirm

Выполняет действие админки. Без confirm возвращает предпросмотр.

autocomplete

model, field, q

Разрешает значение внешнего ключа в первичный ключ, ища в связанной модели.

Каждая возвращаемая строка несёт pk как строку и admin_url, чтобы агент мог передать человеку ссылку в реальную админку.

Настройки

Все ключи находятся в словаре 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

Ограничение pks для run_action.

ACCESS_TOKEN_TTL_MINUTES

60

Время жизни access-токена. Клиенты обновляют его с помощью refresh-токена.

REFRESH_TOKEN_TTL_DAYS

90

Время жизни refresh-токена. Повторное согласие происходит так часто.

SITE_URL

"http://127.0.0.1:8000"

Публичный URL сайта Django. Это издатель OAuth, и MCP-сервер называет его своим сервером авторизации.

MCP_URL

"http://127.0.0.1:8765/admin/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 fields

REDACT_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

-
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