使用 Logto 为你的 MCP 驱动应用启用认证 (Authentication)
探索 Logto 的 AI 解决方案:为 MCP 服务器、AI 代理和应用提供认证 (Authentication) 与授权 (Authorization)。
本指南将带你通过 mcp-auth 和 MCP 官方 SDK v2,将 Logto 集成到你的 MCP 服务器,实现用户认证 (Authentication) 并安全地从访问令牌 (Access token) 读取其已验证身份。
你将学会如何:
- 配置 Logto 作为你的 MCP 服务器的授权服务器 (Authorization server)。
- 在 MCP 服务器中设置 “whoami” 工具,用于返回当前用户的身份声明 (Claims)。
- 使用 VS Code(MCP 客户端)测试整个流程。
完成本教程后,你的 MCP 服务器将能够:
- 在你的 Logto 租户中认证 (Authentication) 用户。
- 验证 Logto 签发的 JWT 访问令牌 (Access token)(签名、发行者 (Issuer)、受众 (Audience) 和过期时间)。
- 为 “whoami” 工具调用返回已验证的身份声明 (Claims)(
sub、iss、aud等)。
集成完成后,你可以用你自己的 MCP 客户端(如 Web 应用)替换 VS Code,以访问 MCP 服务器暴露的工具和资源。
本指南的完整可运行示例代码可在 mcp-auth/js 仓库中找到:
whoami-express:本指南中的 "whoami" 服务器,基于 Node.js 和 Express。whoami:同样的服务器,基于 fetch-native(Web 标准的Request/Response,使用 Hono),可部署到 Cloudflare Workers。
前置条件
- 一个 Logto Cloud(或自托管)租户
- Node.js >= 20 环境
理解架构
- MCP 服务器:向 MCP 客户端暴露工具和资源的服务器。遵循最新 MCP 规范,它作为 OAuth 2.0 资源服务器,验证由 Logto 签发的访问令牌 (Access token)。
- MCP 客户端:用于发起认证 (Authentication) 流程并测试集成的客户端。在本指南中,我们将使用 VS Code(内置 MCP 支持)作为客户端。
- Logto:作为 OpenID Connect 提供方(授权 (Authorization) 服务器),管理用户身份,并为你的 MCP 服务器签发受受众 (Audience) 绑定的 JWT 访问令牌 (Access token)。
下面的非规范时序图展示了整个流程:
由于 MCP 发展迅速,上述流程图可能不是最新。请参考 mcp-auth 文档获取最新信息。
在 Logto 中设置应用
你的 MCP 客户端需要在 Logto 中注册为一个应用,以发起授权 (Authorization) 流程。本指南将以 VS Code 作为客户端进行注册:
-
登录到你的 Logto 控制台。
-
前往 应用程序 → 创建应用程序 → 不使用框架创建应用。
-
选择类型:原生应用。
-
填写应用名称(如 “VS Code”)及其他必填项,然后点击 创建应用程序。
-
在 设置 / 重定向 URI 部分,为 VS Code 添加以下重定向 URI,并保存更改:
http://127.0.0.1https://vscode.dev/redirect -
保存并复制 App ID 和 发行者端点 (Issuer endpoint)。
设置 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 服务器:
npm start -
让 VS Code 连接到你的 MCP 服务器:
- 按下
Command + Shift + P(macOS)或Ctrl + Shift + P(Windows / Linux)打开命令面板。 - 输入
MCP: Add Server...并选择它。 - 选择
HTTP作为服务器类型。 - 输入 MCP 服务器地址:
http://localhost:3001/ - 当 OAuth 流程启动时,VS Code 会提示输入 Client ID:粘贴你之前复制的 App ID。
- 由于这是一个无密钥的公开客户端,直接按回车跳过密钥输入。
- 在浏览器中完成登录流程。
- 按下
-
登录完成后,在 VS Code 中运行
whoami工具。
你应该能看到来自访问令牌 (Access token) 的已验证声明 (Claims),例如:
{
"iss": "https://my-project.logto.app/oidc",
"sub": "user_XXXX",
"aud": "http://localhost:3001/",
"client_id": "<your-app-id>"
}
延伸阅读
你的 MCP 服务器现在已经可以验证传入的访问令牌 (Access token)。下一步,了解它如何在不传递令牌或丢失用户上下文的情况下,安全地代表用户调用下游业务 API:
MCP 服务器如何代表用户调用你的 API:生产级令牌策略