启用第三方 AI 代理访问你的 MCP 服务器
探索 Logto 的 AI 解决方案:为 MCP 服务器、AI 代理和应用提供认证 (Authentication) 与授权 (Authorization)。
本指南将带你通过 mcp-auth 和 MCP 官方 SDK v2,将 Logto 集成到你的 MCP 服务器中,使第三方 AI 代理能够在用户同意的情况下认证 (Authentication) 用户并安全访问你的 MCP 服务器。
你将学会如何:
- 配置 Logto 作为你的 MCP 服务器的授权 (Authorization) 服务器。
- 接入第三方 AI 代理,可以通过注册第三方应用,或启用 动态应用,让任何代理无需预注册即可连接。
- 在你的 MCP 服务器中设置 “whoami” 工具,用于返回当前用户的身份声明 (Claims)。
- 使用第三方 AI 代理(MCP 客户端)测试整个流程。
完成本教程后,你的 MCP 服务器将能够:
- 在你的 Logto 租户中认证 (Authentication) 用户,并获得用户对第三方 AI 代理的同意。
- 验证由 Logto 签发的 JWT 访问令牌(签名、发行者 (Issuer)、受众 (Audience) 和过期时间)。
- 为 “whoami” 工具调用返回已验证的身份声明 (Claims)(如
sub、iss、aud等)。
本指南的完整可运行示例代码可在 mcp-auth/js 仓库中找到:
whoami-express:本指南中的 "whoami" 服务器,基于 Node.js 和 Express。whoami:同样的服务器,基于 fetch-native(Web 标准的Request/Response,使用 Hono),可部署到 Cloudflare Workers。
第三方 AI 代理(MCP 客户端)与你自己的 MCP 客户端的区别
让我们来看一个例子。假设你是一名开发者,运行着一个 MCP 服务器来管理邮件访问和自动化。
官方邮件应用(你自己的 MCP 客户端)
- 你为用户提供了一个官方邮件应用,用于读取和管理他们的邮件。
- 工作方式:官方邮件应用通过 Logto 连接到你的 MCP 服务器进行用户认证 (Authentication)。当 Alice 登录时,她会自动获得邮件访问权限,无需额外的权限页面,因为这是你信任的应用。
第三方 AI 代理(第三方 MCP 客户端)
- 你正在围绕你的 MCP 服务器构建一个生态系统,因此另一位开发者创建了 “SmartMail AI”(一个可以自动总结邮件和安排会议的 AI 助手),并将其作为第三方客户端集成。
- 工作方式:SmartMail AI(第三方 MCP 客户端)希望通过你的 MCP 服务器访问用户邮件。当 Alice 使用她的账户登录 SmartMail AI 时:
- 她会看到一个用户授权页面 (Consent screen),询问是否允许 SmartMail AI 读取她的邮件和日历。
- Alice 可以允许或拒绝此访问。
- 只有她同意的数据才会被共享给 SmartMail AI,SmartMail AI 无法在未明确重新同意的情况下访问其他数据。
这种访问(权限)控制确保了用户数据的安全,即使你的 MCP 服务器管理所有数据,像 SmartMail AI 这样的第三方应用也只能访问用户明确允许的数据。他们无法绕过这个过程,因为这是由你在 MCP 服务器中实现的访问控制所强制执行的。
总结
| 客户端类型 | 示例 | 是否需要同意? | 谁控制? |
|---|---|---|---|
| 官方邮件应用 | 你自己的邮件应用 | 否 | 你(开发者) |
| 第三方 AI 代理 | SmartMail AI 助手 | 是 | 其他开发者 |
如果你想将 MCP 服务器与你自己的 AI 代理或应用集成,请参考 为你的 MCP 驱动应用启用 Logto 认证 (Authentication) 指南。
前置条件
- 一个 Logto Cloud(或自托管)租户
- Node.js >= 20 环境
理解架构
- MCP 服务器:向 MCP 客户端暴露工具和资源的服务器。遵循最新 MCP 规范,它作为 OAuth 2.0 资源服务器,验证由 Logto 签发的访问令牌 (Access token)。
- MCP 客户端:用于发起认证 (Authentication) 流程并测试集成的客户端。在本指南中,第三方 AI agent 将作为客户端使用。
- Logto:作为 OpenID Connect 提供方(授权 (Authorization) 服务器),管理用户身份,并为你的 MCP 服务器签发受受众 (Audience) 绑定的 JWT 访问令牌 (Access token)。
下面的非规范时序图展示了整个流程:
由于 MCP 发展迅速,上述流程图可能不是最新。请参考 mcp-auth 文档获取最新信息。
在 Logto 中配置第三方 AI 代理
为了让第三方 AI 代理能够访问你的 MCP server,你需要在 Logto 中设置一个第三方应用。该应用将用于代表 AI 代理,并获取认证 (Authentication) 和授权 (Authorization) 所需的凭据。
第三方应用是由外部开发者(非资源所有者)创建的应用程序,需要用户同意才能访问受保护资源。与第一方应用(你自己的应用程序)不同,第三方应用会显示用户授权页面 (Consent screen),在访问用户数据前请求用户批准特定权限。这确保了用户可以控制与外部服务共享哪些数据。
了解更多,请参阅 第三方应用程序。
接入 AI 代理有三种方式:
- 在控制台手动创建应用,适用于测试或少量已知代理。
- 基于 Management API 构建注册服务,如果你希望控制谁能获取凭据。
- 启用动态应用,如果任何代理都可能接入且你不希望有注册步骤。
允许开发者在 Logto 中创建第三方应用
如果你正在构建一个市场或希望允许开发者在 Logto 中创建第三方应用,可以利用 Logto Management API 以编程方式创建第三方应用。这样开发者可以注册他们的应用并获取认证 (Authentication) 所需的凭据。
你需要托管自己的服务来处理客户端注册流程。该服务将与 Logto Management API 交互,代表开发者创建第三方应用。
另外,你也可以在 Logto 控制台手动创建第三方应用,以熟悉整个流程。
允许任何 AI 代理无需预注册即可接入
在开放的 MCP 生态系统中,你通常无法提前知道所有代理。动态应用 移除了注册步骤:代理使用一个公开的 HTTPS URL 提供自己的客户端元数据文档作为其 client_id,Logto 在收到授权 (Authorization) 请求时解析它。
你仍然可以通过授予动态应用的权限来控制代理可请求的内容,并且每次授权 (Authorization) 都会经过用户授权页面 (Consent screen)。
在 Logto 中手动创建第三方应用
你可以在 Logto 控制台手动创建第三方应用,用于测试或临时集成。当你希望快速测试集成而无需实现完整的客户端注册流程时,这种方式非常有用。
-
登录你的 Logto 控制台。
-
前往 应用程序 → 创建应用程序 → 第三方应用 -> OIDC。
-
填写应用名称及其他必填项,然后点击 创建应用程序。
-
点击 权限 标签页,为该应用授予权限:
- 用户部分:如
profile和email等用户数据权限,用于基础身份声明 (Claims)。 - API 资源部分:你在 Logto 中定义的 API 资源 的权限(权限/Scopes),例如代表你的 MCP server 的 API 资源。
- 组织 (Organization) 部分:如果你使用 Logto 组织 (Organizations),可配置组织权限。
- 用户部分:如
-
在第三方应用中,配置 scopes 以请求你授予的权限,例如
openid profile email以及 API 资源 scopes。注意:OIDC 需要
openid。若要获取绑定到 API 资源的访问令牌 (Access token),应用还必须在授权 (Authorization) 请求中包含resource参数。遵循最新 MCP 规范的 MCP 客户端会根据受保护资源元数据自动完成此操作。 -
相应地配置你的第三方应用的 重定向 URI。记得在 Logto 中同步更新重定向 URI。
在底层,第三方应用是一个标准的 OAuth 2.0 / OIDC 客户端。这意味着你(或第三方开发者)可以使用任何 OAuth 2.0 / OIDC 库或框架与 Logto 集成。
需要注意的几点:
- 创建第三方应用时,请根据应用的架构选择合适的应用类型:
- 传统 Web:使用客户端密钥进行认证 (Authentication)。
- 单页应用 / 原生应用:使用 PKCE 实现无需客户端密钥的安全授权 (Authorization)。
- 我们的大多数快速入门指南是为第一方应用编写的,但你仍然可以将它们作为第三方应用集成的参考。
- 主要区别在于,第三方应用会显示用户授权页面 (Consent screen),请求用户明确授权访问他们的数据。
完整集成指南请参见 第三方应用。
设置 MCP 服务器
我们将使用 MCP 官方 SDK v2 和 mcp-auth 创建一个带有 "whoami" 工具的 MCP 服务器,该工具会返回当前用户的身份声明 (Claims)。
创建项目并安装依赖
mkdir mcp-server
cd mcp-server
npm init -y
npm pkg set type="module"
npm pkg set main="whoami.js"
npm pkg set scripts.start="node whoami.js"
npm install @modelcontextprotocol/server @modelcontextprotocol/express @modelcontextprotocol/node express mcp-auth
@modelcontextprotocol/server是核心 MCP SDK v2,采用 web 标准的Request/Response。@modelcontextprotocol/express和@modelcontextprotocol/node让其适配 Node.js 上的 Express。mcp-auth提供令牌验证器和 MCP SDK 的 OAuth 发现元数据。
MCP SDK v2 和 mcp-auth 仅支持 ESM,并且需要 Node.js >= 20。
将 MCP 服务器注册为 API 资源
最新的 MCP 规范 要求访问令牌 (Access token) 必须绑定到它们所颁发的资源(RFC 8707),而 mcp-auth 会强制执行这一点:令牌的 aud 声明 (Claim) 必须与你的 MCP 服务器的资源标识符相匹配。在 Logto 中,这通过创建一个资源指示器与 MCP 服务器 URL 匹配的 API 资源来实现:
- 登录到你的 Logto 控制台。
- 前往 API 资源 → 创建 API 资源。
- 填写详细信息,然后点击 创建 API 资源:
- API 名称:输入一个名称,例如 "Who am I"。
- API 标识符:输入
http://localhost:3001/。它必须与你将在 MCP 服务器中配置的资源标识符一致。
始终在资源指示器中包含末尾斜杠(/)。由于 MCP 官方 SDK 当前存在一个 bug,使用该 SDK 的客户端在发起认证 (Authentication) 请求时会自动在资源标识符后追加斜杠。如果你的资源指示器没有包含斜杠,资源验证将会失败。
配置 MCP Auth 与 Logto 集成
声明你的 MCP 服务器为受保护资源:包括其资源标识符和它信任的授权服务器。记得将 <your-logto-issuer-endpoint> 替换为你之前复制的发行者 (Issuer) 端点(可在应用详情页的 Endpoints & Credentials 下找到,例如 https://my-project.logto.app/oidc)。
在 whoami.js 中:
import { MCPAuth } from 'mcp-auth';
const authIssuer = '<your-logto-issuer-endpoint>';
const mcpAuth = new MCPAuth({
protectedResourceMetadata: {
// 资源标识符;必须与在 Logto 注册的 API 资源指示器一致
resource: 'http://localhost:3001/',
// 此 MCP 服务器信任的授权服务器
authorizationServer: { issuer: authIssuer, type: 'oidc' },
},
});
授权服务器元数据会在首次需要时延迟获取,并随后缓存。MCPAuth 实例会根据 Logto 的 JWKS 验证 JWT 访问令牌 (Access token) —— 包括签名、发行者 (Issuer)、受众 (Audience) 和过期时间,全部都会被强制校验。无需手写令牌验证逻辑。
实现 "whoami" 工具
现在,让我们实现 "whoami" 工具,它会从已验证的访问令牌 (Access token) 返回当前用户的身份声明 (Claims)。使用 getAuthInfo 从工具的回调上下文中读取 mcp-auth 已验证的认证 (Authentication) 信息。
import { McpServer } from '@modelcontextprotocol/server';
import { getAuthInfo } from 'mcp-auth';
// 工厂函数用于创建 MCP 服务器实例
// 每个请求都会获得自己的服务器实例,保证请求隔离
const createMcpServer = () => {
const mcpServer = new McpServer({
name: 'WhoAmI',
version: '0.0.0',
});
// 向服务器注册一个工具,用于返回当前用户的信息
mcpServer.registerTool(
'whoami',
{
description: '获取当前用户信息',
},
(context) => {
const { claims } = getAuthInfo(context);
return {
content: [{ type: 'text', text: JSON.stringify(claims) }],
};
}
);
return mcpServer;
};
启动服务器
最后,提供 OAuth 发现文档(RFC 9728 / RFC 8414),以便 MCP 客户端能够找到你的授权服务器,并使用 SDK 的 Bearer 认证 (Authentication) 中间件保护 MCP 端点。
import {
createMcpExpressApp,
mcpAuthMetadataRouter,
requireBearerAuth,
} from '@modelcontextprotocol/express';
import { toNodeHandler } from '@modelcontextprotocol/node';
import { createMcpHandler } from '@modelcontextprotocol/server';
const PORT = 3001;
// MCP 处理器采用 web 标准的 Request / Response;`toNodeHandler` 让其适配 Express
const mcpNodeHandler = toNodeHandler(createMcpHandler(createMcpServer));
const app = createMcpExpressApp();
// 提供 OAuth 发现文档(`/.well-known/...`),默认公开
app.use(mcpAuthMetadataRouter(await mcpAuth.getAuthMetadataOptions()));
app.all(
'/',
// 需要有效的 Bearer 令牌 (Access token);已验证的认证 (Authentication) 信息通过 `req.auth` 传递给处理器
requireBearerAuth(mcpAuth.getBearerAuthOptions()),
// `createMcpExpressApp` 应用了 `express.json()`,会消耗请求流,因此
// 解析后的 body 会被显式传递
async (request, response) => mcpNodeHandler(request, response, request.body)
);
app.listen(PORT);
运行服务器:
npm start
测试集成效果
- 启动 MCP 服务器。
- 将第三方 AI 代理连接到你的 MCP 服务器,并调用
whoami工具。 - 代理收到 401 Unauthorized 响应,通过 MCP 服务器的受保护资源元数据发现 Logto,并将用户重定向到 Logto 进行认证 (Authentication)。
- 用户登录并查看用户授权页面 (Consent screen),页面列出了代理请求的权限,然后批准(或拒绝)访问。
- 代理收到一个受众绑定的 JWT 访问令牌,并再次使用它调用工具。
- MCP 服务器根据 Logto 的 JWKS 验证访问令牌,并将已验证的身份声明 (Claims) 返回给代理。
延伸阅读
你的 MCP 服务器现在可以验证来自第三方 AI 代理的入站访问令牌。下一步,了解它如何在不传递令牌或丢失用户上下文的情况下,安全地代表用户调用你的下游业务 API:
MCP 服务器如何代表用户调用你的 API:生产环境令牌策略