跳到主要内容

启用第三方 AI 代理访问你的 MCP 服务器

提示:

探索 Logto 的 AI 解决方案:为 MCP 服务器、AI 代理和应用提供认证 (Authentication) 与授权 (Authorization)。

本指南将带你通过 mcp-authMCP 官方 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)(如 subissaud 等)。
示例代码:

本指南的完整可运行示例代码可在 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 代理有三种方式:

允许开发者在 Logto 中创建第三方应用

如果你正在构建一个市场或希望允许开发者在 Logto 中创建第三方应用,可以利用 Logto Management API 以编程方式创建第三方应用。这样开发者可以注册他们的应用并获取认证 (Authentication) 所需的凭据。

你需要托管自己的服务来处理客户端注册流程。该服务将与 Logto Management API 交互,代表开发者创建第三方应用。

另外,你也可以在 Logto 控制台手动创建第三方应用,以熟悉整个流程。

允许任何 AI 代理无需预注册即可接入

在开放的 MCP 生态系统中,你通常无法提前知道所有代理。动态应用 移除了注册步骤:代理使用一个公开的 HTTPS URL 提供自己的客户端元数据文档作为其 client_id,Logto 在收到授权 (Authorization) 请求时解析它。

你仍然可以通过授予动态应用的权限来控制代理可请求的内容,并且每次授权 (Authorization) 都会经过用户授权页面 (Consent screen)。

在 Logto 中手动创建第三方应用

你可以在 Logto 控制台手动创建第三方应用,用于测试或临时集成。当你希望快速测试集成而无需实现完整的客户端注册流程时,这种方式非常有用。

  1. 登录你的 Logto 控制台。

  2. 前往 应用程序创建应用程序第三方应用 -> OIDC

  3. 填写应用名称及其他必填项,然后点击 创建应用程序

  4. 点击 权限 标签页,为该应用授予权限

    • 用户部分:如 profileemail 等用户数据权限,用于基础身份声明 (Claims)。
    • API 资源部分:你在 Logto 中定义的 API 资源 的权限(权限/Scopes),例如代表你的 MCP server 的 API 资源。
    • 组织 (Organization) 部分:如果你使用 Logto 组织 (Organizations),可配置组织权限。
  5. 在第三方应用中,配置 scopes 以请求你授予的权限,例如 openid profile email 以及 API 资源 scopes。

    注意:OIDC 需要 openid。若要获取绑定到 API 资源的访问令牌 (Access token),应用还必须在授权 (Authorization) 请求中包含 resource 参数。遵循最新 MCP 规范的 MCP 客户端会根据受保护资源元数据自动完成此操作。

  6. 相应地配置你的第三方应用的 重定向 URI。记得在 Logto 中同步更新重定向 URI。

第三方应用权限

在底层,第三方应用是一个标准的 OAuth 2.0 / OIDC 客户端。这意味着你(或第三方开发者)可以使用任何 OAuth 2.0 / OIDC 库或框架与 Logto 集成。

需要注意的几点:

  1. 创建第三方应用时,请根据应用的架构选择合适的应用类型:
    • 传统 Web:使用客户端密钥进行认证 (Authentication)。
    • 单页应用 / 原生应用:使用 PKCE 实现无需客户端密钥的安全授权 (Authorization)。
  2. 我们的大多数快速入门指南是为第一方应用编写的,但你仍然可以将它们作为第三方应用集成的参考。
  3. 主要区别在于,第三方应用会显示用户授权页面 (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 资源来实现:

  1. 登录到你的 Logto 控制台。
  2. 前往 API 资源创建 API 资源
  3. 填写详细信息,然后点击 创建 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

测试集成效果

  1. 启动 MCP 服务器。
  2. 将第三方 AI 代理连接到你的 MCP 服务器,并调用 whoami 工具。
  3. 代理收到 401 Unauthorized 响应,通过 MCP 服务器的受保护资源元数据发现 Logto,并将用户重定向到 Logto 进行认证 (Authentication)。
  4. 用户登录并查看用户授权页面 (Consent screen),页面列出了代理请求的权限,然后批准(或拒绝)访问。
  5. 代理收到一个受众绑定的 JWT 访问令牌,并再次使用它调用工具。
  6. MCP 服务器根据 Logto 的 JWKS 验证访问令牌,并将已验证的身份声明 (Claims) 返回给代理。

延伸阅读

你的 MCP 服务器现在可以验证来自第三方 AI 代理的入站访问令牌。下一步,了解它如何在不传递令牌或丢失用户上下文的情况下,安全地代表用户调用你的下游业务 API:

MCP 服务器如何代表用户调用你的 API:生产环境令牌策略