快速结论:当 MCP 服务器使用 auth_type: oauth_delegate 搭配 dcr_bridge: true,且客户端在每次请求上都同时携带 Authorization: Bearer llm_env_… 与 x-litellm-api-key 时,tools/list 会返回 HTTP 200 但工具列表为空。优先排查是否在 MCP 请求上多带了 x-litellm-api-key 头。
适用环境:LiteLLM v1.98.0(镜像 docker.litellm.ai/berriai/litellm-database:v1.98.0)与 v1.101.0;客户端 mcp-remote 0.2.1(Streamable HTTP),另有 Claude Code 及原生 curl 复现;上游为 OAuth 2.0 保护资源(如 GitLab 19.3.1 CE 的内置 MCP)。Issue 未提供操作系统、Python、CUDA 或显卡信息。
最快修复方案:暂无确认的一步修复方案。Issue 中明确说明 dcr_bridge: false 不是可行的替代方案,且 #41390 在关闭时仍为草案。
注意事项:Issue 中确认 #40923(“require admission for delegated OAuth”)并不修复此问题,因为它改动的是旧路径 auth_type: oauth2 + delegate_auth_to_upstream;#41390 看起来针对该故障,但当时仍是 draft,且与 #38326、#38524 存在互相冲突的策略决定。此外,x-litellm-api-key 在 POST /<server>/token 这一步是必需的,去掉它会导致 token 端点报错,因此无法通过客户端配置同时满足两段请求。
问题场景
用户在 LiteLLM 网关后面配置 MCP 服务器,使用 auth_type: oauth_delegate 加 dcr_bridge: true,由网关充当 DCR(动态客户端注册)桥接,让 Claude Desktop / Claude Code / mcp-remote 走浏览器交互式登录,并把上游的 OAuth 保护资源(如 GitLab 内置 MCP)工具暴露给客户端。客户端在注册、授权、换取 token 后,用 llm_env_ 前缀的网关令牌发起 tools/list。此时若请求头里同时带上 x-litellm-api-key,工具列表变空,Claude Desktop 显示 “This server offered no tools”,服务器被判为不可用。
报错原文
[Bug]: MCP sending x-litellm-api-key to a dcr_bridge server returns an empty tool list
data: {"jsonrpc":"2.0","id":3,"result":{"_meta":{"litellm.ai/server_outcomes":{"gitlab":{"status":"auth_required","http_status":401}}},"tools":[]}}
this server issues a gateway-bound credential; complete the interactive sign-in, or send a litellm credential (x-litellm-api-key or Authorization) on the token request
SDK auth failed: Protected resource https://gitlab.example.com/api/v4/mcp does not match expected https://gateway.example.com (or origin)
原因分析
可能原因是:MCP 请求路径上的身份判定与 token 端点上的准入判定策略不一致。在 dcr_bridge: true 下,llm_env_ 令牌已经编码了准入身份(复现中可见 "subject_type":"key_hash",即准入绑定到虚拟 key),此时再附带冗余的 x-litellm-api-key 头会被当作额外的准入要求处理,导致上游凭据被扣留、上游返回 401,网关侧对客户端仍以 200 返回空 tools 数组(status: auth_required)。Issue 作者也指出,期望行为应当是冗余的 x-litellm-api-key 被忽略而不是让上游凭据被 withhold。
环境排查
- LiteLLM 版本:
v1.98.0已确认存在,v1.101.0仍存在;作者称撰写时main分支同样存在。 - 部署方式:Docker 镜像
docker.litellm.ai/berriai/litellm-database:v1.98.0,并带有DATABASE_URL、STORE_MODEL_IN_DB=True。 - MCP 配置:确认是否同时使用了
auth_type: oauth_delegate和dcr_bridge: true。 - 上游授权服务器:是否只发布
authorization_code和refresh_token、没有client_credentials(GitLab 19.3.1 CE 即属此类,故只能做每用户浏览器登录)。 - 客户端:
mcp-remote0.2.1(Streamable HTTP)、Claude Code;mcp-remote会把--header加到所有请求上,这一点需确认。 - 请求路径:单服务器路由(如
/gitlab/mcp)而非聚合端点。 - Issue 未提供操作系统、Python 版本、CUDA、显卡信息。
解决步骤
- 先用最小复现确认故障边界:使用同一个 MCP session,先只带
Authorization: Bearer <ENVELOPE>调tools/list,观察是否返回全部工具(复现实测 28 个)。 - 保持同一 session、同一 token,仅额外加上
x-litellm-api-key头再调一次tools/list,观察是否变成空数组且_meta中出现status: auth_required/http_status: 401。若两次结果不一致,即可定位到该头。 - 可优先尝试的临时绕行(Issue 作者所述):先带着
x-litellm-api-key完成POST /<server>/token铸出llm_env_凭据,然后停掉客户端,再在不带该头的情况下重启客户端。注意这只是临时手段。 - 不要尝试用
dcr_bridge: false规避:关闭桥接后 LiteLLM 会原样转发上游的 protected-resource 元数据,客户端拿到"resource": "https://gitlab.example.com/api/v4/mcp",与自身连接的https://gateway.example.com不匹配,会在 RFC 9728 资源校验处直接失败,没有客户端开关可绕过。 - 跟踪上游修复进展:
#41390看起来针对该故障,但当时为 draft,且与#38326、#38524存在冲突的策略决定;#40923不适用(它改的是auth_type: oauth2+delegate_auth_to_upstream旧路径)。
验证方法
修复后应满足:在 Authorization: Bearer llm_env_… 与 x-litellm-api-key 同时存在的情况下,POST /<server>/mcp 的 tools/list 返回 HTTP 200 且列出全部工具(复现中为 28 个),_meta 的 status 为 ok 而非 auth_required;Claude Desktop / Claude Code 中该服务器显示为已连接且可调用工具。另需确认约 2 小时后的 token 刷新路径同样获批,否则刷新后仍会复现空列表。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: MCP on host mode returns empty dataset ids](https://www.chat-gpts.plus/wp-content/uploads/2026/09/13183-415cd908-768x403.jpg)

