Skip to main content
Glama

MCPController

MCPController 是一个单管理员医生管理 MCP 应用。ChatGPT 通过 OAuth 2.1(带 PKCE)连接,管理员登录后选择授予哪些医生权限,MCP 服务器基于 MongoDB 提供医生工具。

架构

ChatGPT
  ↓
OAuth
  ↓
Admin Login
  ↓
Admin Consent
  ↓
Granted Permissions
  ↓
MCP Access Token
  ↓
MCP /mcp
  ↓
Permission Check
  ↓
Doctor Tools
  ↓
MongoDB

Related MCP server: aster-mcd-mcp-adapter

此应用的功能

  • 一个管理员拥有整个系统。

  • 没有公开注册,也没有多用户账户切换。

  • 管理员使用环境变量中的凭据进行身份验证。

  • 同意屏幕允许管理员批准 doctor:read、doctor:write 和 doctor:delete。

  • MCP 服务器在每次工具调用时再次检查已批准的 scope。

  • 医生数据通过简单的 Mongoose 模型存储在 MongoDB 中。

身份验证

浏览器会话与 MCP 承载令牌是分开的。

  • 浏览器会话:用于管理员 UI 和同意屏幕的 HTTP-only cookie。

  • MCP 访问令牌:ChatGPT 针对 /mcp 使用的 Bearer 令牌。

  • OAuth 使用带 PKCE 的授权码流程。

  • 授权码是一次性的且短期有效。

  • 访问令牌和刷新令牌在存储前会进行哈希处理。

管理员登录使用 .env 中的 ADMIN_EMAIL 和 ADMIN_PASSWORD。

医生管理

领域模型刻意保持精简:

  • name - 必填字符串

  • specialization - 必填字符串

  • createdAt / updatedAt - 由 Mongoose 时间戳管理

医生 CRUD 在服务层实现,并由 REST 管理 API 和 MCP 工具层复用。

OAuth 流程

  1. ChatGPT 打开授权端点。

  2. 如果管理员未通过身份验证,浏览器会转到 /login。

  3. 管理员登录。

  4. 同意页面显示请求的医生权限。

  5. 管理员批准子集或拒绝请求。

  6. 授权码被交换为访问令牌。

  7. ChatGPT 在 /mcp 上使用该令牌。

权限流程

请求的 scope 映射到 MCP 工具,如下所示:

  • doctor:read → list_doctors, get_doctor

  • doctor:write → add_doctor, update_doctor

  • doctor:delete → delete_doctor

后端强制执行两次权限:

  • OAuth 仅将已批准的 scope 写入授权码和令牌。

  • 每个 MCP 工具在接触 MongoDB 之前都会检查令牌 scope。

MCP 工具

工具

Scope

行为

list_doctors

doctor:read

返回所有医生

get_doctor

doctor:read

按 doctorId 返回单个医生

add_doctor

doctor:write

使用 name 和 specialization 创建医生

update_doctor

doctor:write

按 doctorId 更新医生

delete_doctor

doctor:delete

按 doctorId 删除医生

环境变量

使用根目录的 .env 文件。应用程序从项目根目录加载它。

本地 npm run dev(Vite 在 5173,API 在 3000)所需的值:

NODE_ENV=development
PORT=3000
APP_URL=http://localhost:5173
API_URL=http://localhost:3000
MONGODB_URI=mongodb://127.0.0.1:27017/mcpcontroller
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=change-this-password
JWT_SECRET=change-this-to-a-long-random-secret
MCP_SERVER_NAME=MCPController
MCP_SERVER_VERSION=1.0.0

代码还支持令牌/会话生命周期变量,并带有安全默认值:

  • JWT_EXPIRES_IN

  • AUTH_CODE_TTL_SECONDS

  • ACCESS_TOKEN_TTL_SECONDS

  • REFRESH_TOKEN_TTL_SECONDS

在 Vercel 上,APP_URL 和 API_URL 都必须为公共 HTTPS 源(请参阅下面的部署)。

本地设置

  1. 安装依赖:

npm install
  1. 在本地启动 MongoDB。

  2. 填充示例数据:

npm run seed
  1. 启动应用:

npm run dev

在开发环境中,React 客户端通过 Vite 运行,并将 API 请求代理到后端。

测试

使用以下命令运行自动化检查:

npm test

使用以下命令运行客户端构建:

npm run build

当前测试套件涵盖:

  • 管理员登录

  • 注册已禁用

  • 医生模型和 CRUD 服务

  • OAuth scope 批准

  • MCP 工具权限强制执行

  • 令牌撤销

连接 ChatGPT

使用服务器公开的授权 URL:

  • /.well-known/oauth-authorization-server

  • /.well-known/oauth-protected-resource

  • /oauth/token

  • /mcp

