MCP 多服务器 OAuth 管理
MCP 多服务器 OAuth 管理
学习目标
本章聚焦 LibreChat 的 MCP Manager 实现。你将了解:
- 应用级与用户级连接的分级管理
- OAuth PKCE 流程在 MCP 中的实现
- 工具发现与工具执行的分离
- 连接缓存与失效检测
前置知识
下文假设你已理解上述概念,直接聚焦 LibreChat 的具体实现。
项目实践
分级连接管理
MCPManager 继承自 UserConnectionManager,实现了两级连接:
MCPManager ├── appConnections (ConnectionsRepository) │ └── 应用级连接:所有用户共享,无需认证 │ └── userConnections (per-user) └── 用户级连接:需要 OAuth 认证getConnection 方法按优先级查找:
getConnection(serverName, user): 1. 先查找 appConnections[serverName] 2. 如果没有且 user.id 存在 → getUserConnection(serverName, user) 3. 如果都没有 → 抛出 McpError工具发现独立于 OAuth
discoverServerTools 方法允许在 OAuth 未完成的情况下列出工具 schemas:
discoverServerTools({ serverName, user, signal, timeout }): 1. 获取或创建连接(可能不需要 OAuth) 2. 调用 MCP protocol 的 tools/list 3. 返回工具列表根据 MCP 规范,工具列表不需要认证。这使得 Agent 初始化时可以提前获取工具 schemas 注入 prompt,而 OAuth 认证在用户实际调用工具时才完成。
MCPConnectionFactory 工厂模式
连接创建通过 MCPConnectionFactory 工厂函数:
createConnection(serverName, config, user): 1. 解析服务器配置(SSE URL、stdio 命令、环境变量等) 2. 检查是否需要 OAuth 3. 创建 MCPConnection 实例 4. 初始化连接(handshake + tool listing)工厂模式的好处是连接创建逻辑集中管理,便于测试和替换传输层。
OAuth 认证流程
OAuth 连接使用 PKCE(Proof Key for Code Exchange)流程:
1. 用户请求连接 → 生成 code_verifier / code_challenge2. 重定向到 OAuth provider3. 回调获取 authorization code4. 用 code_verifier 交换 access token5. 使用 token 建立 MCP 连接Token 存储在 MCPOAuthTokens 中,由 FlowStateManager 管理生命周期。
问题与规避
问题 1:OAuth 完成后工具列表未更新
规避:discoverServerTools 在每次调用时重新获取工具列表,不缓存。这确保 OAuth 完成后新增的工具立即可见。
问题 2:应用级连接配置变更后旧连接仍在使用
规避:ConnectionsRepository.get 方法检查配置是否仍然有效。如果配置变更,旧连接被销毁并创建新的。
问题 3:用户级连接在 OAuth token 过期后无法自动恢复
规避:getUserConnection 检查 token 有效性,如果过期则触发刷新流程。FlowStateManager 管理刷新状态,避免并发刷新。
设计取舍
工具发现与执行分离
| 方案 | 优势 | 代价 |
|---|---|---|
| 分离(LibreChat 的选择) | Agent 初始化时即可获取工具 schemas,OAuth 可延迟 | 需要维护两套连接逻辑 |
| 合并 | 简单一致 | Agent 初始化需要等待 OAuth 完成 |
分离是 MCP 规范的自然结果——工具列表不需要认证,执行可能需要。