
LiteLLM 代理托管 MCP Server 包架构地图变更规范、模块边界与测试镜像策略【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm本篇技术指南基于 LiteLLM 仓库中 litellm/proxy/_experimental/mcp_server/AGENTS.md 展开。该文件是 LiteLLM 中由代理托管proxy-hosted的 MCP Server 实现包的工程变更守则界定了包的模块职责、认证边界、工具调用链路与测试镜像策略。读完本文你将掌握该实验性包的完整代码地图、贡献代码时应遵守的边界规则以及安全敏感逻辑与测试的组织方式可直接用于为 LiteLLM MCP 相关能力做源码级维护与二次开发。为什么需要一份针对该包的 AGENTS.mdLiteLLM 的 MCP 能力并不只是某个脚本而是一整套挂在代理进程内的服务端实现。AGENTS.md明确了一条总原则改动必须先读文档、再动手——文档要求改动方在修改该包前阅读仓库根目录的 CLAUDE.md 与包内 CLAUDE.mdAGENTS.md原文用../../../../CLAUDE.md指代仓库根文档本文已换算为仓库根路径。该目录拥有owns代理承载的 MCP Server 实现。文件结构注释约定行为改动应留在拥有该行为的模块内部只有以下情况才允许跨出本包边界公共类型契约、数据库 schema、Dashboard 状态或跨代理路由接线必须随之变化。换言之这份文档把高内聚、低耦合落实为具体的目录纪律——避免任何模块都向外伸手导致归属混乱。包结构地图每个文件的职责AGENTS.md给出了逐文件职责清单。结合当前仓库实际目录litellm/proxy/_experimental/mcp_server/各文件的核心职责可归纳如下模块职责server.pyASGI/MCP 路由处理、会话管理、工具调用核心载体约 4900 行mcp_server_manager.py上游服务器注册表、客户端创建、工具路由与权限检查auth/user_api_key_auth_mcp.pyLiteLLM 准入admission认证与 MCP 请求头解析auth/token_exchange.pyOAuth token exchange 处理auth/litellm_auth_handler.py面向 MCP 会话的已认证用户适配器outbound_credentials/新增的类型化上游凭据解析命名空间见下文专节discoverable_endpoints.pyMCP OAuth 元数据、authorize、token、callback 端点byok_oauth_endpoints.pyBYOKBring-Your-Own-KeyOAuth UI/API 流程oauth_utils.pyredirect URI 与代理 base URL 校验oauth2_token_cache.pyOAuth2 与按用户 token 的解析/缓存db.pyMCP server、凭据、环境变量、提交审批的 DB 访问toolset_db.pyMCP toolset 的 DB 访问rest_endpoints.py供列出/调用 MCP 工具的代理 REST 门面/mcp-rest前缀路由openapi_to_mcp_generator.pyOpenAPI spec 到 MCP 工具的定义生成sampling_handler.pyMCP sampling 到 LiteLLM completion 的流转elicitation_handler.pyMCP elicitation 中继流semantic_tool_filter.py对可用 MCP 工具做语义过滤tool_search.py可选虚拟工具mcp_tool_search/mcp_tool_call用于大型工具目录guardrail_translation/handler.pyMCP guardrail 结果翻译MCPGuardrailTranslationHandlersse_transport.pySSE 传输实现mcp_context.py承载 MCP 请求/会话元数据的 contextvarstool_registry.py内存 MCP 工具注册表辅助cost_calculator.pyMCP 工具调用成本计算ui_session_utils.pyDashboard 会话鉴权上下文辅助utils.py多模块共享的原语服务器命名/前缀、header 处理、env var 插值等需要说明AGENTS.md是指导性清单仓库已演进为更细的子目录与文件例如outbound_credentials/下已包含bridge_credentials.py、session_credentials.py、client_credentials.py、token_exchanger.py、v2_token_store.py、redis_distributed_lock.py、redis_refresh_coordinator.py等另有gateway_dcr_flow.py、bridge_token_flow.py、proxy_api_credentials.py、faults/子包与exceptions.py。新增这些文件正是为了让既有模块不至于材料性地更难理解——与AGENTS.md中不要添加宽泛的 catch-all 模块只有当一个全新能力会使既有模块难以理解时才新增文件的规则一致。从源码可见包的入口接线集中在 server.py以app.mount(/, ...)、app.mount(/mcp, ...)、app.mount(/{mcp_server_name}/mcp, ...)挂载 Streamable HTTP 处理器并以app.mount(/sse, ...)挂载 SSE 处理器。会话管理生命周期则由 lifespan 在应用启停时统一调用initialize_session_managers()/shutdown_session_managers()对应 server.py 中的实现stateless/stateful/SSE 三类 MCP SDK session manager 全部用 context manager 启动与退出。第一条硬边界准入认证与上游认证必须分离AGENTS.md最强调的实现规则是保持LiteLLM 准入认证与上游 MCP 认证之间的边界LiteLLM 准入admission属于 auth/user_api_key_auth_mcp.py它负责判断这个请求能否进入 LiteLLM 代理校验代理 API Key、用户/团队/组织对 MCP server 与工具的授权范围上游 token exchange、委托认证delegated auth、按用户 OAuth、BYOK 以及原始请求头转发则应归属专门的 OAuth/header 模块。同时AGENTS.md要求不要把这些模式折叠成一个泛化分支none、bearer/API key、OAuth、OAuth token exchange、委托上游认证、SSE、Streamable HTTP、stdio 都要视为相互独立的流程——除非测试能证明每种模式仍然正确。一个需要特别小心的安全组合包内 CLAUDE.md 给出了一个关键安全提示AGENTS.md也点名要求谨慎available_on_public_internet: false配合delegate_auth_to_upstream: trueoauth2、interactive而非client_credentials时LiteLLM 仍允许匿名上游 PKCE 路径——即/authorize及匹配的 MCP 路由可以不带代理 API Key。internal-only 标志主要影响其他面如基于 IP 的发现。此时需要依赖上游 IdP 与网络策略兜底Dashboard 在两者同时设置时会显示告警代理在从配置或数据库加载该 server 时也会打印告警。这正是AGENTS.md强调该匿名上游 PKCE 路径必须保持有意为之intentional的落点任何重构都不应无意间放宽或收紧这一组合下的行为。有状态的 MCP 会话内存上限与防滥用server.py顶部的常量暴露了代理承载 MCP 会话时的资源约束策略见 server.py_STATEFUL_SESSION_IDLE_TIMEOUT_SECONDS 30 * 60有状态会话 30 分钟空闲即被回收_MAX_STATEFUL_SESSIONS_PER_OWNER 100每个调用方最多并发持有 100 个有状态会话。每次initialize都会创建一个直到空闲超时才消失的会话若不设上限已认证客户端可刷initialize耗尽内存。达到上限时优先淘汰调用方自身最旧的空闲会话若仍超限每个会话都在飞行中新的initialize将以 429 拒绝_MCP_ROUTING_PEEK_MAX_BYTES 4096嗅探 POST 上 JSON-RPC method 时最多窥探的字节数防止已认证客户端强制代理缓存超大 body 以做路由决策_byok_cred_cache短时内存缓存TTL 60 秒、最大 4096 项用于 BYOK 凭据查询去重。这些常量本身即是安全审计点任何涉及会话创建、凭据缓存或 body 缓冲的改动都应回归这些边界。outbound_credentials/把失败建模成值的类型化凭据解析AGENTS.md中标注为 NEW 的 outbound_credentials/init.py 是一个值得单独研读的子包。其模块 docstring 自述设计意图服务器对每个模式声明一个来自AuthConfig判别联合discriminated union的配置UpstreamCredentialProvider.resolve_credentials选择一个分支并返回httpx.Auth或类型化的CredError。失败以值values方式建模——经result.Result[T, CredError]Ok/Error联合返回而非抛出异常因此每个 seam 都是全函数total。子包公开面见 outbound_credentials/init.py包括AuthConfig判别联合NoneConfig、ApiKeyConfig、ClientCredentialsConfig、AuthorizationCodeConfig、TokenExchangeConfig、PassthroughConfig、IdJagConfig等辅助类型CredError、ServerSpec、Subject、HeaderCarrier、ApiKeySource、AwsSigV4Config等值类型Ok/Error/Result以及parse_auth_spec_kind、validate_header_namehttpx_auth.py 中把每种模式都收敛成httpx.Auth如NoOpAuth、StaticHeaderAuth保证对外行为统一可注入。从目录中可以看到更完整的运行支撑文件如client_credentials.py处理 M2M client credentials 授权并带本地/分布式缓存、token_exchanger.py实现 RFC 8693 与 Entra OBO 两种 exchange 表单、per_user_oauth_store.py与v2_token_store.py处理按用户 token 存取、redis_distributed_lock.py/redis_refresh_coordinator.py用于 Redis 刷新协调它们共同支撑resolve_credentials各分支。adapter.py则在 v1 服务器对象与 v2Subject/ServerSpec之间做换算是AGENTS.md中 PR7 注记_create_mcp_client由resolve_mcp_auth切换为resolve_credentials演进路径的现役边界。工具调用主链路与虚拟工具的一致性要求AGENTS.md对虚拟工具路径给出了强制约束tool_search.py由mcp_tool_search_enabled门控中的mcp_tool_search与mcp_tool_call必须镜像普通工具流程逐项复用而非重写IP 过滤server 白名单allowlist按 key 的 tool 权限no-accessible-server 时的拒绝按请求的认证头server 作用域scope错误转为isError用量spend记录。具体做法是复用server.py中的_list_mcp_tools与execute_mcp_tool而不是绕过它们另起炉灶。实际函数签名印证了这一点_list_mcp_tools与execute_mcp_tool均接受user_api_key_auth、mcp_auth_header、mcp_server_auth_headers、oauth2_headers、raw_headers、client_ip等一整套上下文而mcp_server_manager.py侧则由check_allowed_or_banned_tools、validate_allowed_params、check_tool_permission_for_key_team、pre_call_tool_check等在调用上游前完成工具级准入见 mcp_server_manager.py。这背后是一个贯穿全包的安全原则无论请求从 Streamable HTTP、SSE 还是 REST/虚拟工具进来工具可达性判定都必须收敛到同一套代码避免出现某条路径少查一个 IP 过滤之类的绕过面。Guardrail 与 MCP 的衔接作为工具调用链的补充guardrail_translation/handler.py 中的MCPGuardrailTranslationHandler会把一次 MCPcall_toolname arguments翻译成单个 OpenAI 兼容的tool_call交给统一 guardrail 管线。其 docstring 说明了一个细节差异当只有调用载荷name arguments而没有完整工具 schema 时这里只构造tool_call若要做 MCP Tool 定义schema到 OpenAItools[]的转换应使用 litellm/experimental_mcp_client/tools.py 中的transform_mcp_tool_to_openai_tool。翻译层还负责把 guardrail 的处理结果回写 MCP 工具结果结构并利用json_string_leaves/with_json_string_leaves等工具做结构化内容的改写。数据库字段同步与类型契约AGENTS.md规定凡是用户可见、且由数据库承载的字段必须在多处保持同步——数据库迁移、litellm/types/mcp.py或litellm/types/mcp_server/下的类型化 Pydantic 模型、配置加载、本包逻辑以及 Dashboard 状态。包边界处应优先使用官方 MCP SDK 类型与既有的 LiteLLM Pydantic 模型避免使用无类型协议字典。例如mcp_server_manager.py中build_mcp_server_from_table/_build_mcp_server_table负责 DB 行与MCPServer源自 litellm/types/mcp_server/mcp_server_manager.py之间的双向转换而 db.py 则集中了 MCP server/凭据/env var 的加解密与 CRUD含rotate_mcp_server_credentials_master_key、rotate_mcp_user_credentials_master_key、rotate_mcp_user_env_vars_master_key等主密钥轮换能力。改字段意味着改动会横跨这些文件这也是AGENTS.md把跨代理路由接线列为允许越出本包的少数情形的原因。测试规范镜像目录 定向覆盖AGENTS.md对测试布局的规定非常具体可直接照做镜像本包在tests/test_litellm/proxy/_experimental/mcp_server/下建立与实现路径一一对应的目录。当前仓库实测已存在完整镜像树见 tests/test_litellm/proxy/_experimental/mcp_server/例如auth/test_user_api_key_auth_mcp.py、auth/test_token_endpoint_auth.py对应auth/guardrail_translation/test_mcp_guardrail_handler.py对应guardrail_translation/handler.pyoutbound_credentials/test_resolver.py、test_adapter.py、test_client_credentials.py、test_token_exchanger.py、test_v2_token_store.py等 20 文件对应outbound_credentials/各实现顶层还有test_mcp_server.py、test_mcp_server_manager.py、test_discoverable_endpoints.py、test_byok_oauth_endpoints.py、test_rest_endpoints.py、test_mcp_tool_search.py、test_semantic_tool_filter.py、test_openapi_to_mcp_generator.py、test_db_credentials.py等。回归扩展而非新建对既有文件做回归时应扩展现有映射测试文件而不是另起炉灶新增场景优先落在镜像路径做聚焦覆盖。tests/mcp_tests/只用于扩展现已存在那里的更宽泛 MCP 集成场景。覆盖主题清单路由、认证、工具列出、工具执行、OAuth、sampling、elicitation、DB、Dashboard 会话等改动都应有镜像路径下的聚焦测试。安全敏感逻辑的测试红线AGENTS.md明确指出以下几类逻辑需要既测放行路径又测拒绝路径focused tests for both allowed and rejected paths的定向测试请求头转发header forwardingIP 过滤公网可达性检查public internet checkstoken 存储env var 插值凭据加密。与此呼应的源码证据包括utils.py中的interpolate_env_vars/interpolate_headers/logging_safe_mcp_headersmcp_debug.py中的请求头掩码与调试头构建oauth_utils.py中的 redirect URI 校验含validate_loopback_redirect_uri、_parse_trusted_redirect_origins、validate_trusted_redirect_uri等以及rest_endpoints.py中_relay_upstream_auth_http_exception对上游认证错误的规范化。另一条注释纪律同样值得注意新增代码不要写注释除非它在解释非显而易见的安全或协议行为**优先用清晰的命名与短小函数表达意图**。这保证了安全逻辑的可审计性不会被注释噪声稀释。变更工作流速查清单综合AGENTS.md与仓库现状向该包提交变更时可按下述顺序自查先读仓库根 CLAUDE.md 与本包 CLAUDE.md尤其关注匿名上游 PKCE 组合判断改动归属行为所属模块 vs 需要越界的公共类型契约 / DB schema / Dashboard / 跨代理路由接线确认认证模式边界准入留在auth/user_api_key_auth_mcp.py上游凭据/转发留给 OAuth/header 与outbound_credentials/不要把none/bearer/OAuth/token exchange/delegated/SSE/Streamable HTTP/stdio 折叠成单一泛化分支涉及虚拟工具路径时确认复用了_list_mcp_tools与execute_mcp_tool全流程IP 过滤→server allowlist→按 key 工具权限→无可用 server 拒绝→按请求认证头→server scope→isError→spend 日志无遗漏涉及 DB 字段时核对迁移、litellm/types/mcp.py或litellm/types/mcp_server/类型、配置加载、包内逻辑与 Dashboard 五处同步在tests/test_litellm/proxy/_experimental/mcp_server/镜像路径补测试回归优先扩展既有文件安全敏感逻辑必须覆盖允许与拒绝两条路径除非解释安全/协议行为否则不为新代码添加注释避免新增宽泛 catch-all 模块。上述规则可总结为包的三条架构主线认证职责分离、工具可达性判定收敛、失败以类型化值建模。理解这三条主线后再阅读 server.py、mcp_server_manager.py 与 outbound_credentials/ 的源码即可快速定位任何 MCP 相关能力在 LiteLLM 代理内的实现位置与扩展切入点。【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考