Skip to content

feat(zhipu): passthrough for Zhipu Coding Plan remote MCP servers - #6359

Open
alfadb wants to merge 8 commits into
Wei-Shaw:mainfrom
alfadb:feature/zhipu-mcp-passthrough
Open

feat(zhipu): passthrough for Zhipu Coding Plan remote MCP servers#6359
alfadb wants to merge 8 commits into
Wei-Shaw:mainfrom
alfadb:feature/zhipu-mcp-passthrough

Conversation

@alfadb

@alfadb alfadb commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

概述

智谱 GLM Coding Plan 订阅附带三个专属远程 MCP Server(Streamable HTTP,端点 https://open.bigmodel.cn/api/mcp/{slug}/mcp):

  • web_search_prime — 联网搜索(webSearchPrime)
  • zread — 开源仓库检索(search_doc / get_repo_structure / read_file)
  • web_reader — 网页读取(webReader)

本 PR 让用户用 sub2api 自己的 API key 透明访问这些 MCP server:平台从 zhipu 账号池调度选号、重写认证头后透传(含 SSE 流式),并对 tools/call 按次计费。

注:视觉理解 MCP 是 Local MCP Server(本地运行直调推理端点,无远程端点可透传),不在本 PR 范围;它可通过 Z_AI_BASE_URL 指向 sub2api 的 /v1 兼容端点复用现有模型转发,无需改动。

使用方式

# MCP 客户端(Claude Code / Cline 等)
httpUrl: https://<sub2api-host>/api/mcp/zhipu/web_search_prime/mcp
Headers: Authorization: Bearer <sub2api api key>

实现

账号级开关(默认关,合并即安全)

  • accounts.extra.zhipu_mcp_enabled(bool);仅 Coding Plan 模式账号可开启,payg 拒绝(400)
  • 前端创建/编辑表单开关(zhipu + coding 才可交互);update 未提供该键时保留现值

透传链路/api/mcp/zhipu/{slug}/mcp,POST/DELETE;GET 显式 405)

  • slug 白名单(三个已实测端点),表外 404
  • 请求头白名单透传;认证头按选中账号重写(sub2api key 不出网、上游 key 不外泄,测试含零泄漏断言)
  • 上游响应 JSON / SSE 双形态透传,SSE 逐块 flush
  • 上游走既有 HTTPUpstream(连接池按账号隔离 + 账号代理生效)

Session 粘性Mcp-Session-Id → account_id Redis 粘表(TTL 30min,防 key 注入的 session id 校验);带 session 的请求路由回绑定账号;账号失效自动清粘表回退调度

换号重试:上游 429/402 或传输层错误换号(最多 4 次);协议级 4xx/5xx 原样透传(不重试非幂等调用)

计费:仅 tools/call(带 id 的 JSON-RPC Request)按次计费,batch 计数;复用既有 SearchCountsearch_price_per_1k 通道(zhipu 分组该字段语义即 MCP 每千次价格),零 schema 改动;usage 以伪模型名 zhipu-mcp-{slug} 落库

测试

  • 单测:开关 getter/校验/update 保留(20 例)、计费口径(15 分支)、粘表生命周期、路由权限
  • 集成:httptest fake MCP 上游覆盖认证重写、session 亲和、SSE 字节等价、429 换号、DELETE 清理
  • 已对真实上游完成三个 slug 的端到端验证(initialize / tools/list / tools/call)

slug ↔ 工具名对照(接入方必读)

上游 MCP 工具命名与路径 slug 风格不统一,勿按 slug 推断工具名,以 tools/list 实时返回为准

slug(路径段) tools/list 实际工具名 命名风格
web_search_prime web_search_prime 与 slug 一致
zread search_doc / read_file / get_repo_structure snake_case,与 slug 不同名
web_reader webReader camelCase,与 slug 风格不一致

踩坑案例:对 web_reader slug 按路径推断调用 "web_reader" → 上游 -32603 "Tool not found"。网关只透传,不做任何工具名映射。

后续修复(含在本 PR)

  • DELETE 会话终止 fail-closed:实测上游 DELETE 可能 HTTP 200 但内部失败(session 实际未终止)。现网关在 DELETE 后无条件写 session tombstone,此后携带该 session id 的任何请求直接 404(符合 MCP StreamableHTTP 规范),客户端须重新 initialize;同时 DELETE 透传不再携带 body 与 Content-Type(规避上游 transport 解析错误)。

设计决策:不引入 slug ↔ 工具名映射层

上游命名不统一(web_readerwebReader)是美观问题而非正确性问题:zread 一对多(search_doc/read_file/get_repo_structure)说明 slug(server 标识)与 tool(能力标识)本就是两个概念,"同名化"在概念上不成立。规范 MCP 客户端必经 tools/list 发现工具、按返回名调用,不会踩坑;网关侧映射层会破坏字节透传语义、造成直连/转发环境间的行为漂移,并随上游工具新增/改名产生持续维护负担,收益不成比例,故明确不做。

Rebase note (2026-08-29): rebased onto latest main (includes the newly merged Zhipu team Coding Plan org/project fields). Both features coexist in EditAccountModal.vue — team fields write credentials.zhipu_organization / zhipu_project, MCP switch writes extra.zhipu_mcp_enabled; no interaction by design. All upstream CI checks green.

@alfadb
alfadb force-pushed the feature/zhipu-mcp-passthrough branch from 3e1e602 to e39c539 Compare August 29, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant