教程:构建一个待办事项管理器
MCP Auth 也支持 Python!请查看 Python SDK 仓库 了解安装和用法。
在本教程中,我们将构建一个带有用户认证 (Authentication) 和授权 (Authorization) 的待办事项管理器 MCP 服务器。按照最新的 MCP 规范,我们的 MCP 服务器将作为 OAuth 2.0 资源服务器 (Resource Server),用于验证访问令牌 (Access token) 并强制执行基于权限 (Scope) 的权限控制。
完成本教程后,你将获得:
- ✅ 对如何在 MCP 服务器中设置基于角色的访问控制 (RBAC) 有基本了解
- ✅ 一个作为资源服务器 (Resource Server) 的 MCP 服务器,能够消费由授权服务器 (Authorization Server) 签发的访问令牌 (Access token)
- ✅ 一个基于权限 (Scope) 强制执行待办事项操作权限的工作实现
概览
本教程涉及以下组件:
- MCP 客户端(VS Code):一个内置 MCP 支持的代码编辑器,作为 OAuth 2.0/OIDC 客户端。它发起与授权服务器的授权流程,并获取访问令牌 (Access token) 以认证 (Authentication) 对 MCP 服务器的请求。
- 授权服务器 (Authorization Server):一个 OAuth 2.1 或 OpenID Connect 提供商,负责管理用户身份、认证 (Authentication) 用户,并向授权客户端签发带有相应权限 (Scope) 的访问令牌 (Access token)。
- MCP 服务器(资源服务器 Resource Server):根据最新的 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为资源服务器 (Resource Server)。它验证授权服务器签发的访问令牌 (Access token),并对待办事项操作强制执行基于权限 (Scope) 的权限控制。
该架构遵循标准的 OAuth 2.0 流程:
- VS Code 代表用户请求受保护资源
- 授权服务器 (Authorization Server) 认证 (Authentication) 用户并签发访问令牌 (Access token)
- MCP 服务器 验证令牌并根据授予的权限 (Scope) 提供受保护资源
以下是这些组件之间交互的高级流程图:
了解你的授权服务器
带权限 (Scope) 的访问令牌 (Access token)
要在 MCP 服务器中实现基于角色的访问控制 (RBAC),你的授权服务器需要支持签发带有权限 (Scope) 的访问令牌 (Access token)。权限 (Scope) 代表用户被授予的权限。
- Logto
- OAuth 2.0 / OIDC
Logto 通过其 API 资源(符合 RFC 8707: OAuth 2.0 的资源指示器 Resource Indicators)和角色 (Role) 功能提供 RBAC 支持。设置方法如下:
-
登录 Logto 控制台(或你的自托管 Logto 控制台)
-
创建 API 资源和权限 (Scope):
- 进入“API 资源”
- 创建一个名为“Todo Manager”的新 API 资源
- 添加以下权限 (Scope):
create:todos:“创建新的待办事项”read:todos:“读取所有待办事项”delete:todos:“删除任意待办事项”
-
创建角色 (Role)(推荐,便于管理):
- 进入“角色 (Roles)”
- 创建一个“Admin”角色,并分配所有权限 (
create:todos,read:todos,delete:todos) - 创建一个“User”角色,仅分配
create:todos权限
-
分配权限:
- 进入“用户”
- 选择一个用户
- 你可以:
- 在“角色 (Roles)”标签页分配角色(推荐)
- 或在“权限 (Permissions)”标签页直接分配权限 (Scope)
这些权限 (Scope) 会以空格分隔字符串的形式包含在 JWT 访问令牌 (Access token) 的 scope 声明 (Claim) 中。
OAuth 2.0 / OIDC 提供商通常支持基于权限 (Scope) 的访问控制。实现 RBAC 时:
- 在授权服务器中定义所需的权限 (Scope)
- 配置客户端在授权流程中请求这些权限 (Scope)
- 确保授权服务器在访问令牌 (Access token) 中包含授予的权限 (Scope)
- 权限 (Scope) 通常包含在 JWT 访问令牌 (Access token) 的
scope声明 (Claim) 中
请查阅你的提供商文档,了解以下内容:
- 如何定义和管理权限 (Scope)
- 权限 (Scope) 如何包含在访问令牌 (Access token) 中
- 是否有额外的 RBAC 功能,如角色 (Role) 管理
验证令牌并检查权限
根据最新的 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为资源服务器 (Resource Server)。作为资源服务器 (Resource Server),MCP 服务器有以下职责:
- 令牌验证:验证从 MCP 客户端收到的访问令牌 (Access token) 的真实性和完整性
- 权限 (Scope) 强制执行:从访问令牌 (Access token) 中提取并验证权限 (Scope),以确定客户端被授权执行哪些操作
- 资源保护:仅在客户端提供有效且权限 (Scope) 足够的令牌时,才提供受保护资源(执行工具)
当你的 MCP 服务器收到请求时,会执行如下验证流程:
- 从
Authorization头中提取访问令牌 (Access token)(Bearer token 格式) - 验证访问令牌 (Access token) 的签名和过期时间
- 从已验证的令牌中提取权限 (Scope) 和用户信息
- 检查令牌是否包含请求操作所需的权限 (Scope)
例如,如果用户想创建新的待办事项,其访问令牌 (Access token) 必须包含 create:todos 权限 (Scope)。以下是资源服务器 (Resource Server) 验证流程:
动态客户端注册
本教程不要求动态客户端注册,但如果你希望自动化 MCP 客户端与授权服务器的注册流程,可以参考 是否需要动态客户端注册? 了解详情。
了解待办事项管理器中的 RBAC
为了演示,我们将在待办事项管理器 MCP 服务器中实现一个简单的基于角色的访问控制 (RBAC) 系统。这将向你展示 RBAC 的基本原理,同时保持实现简洁。
虽然本教程演示了基于 RBAC 的权限 (Scope) 管理,但需要注意,并非所有认证 (Authentication) 提供商都通过角色 (Role) 实现权限 (Scope) 管理。有些提供商可能有自己独特的访问控制和权限管理机制。
工具与权限 (Scope)
我们的待办事项管理器 MCP 服务器提供三个主要工具:
create-todo:创建新的待办事项get-todos:列出所有待办事项delete-todo:按 ID 删除待办事项
为了控制对这些工具的访问,我们定义了以下权限 (Scope):
create:todos:允许创建新的待办事项delete:todos:允许删除现有待办事项read:todos:允许查询和获取所有待办事项列表
角色 (Role) 与权限 (Permission)
我们将定义两个具有不同访问级别的角色 (Role):
| 角色 (Role) | create:todos | read:todos | delete:todos |
|---|---|---|---|
| Admin | ✅ | ✅ | ✅ |
| User | ✅ |
- User:普通用户,可以创建待办事项,并仅查看或删除自己的待办事项
- Admin:管理员,可以创建、查看和删除所有待办事项,无论归属谁
资源归属
虽然上表显示了每个角色 (Role) 明确分配的权限 (Scope),但还有一个重要的资源归属原则:
- User 没有
read:todos或delete:todos权限 (Scope),但他们仍然可以:- 查看自己的待办事项
- 删除自己的待办事项
- Admin 拥有全部权限 (
read:todos和delete:todos),可以:- 查看系统中所有待办事项
- 删除任意待办事项,无论归属谁
这体现了 RBAC 系统中的常见模式:资源归属为用户自己的资源隐式授予权限,而管理员角色 (Role) 则对所有资源拥有显式权限。
想深入了解 RBAC 概念和最佳实践,请查看 精通 RBAC:一个全面的真实案例。
在你的提供商中配置授权 (Authorization)
要实现我们前述的访问控制系统,你需要在授权服务器中配置所需的权限 (Scope)。不同提供商的配置方法如下:
- Logto
- OAuth 2 / OIDC
Logto 通过其 API 资源和角色 (Role) 功能提供 RBAC 支持。设置方法如下:
-
登录 Logto 控制台(或你的自托管 Logto 控制台)
-
创建 API 资源和权限 (Scope):
- 进入“API 资源”
- 创建一个名为“Todo Manager”的新 API 资源,并使用
http://localhost:3001/作为资源指示器 (Resource indicator)。- 重要:资源指示器 (Resource indicator) 必须与你的 MCP 服务器 URL 完全一致。本教程使用
http://localhost:3001/,因为 MCP 服务器运行在 3001 端口。生产环境请使用实际 MCP 服务器 URL(如https://your-mcp-server.example.com/)。
- 重要:资源指示器 (Resource indicator) 必须与你的 MCP 服务器 URL 完全一致。本教程使用
- 创建以下权限 (Scope):
create:todos:“创建新的待办事项”read:todos:“读取所有待办事项”delete:todos:“删除任意待办事项”
-
创建角色 (Role)(推荐,便于管理):
- 进入“角色 (Roles)”
- 创建一个“Admin”角色,并分配所有权限 (
create:todos,read:todos,delete:todos) - 创建一个“User”角色,仅分配
create:todos权限 - 在“User”角色详情页,切换到“常规”标签,并将“User”角色设置为“默认角色 (Default role)”。
-
管理用户角色 (Role) 和权限 (Permission):
- 新用户:
- 因为设置了默认角色,注册后会自动获得“User”角色
- 已有用户:
- 进入“用户管理”
- 选择一个用户
- 在“角色 (Roles)”标签页为用户分配角色
- 新用户:
你也可以使用 Logto 的 Management API 以编程方式管理用户角色 (Role)。这对于自动化用户管理或构建管理后台特别有用。
请求访问令牌 (Access token) 时,Logto 会根据用户角色 (Role) 权限将权限 (Scope) 包含在令牌的 scope 声明 (Claim) 中。
对于 OAuth 2.0 或 OpenID Connect 提供商,你需要配置代表不同权限的权限 (Scope)。具体步骤视你的提供商而定,但通常包括:
-
定义权限 (Scope):
- 配置授权服务器支持:
create:todosread:todosdelete:todos
- 配置授权服务器支持:
-
配置客户端:
- 注册或更新你的客户端以请求这些权限 (Scope)
- 确保权限 (Scope) 被包含在访问令牌 (Access token) 中
-
分配权限 (Permission):
- 使用你的提供商界面为用户授予相应权限 (Scope)
- 有些提供商支持基于角色 (Role) 的管理,有些则直接分配权限 (Scope)
- 查阅你的提供商文档,了解推荐做法
大多数提供商会将授予的权限 (Scope) 以空格分隔字符串的形式包含在访问令牌 (Access token) 的 scope 声明 (Claim) 中。
资源指示器 (Resource indicator) 一定要带上末尾斜杠(/)。由于 MCP 官方 SDK 当前存在一个 bug,使用该 SDK 的客户端在发起认证 (Authentication) 请求时会自动在资源标识符后追加斜杠。如果你的资源指示器没有斜杠,这些客户端的资源验证会失败。(VS Code 不受此 bug 影响。)
配置好授权服务器后,用户将获得包含其权限 (Scope) 的访问令牌 (Access token)。MCP 服务器将使用这些权限 (Scope) 判断:
- 用户是否可以创建新的待办事项(
create:todos) - 用户是否可以查看所有待办事项(
read:todos)或仅能查看自己的 - 用户是否可以删除任意待办事项(
delete:todos)或仅能删除自己的
搭建 MCP 服务器
我们将使用 MCP 官方 SDK 创建我们的待办事项管理器 MCP 服务器。
创建新项目
创建一个新的 Node.js 项目:
mkdir mcp-server
cd mcp-server
npm init -y # 或使用 `pnpm init`
npm pkg set type="module"
npm pkg set main="todo-manager.ts"
npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
我们的示例使用 TypeScript,因为 Node.js v22.6.0+ 原生支持通过 --experimental-strip-types 运行 TypeScript。如果你使用 JavaScript,代码类似——只需确保 Node.js 版本为 v22.6.0 或更高。详见 Node.js 官方文档。
安装 MCP SDK 及依赖
npm install @modelcontextprotocol/sdk express zod
或使用你喜欢的包管理器,如 pnpm 或 yarn。
创建 MCP 服务器
创建名为 todo-manager.ts 的文件,并添加如下代码:
(代码部分保持原样,不翻译)
运行服务器:
npm start
与授权服务器集成
完成本节前,你需要考虑以下事项:
你的授权服务器的发行者 (Issuer) URL
通常是你的授权服务器的基础 URL,如 https://auth.example.com。有些提供商可能是 https://example.logto.app/oidc,请查阅你的提供商文档。
如何获取授权服务器元数据
- 如果你的授权服务器符合 OAuth 2.0 授权服务器元数据 或 OpenID Connect 发现,你可以使用 MCP Auth 内置工具自动获取元数据。
- 如果不符合这些标准,你需要在 MCP 服务器配置中手动指定元数据 URL 或端点。请查阅你的提供商文档。
如何在授权服务器注册 MCP 客户端
- 如果你的授权服务器支持 动态客户端注册,可以跳过此步骤,MCP 客户端会自动注册。
- 如果不支持动态客户端注册,你需要手动在授权服务器注册 MCP 客户端。
了解令牌请求参数
向不同授权服务器请求访问令牌 (Access token) 时,指定目标资源和权限 (Scope) 的方式各有不同。主要模式如下:
-
基于资源指示器 (Resource indicator):
- 使用
resource参数指定目标 API(见 RFC 8707: OAuth 2.0 的资源指示器) - 现代 OAuth 2.0 实现常见
- 示例请求:
{ "resource": "http://localhost:3001/", "scope": "create:todos read:todos" } - 服务器签发专门绑定到请求资源的令牌
- 使用
-
基于受众 (Audience):
- 使用
audience参数指定令牌接收方 - 与资源指示器类似,但语义不同
- 示例请求:
{ "audience": "todo-api", "scope": "create:todos read:todos" }
- 使用
-
纯权限 (Scope) 模式:
- 仅依赖权限 (Scope),无资源/受众参数
- 传统 OAuth 2.0 做法
- 示例请求:
{ "scope": "todo-api:create todo-api:read openid profile" } - 通常用前缀权限 (Scope) 进行命名空间隔离
- 简单 OAuth 2.0 实现常见
- 查阅你的提供商文档,了解支持哪些参数
- 有些提供商同时支持多种方式
- 资源指示器 (Resource indicator) 通过受众限制提升安全性
- 如可用,优先使用资源指示器 (Resource indicator) 以获得更好的访问控制
每个提供商可能有自己的具体要求,以下步骤将指导你如何结合 VS Code 和 MCP 服务器进行集成,并进行针对性配置。
注册 MCP 客户端为第三方应用
- Logto
- OAuth 2.0 / OIDC
将待办事项管理器与 Logto 集成非常简单,因为它是支持资源指示器 (Resource indicator) 和权限 (Scope) 的 OpenID Connect 提供商,可以用 http://localhost:3001/ 作为资源指示器保护你的 todo API。
由于 Logto 目前尚不支持动态客户端注册,你需要手动将 MCP 客户端(VS Code)注册为 Logto 租户的第三方应用:
- 登录 Logto 控制台(或你的自托管 Logto 控制台)。
- 进入 应用程序 > 第三方应用,点击“创建应用”。
- 选择 原生应用 (Native App) 作为应用类型。
- 填写应用信息:
- 应用名称:如“MCP Client”
- 描述:如“VS Code 的 MCP 客户端”
- 为 VS Code 设置以下 重定向 URI:
http://127.0.0.1 https://vscode.dev/redirect - 点击“保存更改”。
- 进入应用的 权限 (Permissions) 标签页,在 用户 部分,添加你之前创建的 Todo Manager API 资源下的
create:todos、read:todos和delete:todos权限。 - 在顶部卡片中,你会看到“App ID”值。复制备用。
这是通用的 OAuth 2.0 / OpenID Connect 提供商集成指南。OAuth 2.0 和 OIDC 步骤类似,因为 OIDC 构建在 OAuth 2.0 之上。具体细节请查阅你的提供商文档。
如果你的提供商支持动态客户端注册,可以跳过手动注册;否则需要手动注册 MCP 客户端:
-
登录你的提供商控制台。
-
进入“应用程序”或“客户端”部分,创建新应用或客户端。
-
如需选择客户端类型,选择“原生应用 (Native App)”或“公共客户端 (Public client)”。
-
创建应用后,配置重定向 URI。对于 VS Code,添加如下:
http://127.0.0.1 https://vscode.dev/redirect -
为应用配置所需权限 (Scope):
create:todos read:todos delete:todos -
找到新建应用的“Client ID”或“Application ID”,复制备用。
设置 MCP Auth
首先,在 MCP 服务器项目中安装 MCP Auth SDK。
- pnpm
- npm
- yarn
pnpm add mcp-authnpm install mcp-authyarn add mcp-auth现在需要在 MCP 服务器中初始化 MCP Auth。在受保护资源模式下,你需要配置资源元数据,包括授权服务器信息。
配置授权服务器有两种方式:
- 预获取(推荐):使用
fetchServerConfig()在初始化 MCPAuth 前获取元数据,确保启动时配置已验证。 - 按需发现:只提供
issuer和type,首次需要时再获取元数据。适用于如 Cloudflare Workers 等不允许顶层异步 fetch 的边缘运行时。
配置受保护资源元数据
首先,获取你的授权服务器发行者 (Issuer) URL:
- Logto
- OAuth 2.0 / OIDC
在 Logto 中,你可以在 Logto 控制台的应用详情页“端点与凭据 / 发行者端点 (Issuer endpoint)”部分找到发行者 (Issuer) URL,格式类似 https://my-project.logto.app/oidc。
对于 OAuth 2.0 提供商,你需要:
- 查阅你的提供商文档,获取授权服务器 URL(通常称为发行者 (Issuer) URL 或基础 URL)
- 有些提供商会在
https://{your-domain}/.well-known/oauth-authorization-server暴露此信息 - 在提供商管理后台的 OAuth/API 设置中查找
现在,在构建 MCP Auth 实例时配置受保护资源元数据:
(代码部分保持原样,不翻译)
更新 MCP 服务器
我们快完成了!现在需要更新 MCP 服务器,应用 MCP Auth 路由和中间件,并基于用户权限 (Scope) 实现待办事项工具的权限控制。
首先,应用受保护资源元数据路由,让 MCP 客户端可以从 MCP 服务器获取资源元数据。
(代码部分保持原样,不翻译)
接下来,应用 MCP Auth 中间件到 MCP 服务器。该中间件会处理所有请求的认证 (Authentication) 和授权 (Authorization),确保只有被授权的用户才能访问待办事项工具。
(代码部分保持原样,不翻译)
现在,我们可以更新待办事项工具的实现,利用 MCP Auth 中间件进行认证 (Authentication) 和授权 (Authorization)。
(代码部分保持原样,不翻译)
接下来,创建上面代码中用到的“Todo service”:
创建 todo-service.ts 文件,实现相关功能:
(代码部分保持原样,不翻译)
恭喜!我们已经成功实现了一个带有认证 (Authentication) 和授权 (Authorization) 的完整 MCP 服务器!
查看 MCP Auth Node.js SDK 仓库 获取 MCP 服务器(OIDC 版本)的完整代码。
检查点:运行 todo-manager 工具
重启你的 MCP 服务器,并用 VS Code 连接它。以下是带认证 (Authentication) 的连接方法:
- 在 VS Code 中,按下
Command + Shift + P(macOS)或Ctrl + Shift + P(Windows/Linux)打开命令面板。 - 输入
MCP: Add Server...并选择它。 - 选择
HTTP作为服务器类型。 - 输入 MCP 服务器 URL:
http://localhost:3001 - OAuth 请求发起后,VS Code 会提示你输入 App ID。输入你从授权服务器复制的 App ID。
- 因为我们没有 App Secret(这是公共客户端),直接回车跳过。
- 在浏览器中完成登录流程。
登录并返回 VS Code 后,重复上一个检查点的操作,运行待办事项管理器工具。这一次,你可以用已认证 (Authentication) 的用户身份使用这些工具。工具的行为将取决于你用户的角色 (Role) 和权限 (Permission):
-
如果你以 User(仅有
create:todos权限)身份登录:- 可以用
create-todo工具创建新待办事项 - 只能查看和删除自己的待办事项
- 无法查看或删除其他用户的待办事项
- 可以用
-
如果你以 Admin(拥有全部权限:
create:todos、read:todos、delete:todos)身份登录:- 可以创建新待办事项
- 可以用
get-todos工具查看系统中所有待办事项 - 可以用
delete-todo工具删除任意待办事项,无论归属谁
你可以通过以下方式测试不同权限级别:
- 断开 MCP 服务器连接(在 VS Code 中移除服务器配置)
- 用拥有不同角色 (Role)/权限 (Permission) 的其他用户账号登录
- 再次尝试相同工具,观察因用户权限不同而产生的行为变化
这展示了基于角色的访问控制 (RBAC) 在实际中的工作方式,不同用户对系统功能有不同访问级别。
查看 MCP Auth Node.js SDK 仓库 获取 MCP 服务器(OIDC 版本)的完整代码。
结语
恭喜!你已成功完成本教程。让我们回顾一下所做的内容:
- 搭建了一个基础的 MCP 服务器,包含待办事项管理工具(
create-todo、get-todos、delete-todo) - 实现了基于角色的访问控制 (RBAC),为用户和管理员设置了不同权限级别
- 使用 MCP Auth 将 MCP 服务器与授权服务器集成
- 配置 VS Code 认证 (Authentication) 用户,并用带权限 (Scope) 的访问令牌 (Access token) 调用工具
欢迎查阅其他教程和文档,充分发挥 MCP Auth 的强大能力。