Remote MCP · OAuth 2.1 · Next.js

Agent 如何安全地操作小组、成员与资源

Agent 只看见 MCP 工具;OAuth 负责把登录账号的权限委托给 Agent;领域服务仍然是唯一的数据与权限入口。REST/OpenAPI 保留给非 Agent 开发与契约检查。

Remote MCP endpointhttps://growthengineer.space/mcp

一张图看懂整体架构

Agent / MCP Client
  • 读取 /agent.md
  • 连接 Streamable HTTP
  • 自动发现 OAuth
  • 通过 tools/list 感知能力
Next.js MCP Gateway
  • mcp-handler 无状态传输
  • JWT 本地验签与 scope 检查
  • Zod 工具输入校验
  • 危险工具强制 confirm=true
Domain / Data Layer
  • groups.ts 权限真源
  • Neon Postgres
  • pending / active / rejected 状态
  • Cloudflare 邮件邀请与审核通知
入口层/mcp、OAuth discovery、授权确认页面
协议层MCP Streamable HTTP、OAuth 2.1、PKCE S256、RFC 9728 protected resource metadata
工具层小组 CRUD、成员检索/维护、邀请/申请/审核、资源/案例完整 CRUD、Admin 工具
领域层待审核者不可读取成员、创始人不可删除、管理员不能授予管理员、后台管理员实时校验、积分内容访问控制
数据层Postgres 状态与唯一约束、成员检索 GIN 索引、一次性授权码哈希、刷新令牌哈希与轮换

用户连接 Agent 的完整流程

交给 Agent用户复制 /agent 页面中的提示词。
连接 MCPAgent 连接 /mcp,收到 401 与 protected-resource 地址。
自动发现客户端读取 OAuth metadata,并用 PKCE 注册/发起授权。
浏览器确认用户可在任何已登录本站的电脑查看 scope 并确认;OpenClaw 会进入站内完成页复制一次性授权码,其他客户端继续标准回调。
自动回调授权码返回客户端,客户端用 code_verifier 换取短期 access token。
调用工具客户端发现工具;每次调用同时校验 token scope 与账号领域权限。
用户不再复制 Token。 OAuth 回调由 MCP 客户端自动完成。access token 15 分钟过期;refresh token 保存为哈希,并在每次刷新后轮换。

工具、数据范围与权限

工具域代表工具Scope额外规则
小组groups_list/create/update/deletegroups:read / write删除需二次确认并输入准确组名;普通账号只看已正式加入的小组
成员group_members_search/update/removegroups:read / write只返回 active 成员;表单挂在 membership 下,可持续编辑
邀请与审核group_invites_creategroup_joingroup_applications_list/reviewgroups:read / write邀请默认永久;完整表单先进入 pending,审核通过后才获得目录访问权
内容查询resources_list/get/minecases_list/get/minegroups:read公开内容遵守积分访问;mine 返回本人全部审核状态与可编辑字段
内容维护resources_create/update/deletecases_create/update/deletegroups:write只可维护本人投稿;已发布内容的修改先进入待审核状态;删除需要二次确认
后台admin_groups_list/get/deleteadmin:read / write还必须是当前后台管理员;scope 不能提权

Agent 可以直接问“我想找西语外链,我可以找谁?”,然后调用 group_members_search,只在该账号可见的小组成员表单里匹配并给出依据。

为什么 MCP 不会成为性能瓶颈

01

无状态 HTTP

只启用 Streamable HTTP,关闭旧 SSE;无需 Redis 会话,可水平扩容。

02

本地 JWT 验签

每个 MCP 请求不查 token 表,避免额外数据库 RTT;refresh 才查库。

03

有界返回

小组/成员最多 100 条,跨组成员检索、资源和案例最多 50 条;管理员通知收件人也有上限。

04

直达领域服务

MCP handler 不再 HTTP 回调自己的 REST API,减少序列化和网络开销。

05

索引化成员搜索

active 成员使用 PostgreSQL trigram GIN 索引;跨组可见性通过单条 EXISTS 查询完成,避免先扫小组再逐组查询。

06

异步邮件边界

加入申请先快速响应,审核邮件通过响应后的任务发送;单次 MCP Function 最长 30 秒,错误不泄露内部堆栈。

OpenAPI 如何随 REST 接口自动更新

共享 Zod Schema
  • 运行时校验请求
  • 成员表单与 CRUD 输入真源
API_CONTRACTS Registry
  • method / path / operationId
  • scope / body / query
  • z.toJSONSchema()
/openapi.json
  • 运行时生成 OpenAPI 3.1
  • 无需手写重复 schema
  • 新增 route 未登记会测试失败
改动共享 Zod schema,OpenAPI 请求结构会自动变化;新增、删除或改名 REST method/path 时,openapi:check 会比对所有 api/v1/**/route.ts,防止文档静默过期。

RESTful 跟 OpenAPI 有何区别?

RESTful

一种 API 设计风格

它规定运行时如何把业务表达成资源与 HTTP 语义:例如 GET /groups 查询、PATCH /groups/{id} 修改、无状态请求、正确状态码。

OpenAPI

一份机器可读的接口合同

它描述一个 HTTP API 有哪些 path、method、参数、数据结构、认证方式和响应,可用于文档、SDK、Mock 与契约测试。

关系:RESTful 是“接口怎么设计和运行”,OpenAPI 是“怎么准确描述这套接口”。REST API 可以没有 OpenAPI;OpenAPI 也能描述不太 RESTful 的 RPC 风格 HTTP 接口。这里 Agent 使用 MCP,普通开发/内部集成使用 REST,OpenAPI 自动描述 REST。

关键地址

https://growthengineer.space/mcphttps://growthengineer.space/agent.mdhttps://growthengineer.space/.well-known/oauth-protected-resourcehttps://growthengineer.space/.well-known/oauth-authorization-serverhttps://growthengineer.space/openapi.json