跳转到内容

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_challenge
2. 重定向到 OAuth provider
3. 回调获取 authorization code
4. 用 code_verifier 交换 access token
5. 使用 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 规范的自然结果——工具列表不需要认证,执行可能需要。


参考来源