跳到主要内容

使用 Logto 为你的 MCP 驱动应用启用认证 (Authentication)

提示:

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

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

集成完成后,你可以用你自己的 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 作为客户端进行注册:

  1. 登录到你的 Logto 控制台。

  2. 前往 应用程序创建应用程序不使用框架创建应用

  3. 选择类型:原生应用。

  4. 填写应用名称(如 “VS Code”)及其他必填项,然后点击 创建应用程序

  5. 设置 / 重定向 URI 部分,为 VS Code 添加以下重定向 URI,并保存更改:

    http://127.0.0.1
    https://vscode.dev/redirect
  6. 保存并复制 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 资源来实现:

  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 服务器:

    npm start
  2. 让 VS Code 连接到你的 MCP 服务器:

    1. 按下 Command + Shift + P(macOS)或 Ctrl + Shift + P(Windows / Linux)打开命令面板。
    2. 输入 MCP: Add Server... 并选择它。
    3. 选择 HTTP 作为服务器类型。
    4. 输入 MCP 服务器地址:http://localhost:3001/
    5. 当 OAuth 流程启动时,VS Code 会提示输入 Client ID:粘贴你之前复制的 App ID
    6. 由于这是一个无密钥的公开客户端,直接按回车跳过密钥输入。
    7. 在浏览器中完成登录流程。
  3. 登录完成后,在 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:生产级令牌策略