feat: add raw_response field to MCPServer - #2643
Conversation
wklken
left a comment
There was a problem hiding this comment.
PR #2643 Code Review 汇总报告
由 codex-internal (gpt-5.4) + claude-internal 双模型 review,主 agent 汇总整理。
变更概述
本次 PR 为 MCP Server 系统新增 raw_response 开关(布尔字段,默认 false)。当启用时,mcp-proxy 直接返回 API 原始响应体,不再包裹 status_code、request_id、trace_id、x_request_id 等额外字段。
主要涉及:
- Dashboard 侧:
MCPServer模型新增raw_response字段 + migration,v2/sync 和 web serializer 同步添加字段,API 文档更新 - mcp-proxy 侧:
MCPServer实体/配置/服务器层均传递raw_response,genToolHandler根据该字段决定响应是否包裹信封 - 顺手修复:
releaser.py中BK_APIGW_RELEASE_VERSION的split()调用 - 测试:新增了 model/config/server 及 handler 行为的基础测试
变更规模:18 个文件,234 行新增,19 行删除。
问题列表
🔴 Blocking
[1] 热更新链路不支持 raw_response,已有 server 修改该字段后不会生效 [codex]
- 位置:
src/mcp-proxy/pkg/mcp/mcp.go、pkg/infra/proxy/proxy.go、pkg/infra/proxy/server.go - 问题:
checkNeedLoad()仅比较协议类型、resourceVersionID和工具集合,不比较raw_response。用户通过 dashboard 或同步接口将已有 server 的raw_response从false改为true(或反向),大多数情况下会走skipped,现网内存里的 handler 保持旧行为,新配置不生效。即使别的原因触发 reload,UpdateMCPServerFromOpenApiSpec()也没有显式刷新rawResponse状态。 - 实际影响:
raw_response仅对"首次创建 server"或"进程重启冷启动"有效,属于"可创建但不可热更新"的功能性缺陷。 - 建议:
- 在
checkNeedLoad()中加入existingServer.IsRawResponse() != s.RawResponse的判断 - 更新路径显式调用
SetRawResponse()并基于新值重建 tool handler - 补回归测试:已有 server 从
false切到true且resource version不变时触发热更新
- 在
🟠 Major
[1] buildToolResponseEnvelope 函数对 raw_response 模式的处理位置可能需要调整 [claude]
- 位置:
src/mcp-proxy/pkg/infra/proxy/proxy.go - 问题:当前信封构建在调用方(
genToolHandler)内部通过条件分支控制,但buildToolResponseEnvelope本身与 raw_response 模式无感知耦合,后续若逻辑复杂化可维护性较差 - 建议:明确错误响应在两种模式下的行为策略(是否也跳过信封),并统一处理,或者为函数提供 raw_response 参数使其自包含
🟡 Minor
[1] Migration 字段状态与 model 定义不一致 [codex]
- 位置:
0013_mcpserver_raw_response.pyvsmodels.py - 问题:
models.py新字段只有help_text,无verbose_name;但 migration 记录了verbose_name="是否返回原始响应",未保留help_text。不影响 DB schema,但后续makemigrations可能生成无意义的AlterField - 建议:让 migration 中的字段状态与 model 声明完全一致
[2] 文档更新不完整 [claude]
- 位置:
src/dashboard/apigateway/apigateway/data/apidocs/zh/v2_sync_stage_mcp_servers.md - 问题:只更新了 v2 API 文档,未见 web API 对应文档更新
- 建议:检查并补全所有相关 API 文档
💬 Nit
[1] 多个 serializer 中 raw_response 字段重复定义 [claude]
- 可考虑使用 mixin 或基类减少重复,但不强求
[2] 部分测试用例命名可以更具体 [claude]
- 如
test_raw_response_default_false→should_return_wrapped_response_when_raw_response_disabled之类的描述性命名
优点
- 向后兼容设计良好:默认值为
false,对现有调用方无影响,两个 reviewer 均认可 - 配置链路打通:从 DB → serializer → mcp-proxy 配置结构 → server 层 → handler,整条链路完整
- 基础测试覆盖:涵盖了新字段的默认值语义、传递行为以及 handler 分支的正确性
- 代码组织清晰:遵循了项目分层架构规范,类型安全,字段命名语义明确
- 多协议支持:同时适配 SSE 和 Streamable HTTP 协议
综合建议
当前最需要处理的是 Blocking 问题:热更新链路不支持 raw_response,会导致该功能成为"可创建但不可更新"的半成品。建议合入前修正,并补充以下回归测试:
- 已有 server 切换
raw_response(resource version不变)时触发热更新的行为 raw_response=true且上游返回非 2xx 时的结果表现,确保错误响应行为也符合预期(对应 major 问题)
Minor 问题(migration 状态不一致、文档缺失)建议一并处理,cost 低、收益高。
由 codex-internal (gpt-5.4) + claude-internal 双模型 review,主 agent 汇总 | [from openclaw-internal]
ab89f9b to
0b8b8e7
Compare
- Add raw_response_enabled boolean field to MCPServer Django model with migration - Add raw_response_enabled to v2/sync and web/mcp_server serializers - Add RawResponseEnabled field to Go MCPServer model and MCPServerConfig - Support rawResponse in proxy server and tool handler - When raw_response_enabled is enabled, mcp-proxy returns raw API response without wrapping envelope - Support hot-reload for raw_response_enabled field change - Add unit tests for raw_response_enabled in Go (model, config, server, proxy, mcp) - Update apidocs for sync API
3588df9 to
69c9a1b
Compare
- Add raw_response_enabled boolean field to MCPServer Django model with migration - Add raw_response_enabled to v2/sync and web/mcp_server serializers - Add RawResponseEnabled field to Go MCPServer model and MCPServerConfig - Support rawResponse in proxy server and tool handler - When raw_response_enabled is enabled, mcp-proxy returns raw API response without wrapping envelope - Support hot-reload for raw_response_enabled field change - Add unit tests for raw_response_enabled in Go (model, config, server, proxy, mcp) - Update apidocs for sync API
Summary
raw_responseboolean field to MCPServer Django model with migrationraw_responseto web/mcp_server serializers (create, update, output)raw_responseto v2/sync serializerRawResponsefield to Go MCPServer model and MCPServerConfigrawResponsein proxy server and tool handlerraw_responseis enabled, mcp-proxy returns raw API response without wrapping in envelope (status_code, request_id, trace_id, etc.)raw_responsein Go (model, config, server, proxy, mcp)Test Plan