mcpField
F
Frisian MCP (Django)

Frisian MCP (Django)

远程服务
frisian-mcp.com开发工具64 天前更新

关于 Frisian MCP (Django)

Frisian MCP (Django) 将 Django REST Framework 的 ViewSet 操作自动注册为 MCP 工具,面向需要向 Agent 开放现有 Django API 的团队。它支持调度器、细粒度权限控制和精简响应,以减少工具描述与写入结果占用的上下文。

主要功能

  1. 01自动发现 ViewSet 操作
  2. 02从序列化器生成工具架构
  3. 03将多个操作合并到调度器
  4. 04OAuth 2.0 与令牌认证
  5. 05按凭据和权限层级限制访问
  6. 06精简写入响应与延迟发现

适用场景

  1. 01将现有 DRF API 提供给 MCP 客户端
  2. 02按 Agent 凭据限制可用工具
  3. 03降低大量 API 操作的工具列表开销
  4. 04通过 Django 权限控制 API 调用

MCP 相关

提供基于 HTTP 的 MCP 服务,支持工具和资源发现及调用。它将 ViewSet 操作或自定义函数作为工具暴露,并可选地将多个操作汇总到单个调度器。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.frisian-mcp.com/mcp/
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

4
参数类型必填说明
modeenum否summary | paginated | filtered | full
pageinteger否
actionenum否要执行的操作。省略或使用 'help' 可列出所有可用操作及其必需参数。about | getting_started | integrations | security | demo | documents | rag
paramsobject否特定操作的参数。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_sizeinteger否
filter_keysarray否
continuation_tokenstring否来自探测响应。在顶层发送,不要放在 'params' 内。

详细介绍

frisian-mcp

OpenSSF Best Practices Slack MCP Queen operational grade

可自动发现 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.0contrib.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-25Streamable 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/list1,737 个扁平工具15 个分发器工具工具数量减少 ~99%
60 台设备的批量创建响应~10,798 个 token(完整回显)24 个 token(精简信封)99.8%
200 台设备的批量创建响应~36,000 个 token24 个 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/。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。