典型流程:

  1. ChatGPT 发现 OAuth 元数据。

  2. ChatGPT 请求 MCP 资源的授权。

  3. 浏览器重定向到管理员登录屏幕。

  4. 管理员查看权限并点击 Allow & Connect。

  5. ChatGPT 将代码交换为令牌。

  6. ChatGPT 使用 Bearer 令牌调用 MCP 工具。

部署

该应用是单一源:Express 提供 /api、/oauth、/mcp、OAuth 发现和 React 构建。

Vercel

此仓库已包含 vercel.json 和 api/index.js。Vercel 将 Express 应用作为单个 serverless 函数运行,并将每个路径重写到它。

1. MongoDB Atlas

  1. 创建一个集群(免费的 M0 就足够了)。

  2. 创建一个数据库用户。

  3. 网络访问:允许 0.0.0.0/0,以便 Vercel 可以连接(或者如果您愿意,可以添加 Vercel IP)。

  4. 复制连接字符串,例如:

mongodb+srv://USER:PASSWORD@cluster0.xxxxx.mongodb.net/mcpcontroller?retryWrites=true&w=majority

2. 部署项目

  • 将此仓库推送到 GitHub。

  • 在 Vercel 中,导入仓库。

  • 框架预设:其他(保留)。vercel.json 设置安装和构建。

  • 根目录:保留为仓库根目录(不要设置为 client 或 server)。

  • Node.js 版本:20.x 或更高。

3. Vercel 中的环境变量

项目 → 设置 → 环境变量。为生产环境(以及如果您使用预览 URL,则为预览环境)设置它们。

名称

示例

说明

NODE_ENV

production

Vercel 通常会自动设置此项。

APP_URL

https://your-app.vercel.app

无尾部斜杠。必须与实时源匹配。

API_URL

https://your-app.vercel.app

在 Vercel 上与 APP_URL 相同。

MONGODB_URI

mongodb+srv://…/mcpcontroller

Atlas URI。

ADMIN_EMAIL

您的管理员邮箱

用于登录同意 UI。

ADMIN_PASSWORD

强密码

登录时比较;绝不会发送到浏览器。

JWT_SECRET

长随机字符串

会话 cookie 签名。不要使用示例值。

JWT_EXPIRES_IN

7d

可选。

AUTH_CODE_TTL_SECONDS

120

可选。

ACCESS_TOKEN_TTL_SECONDS

3600

可选。

REFRESH_TOKEN_TTL_SECONDS

2592000

可选。

MCP_SERVER_NAME

MCPController

可选。

MCP_SERVER_VERSION

1.0.0

可选。

不要将 ADMIN_PASSWORD 或 JWT_SECRET 放入 React 应用中。客户端只与 /api 通信。

如果您稍后添加自定义域,请将 APP_URL 和 API_URL 更改为 https://your-domain.com 并重新部署。

使用以下命令生成 JWT_SECRET:

node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"

4. 首次部署和填充

  1. 部署。

  2. 打开 https://your-app.vercel.app/api/health — 您应该看到 { "ok": true, ... }。

  3. 从您的机器(指向 Atlas,而不是 Vercel 的 serverless 函数)填充 MongoDB:

# In the project root, temporarily set MONGODB_URI to the Atlas URI in .env
npm run seed

填充会创建管理员用户行、示例医生和本地 MCP Inspector 客户端。之后,使用 ADMIN_EMAIL / ADMIN_PASSWORD 在实时站点上登录。

5. 连接 ChatGPT

使用部署的源:

  • https://your-app.vercel.app/.well-known/oauth-authorization-server

  • https://your-app.vercel.app/.well-known/oauth-protected-resource

  • https://your-app.vercel.app/mcp

在 ChatGPT(或 MCP Inspector)中,添加该 MCP URL。ChatGPT 将在同一域上打开登录 + 同意屏幕,然后使用 Bearer 令牌调用 /mcp。

CLI 部署(可选)

npm i -g vercel
vercel login
vercel env pull   # optional: sync env locally
vercel --prod

在首次生产部署后,如果您使用了占位符,请将 URL 复制到 APP_URL 和 API_URL 中,然后重新部署,以便 OAuth 元数据指向真实源。

安全说明

  • 不要将 ADMIN_PASSWORD 或 JWT_SECRET 暴露给浏览器。

  • 在数据库中保持 OAuth 令牌的哈希值。

  • 只批准管理员实际希望 ChatGPT 使用的 scope。

  • 当连接不再可信时,撤销访问权限。

  • 管理员登录仅用于授权 ChatGPT 和管理医生数据;没有公开注册流程。

填充数据

填充脚本创建:

  • 示例医生

  • 用于本地 Inspector 使用的示例 OAuth 客户端

它不会创建演示用户或硬编码管理员凭据。

Related MCP Connectors

Related MCP Servers