关于 Frisian MCP (Django)
Frisian MCP (Django) 将 Django REST Framework 的 ViewSet 操作自动注册为 MCP 工具,面向需要向 Agent 开放现有 Django API 的团队。它支持调度器、细粒度权限控制和精简响应,以减少工具描述与写入结果占用的上下文。
主要功能
- 01自动发现 ViewSet 操作
- 02从序列化器生成工具架构
- 03将多个操作合并到调度器
- 04OAuth 2.0 与令牌认证
- 05按凭据和权限层级限制访问
- 06精简写入响应与延迟发现
适用场景
- 01将现有 DRF API 提供给 MCP 客户端
- 02按 Agent 凭据限制可用工具
- 03降低大量 API 操作的工具列表开销
- 04通过 Django 权限控制 API 调用
MCP 相关
提供基于 HTTP 的 MCP 服务,支持工具和资源发现及调用。它将 ViewSet 操作或自定义函数作为工具暴露,并可选地将多个操作汇总到单个调度器。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.frisian-mcp.com/mcp/claude mcp add --transport http com-frisian-mcp-django https://mcp.frisian-mcp.com/mcp/{"mcpServers":{"com-frisian-mcp-django":{"type":"http","url":"https://mcp.frisian-mcp.com/mcp/"}}}在 Cursor 中打开{"servers":{"com-frisian-mcp-django":{"type":"http","url":"https://mcp.frisian-mcp.com/mcp/"}}}在 VS Code 中打开{"mcpServers":{"com-frisian-mcp-django":{"type":"http","url":"https://mcp.frisian-mcp.com/mcp/"}}}{"mcpServers":{"com-frisian-mcp-django":{"serverUrl":"https://mcp.frisian-mcp.com/mcp/"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
4| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mode | enum | 否 | summary | paginated | filtered | full |
| page | integer | 否 | |
| action | enum | 否 | 要执行的操作。省略或使用 'help' 可列出所有可用操作及其必需参数。about | getting_started | integrations | security | demo | documents | rag |
| params | object | 否 | 特定操作的参数。about:{version};getting_started:{version};integrations:{version};security:{version};demo:{surface};documents:{sub_action, slug, id, category, limit, offset};rag:{query, limit, offset, category}。'mode'、'page'、'page_size' 和 'filter_keys' 仅在续接调用时(即与 'continuation_token' 并列)作为顶层参数;否则它们是普通操作参数,应放在此处。 |
| page_size | integer | 否 | |
| filter_keys | array | 否 | |
| continuation_token | string | 否 | 来自探测响应。在顶层发送,不要放在 'params' 内。 |
详细介绍
frisian-mcp
可自动发现 API 的 Django MCP 网关。
frisian-mcp 可将现有的 Django REST Framework ViewSet 转换为 Model Context Protocol 工具,无需编写样板代码。添加此包并包含一个 URL,每个 ViewSet 操作都会成为可调用的 MCP 工具——名称、描述和输入架构均由序列化器自动生成。
专为节省令牌的 Agent 工作流设计。 一个包含 50 个操作的 Django 应用,其 tools/list 架构仅占用 500–2,000 个令牌,而传统扁平 MCP 会输出 15,000–25,000 个令牌;一次包含 60 台设备的批量写入响应仅占用 24 个令牌,而完整回显约需 10,800 个令牌。功能界面相同,但 Agent 开始推理前消耗的上下文减少了两个数量级。完整数据见令牌效率。
版本: 1.1.1 | 许可证: Apache 2.0 | Python: 3.11+ | Django: 5.x
pip install frisian-mcp
项目网站: https://frisian-mcp.com/
我们在 https://frisian-mcp.com/ 托管了一个可实时使用的 MCP 服务,供实际体验——将任何兼容 MCP 的客户端连接到该服务,即可通过真实接口体验分发器模式和精简封装行为。该网站还通过可由 MCP 使用的分发器提供项目文档,因此编码 Agent(Claude Code、Codex、Gemini CLI 等)可以直接连接,并在将 frisian-mcp 集成到你自己的项目时,将安装、配置和装饰器参考资料纳入工作上下文。
概览
| 功能 | 详情 |
|---|---|
| 自动发现 | 启动时遍历 URL 模式;将每个 ViewSet 操作注册为 MCP 工具 |
| 无需样板代码 | 名称、描述和输入架构均由 DRF 序列化器自动生成 |
@mcp_dispatcher | 一个工具对应多个操作;内置帮助模式;逐操作验证 |
@mcp_tool | 显式注册单函数工具以实现自定义逻辑 |
@mcp_resource | 通过 resources/list / resources/read 暴露服务端内容 |
| 筛选器内省 | SearchFilter、OrderingFilter、DjangoFilterBackend → list 上的架构属性 |
| 允许列表 / 拒绝列表 | 使用 FRISIAN_MCP_TOOL_ALLOWLIST / FRISIAN_MCP_TOOL_DENYLIST 精细控制接口 |
| 分发组 | FRISIAN_MCP_DISPATCH_GROUPS — 将 N 个工具打包为 1 个分发器;使用 action="help" 进行发现 |
| 延迟发现 | URL 扫描在首次请求时触发——可捕获后续加载的插件 ViewSet |
| OAuth 2.0 | contrib.oauth — 授权码(PKCE)+ 客户端凭据;令牌经 HMAC 哈希处理 |
| 静态令牌 | contrib.tokens — 供内部 Agent 使用的 HMAC 哈希 Bearer 令牌 |
| 按 Agent 限定范围 | contrib.agents — 每项凭据对应工具允许列表;连接未激活时默认拒绝 |
| 权限层级 | FRISIAN_MCP_TOKEN_TIER_MAP / FRISIAN_MCP_MAX_TIER — 将角色映射到读写权限门槛 |
| 宿主应用范围控制 | SyncInvocation 调用 viewset.initial() — 强制执行宿主 RBAC、查询集过滤和限流 |
| 工具中间件 | FRISIAN_MCP_TOOL_MIDDLEWARE — 审计日志、速率限制、心跳 |
| 速率限制 | RateLimitMiddleware — 内置滑动窗口,无需 Redis |
| 可插拔后端 | 通过点分路径设置指定自定义发现和调用后端 |
| SSE 支持 | Accept: text/event-stream 将任意响应封装为单个 SSE 事件 |
MCP 2025-11-25 | Streamable HTTP;ping、initialize、tools/list、tools/call、resources/list |
Token 效率
分发器模式和精简写入信封只有一个目的:Agent 的上下文窗口有限,而传统的 MCP 形式(每个 ViewSet 操作对应一个工具;每次写入都完整序列化回显)会在 Agent 完成任何有用的工作之前耗尽预算。
来自实际集成的测量数据:
| 场景 | 默认 MCP 形式 | frisian-mcp | 降幅 |
|---|---|---|---|
50 个操作的 Django 应用的 tools/list | ~15,000–25,000 个 token | 使用 FRISIAN_MCP_DISPATCH_GROUPS 时为 500–2,000 个 token | ~95% |
大型基础设施 Django 应用的 tools/list | 1,737 个扁平工具 | 15 个分发器工具 | 工具数量减少 ~99% |
| 60 台设备的批量创建响应 | ~10,798 个 token(完整回显) | 24 个 token(精简信封) | 99.8% |
| 200 台设备的批量创建响应 | ~36,000 个 token | 24 个 token(固定) | 99.9% |
无论批次大小如何,批量写入节省的 token 数量都是固定的——精简信封的形状固定,而完整响应可通过续传令牌获取,无需重新执行写入。分发器功能需通过 FRISIAN_MCP_DISPATCH_GROUPS 显式启用(仅启用自动发现时仍采用传统的扁平形式)。
设计依据和完整测量数据,请参阅Token 问题、分发器模式和写入路径响应过滤。
要求
- Python 3.11+
- Django 5.x
- Django REST Framework 3.14+
快速入门
1. 安装并添加到 INSTALLED_APPS:
# settings.py
INSTALLED_APPS = [
...
"frisian_mcp",
]
2. 引入网关 URL:
# urls.py
from django.urls import include, path
urlpatterns = [
...
path("mcp/", include("frisian_mcp.urls")),
]
就这样。启用自动发现后(默认启用),URL 树中的每个 DRF ViewSet 现在都是一个 MCP 工具。
# myapp/views.py — nothing changes here
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAuthenticated]
启动后,网关会公开 users.list、users.retrieve、users.create、users.update、users.partial_update 和 users.destroy——这些操作完全由 ViewSet 派生而来。
3. 生成客户端配置:
python manage.py mcp_config --token mytoken123
{
"mcpServers": {
"frisian-mcp": {
"url": "http://localhost:8000/mcp/",
"transport": "http",
"headers": { "Authorization": "Bearer mytoken123" }
}
}
}
使用 --client 生成特定 MCP 客户端所需的格式。使用 --url 和 --name 覆盖服务 URL 和键。
4. 验证安装:
python manage.py mcp_doctor # standard audit
python manage.py mcp_doctor --security # extended OAuth security audit
端到端检查配置,遇到错误时以非零状态码退出。每次安装后、每次配置更改后都应运行;出现任何意外行为时,也应将其作为首要诊断步骤。完整检查清单请参阅 mcp_doctor 指南。
架构概览
MCP Client
│ JSON-RPC 2.0 over HTTP POST
▼
┌──────────────────────────────────────────────────┐
│ McpView (DRF APIView) │
│ ├─ Authentication (FRISIAN_MCP_AUTHENTICATION_CLASSES) │
│ ├─ Permissions (FRISIAN_MCP_PERMISSION_CLASSES) │
│ └─ Method dispatch │
│ ├─ initialize / initialized / ping / help │
│ ├─ tools/list ──────────────── ToolRegistry │
│ ├─ tools/call ── ToolMiddleware ── Registry │
│ ├─ resources/list ───────── ResourceRegistry │
│ └─ resources/read ───────── ResourceRegistry │
└──────────────────────────────────────────────────┘
│
┌──────────────────┐ ┌─────────────────────────┐
│ ToolRegistry │ │ Auto-discovery │
│ (module-level │◄──│ (DRFSyncDiscovery) │
│ singleton) │ │ Walks URL patterns at │
│ │ │ AppConfig.ready() │
└──────────────────┘ └─────────────────────────┘
│
┌──────────────────────────────────────────────────┐
│ InvocationBackend (SyncInvocation by default) │
│ Builds synthetic DRF Request → calls ViewSet │
│ action → returns ToolResult │
└──────────────────────────────────────────────────┘
- 发现与调用分离。 两个可插拔后端,可分别覆盖任意一个。
- 注册表是事实来源。
@mcp_tool、@mcp_dispatcher和自动发现都会写入同一个tool_registry单例。 - 工具错误使用
isError: true,而非 JSON-RPC 错误。 权限拒绝和处理器异常会在正常的 HTTP 200 响应中返回isError: true,会话仍会保持活动状态。 - 两个强制执行点。 网关级权限控制整个
/mcp/接口。工具级权限层级控制单个tools/call调用。
分发器模式
对于构建专用 Agent 工具的团队,frisian-mcp 提供了 @mcp_dispatcher 模式:一个 MCP 工具名称可在内部路由到多个操作。
from frisian_mcp import mcp_dispatcher, mcp_action
@mcp_dispatcher(name="tasks", description="Manage project tasks.")
class TasksDispatcher:
@mcp_action(name="create", description="Create a task.")
def create(self, request, params):
task = Task.objects.create(title=params["title"])
return {"id": task.pk}
@mcp_action(name="list", description="List tasks by status.")
def list(self, request, params):
return {"tasks": list(Task.objects.values("id", "title", "status"))}
tools/list 中只列出一个工具,而非多个工具。使用 action="help" 调用,可获取可用操作的结构化列表。调用方法前会进行各操作的 JSON Schema 验证。
对于面向 Agent 的 API,如果工具数量很重要,且渐进式披露优于扁平列表,这就是适用的模式。
对于高流量 API,FRISIAN_MCP_DISPATCH_GROUPS 可以自动将现有的自动发现工具打包成分发器,无需额外代码。
身份验证与安全
frisian-mcp 将身份验证委托给 DRF——任何 DRF 身份验证类都可以通过 FRISIAN_MCP_AUTHENTICATION_CLASSES 开箱即用。三个可直接使用的 contrib 模块涵盖了最常见的场景:
| 模块 | 提供内容 |
|---|---|
frisian_mcp.contrib.tokens | 用于内部 Agent 和服务账户的 HMAC 哈希静态 Bearer 令牌 |
frisian_mcp.contrib.oauth | 完整的 OAuth 2.0——授权码(PKCE)+ 客户端凭据;重定向 URI 允许列表 |
frisian_mcp.contrib.agents | 每个凭据各自的工具允许列表;凭据停用时,连接会以失败关闭 |
网关级访问由 FRISIAN_MCP_PERMISSION_CLASSES 控制。工具级访问由权限层级(read / read_write / admin)控制,并通过 FRISIAN_MCP_TOKEN_TIER_MAP 映射。使用 FRISIAN_MCP_MAX_TIER 可限制某个端点上所有调用方的最高权限,无论其凭据权限层级为何。
默认采用强化安全配置(1.0.x)
默认配置侧重生产环境安全,而非开箱即用的便利性:
- 令牌和客户端密钥使用 HMAC-SHA256 摘要存储(
FRISIAN_MCP_HMAC_KEY)。数据库记录即使泄露,也无法直接用于重放——原始密钥仅在创建时显示一次。 - 默认关闭 OAuth 动态客户端注册(
FRISIAN_MCP_OAUTH_REGISTRATION_OPEN=False、FRISIAN_MCP_OAUTH_PKCE_AUTO_REGISTER=False、FRISIAN_MCP_OAUTH_AUTO_APPROVE=False)。操作员会通过 Django admin 预先注册每个 OAuth 客户端;除非显式选择启用,否则无法进行匿名的即用即注册。 - PKCE 的默认权限层级为
read。 配置错误不会在首次连接时意外授予写入或管理员权限范围。 - 考虑权限的发现(
FRISIAN_MCP_PERMISSION_AWARE_DISCOVERY=True)会为每个请求重新构建 dispatcher 操作枚举——read层级的令牌只能看到list/retrieve操作;写入和管理员操作会从tools/list中隐藏,而不只是执行时被阻止。 .well-known发现元数据受FRISIAN_MCP_OAUTH_PUBLIC_DISCOVERY控制。将其设为False时,OAuth 元数据端点会返回可解析的 JSON 404,使优先进行发现的 MCP 客户端回退到已配置的 Bearer,而不是被导入无法继续的 OAuth 流程。- 验证器链的顺序不再影响正确性——
FrisianMcpTokenAuthentication和OAuthTokenAuthentication在查找未命中时都会返回None,因此无论顺序如何都能正常工作。推荐采用令牌优先的惯例,以获得合适的 WWW-Authenticate 挑战格式(见 docs/Getting Started/getting-started.md)。 - 已记录 SSE 保持连接的结构;当软件包检测到正在同步 WSGI worker 下运行时,会发出一次性运行时警告(此类 worker 无法在不耗尽 worker 池的情况下扩展 SSE)。推荐使用 ASGI worker 类(
uvicorn.workers.UvicornWorker或直接使用uvicorn)部署。
授权路径加固
未经身份验证的 OAuth 授权路径(AUTO_REGISTER)是一个即用即访问入口:请求输入描述调用方的需求,而不是调用方获准执行的操作。关于设计理由,请参阅 ADR-009;关于威胁模型和推荐部署模式,请参阅安全指南。
按路由划分权限等级
FRISIAN_MCP_ROUTES 会在不同路径上挂载 read、read_write 和 admin 接口,各自拥有独立的工具允许/拒绝列表,并在默认拒绝所有操作的基础上设置权限等级上限。某个路由拒绝的工具在该路由上并不存在——它不会出现在发现结果中,也无法调用,而不只是在调用时被拒绝。配置错误会在启动时被捕获;如果某个路由会在匿名状态下提供特权接口,服务将拒绝启动。有关模型及其安全依据,请参阅 ADR-010。
完整文档
完整的设置参考、身份验证配置、装饰器 API、中间件、可插拔后端、安全指南和故障排查内容均位于 docs/ 中。
如需浏览文档、访问运行中的 MCP 服务,以及使用 Agent 可读取的文档分发器(直接将其指向你的编码 Agent),请访问 https://frisian-mcp.com/。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。