Skip to content

feat(agent): support northbound MCP header passthrough (Phase 1) - #4329

Open
yunshuang-hw wants to merge 5 commits into
developfrom
t30057956-header-passthrough
Open

yunshuang-hw wants to merge 5 commits into
developfrom
t30057956-header-passthrough

Conversation

@yunshuang-hw

@yunshuang-hw yunshuang-hw commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

背景

北向调用方(外部 CRM/工单等系统)在调用 Nexent 智能体时,往往需要把自身的身份类 header(Cookie、Authorization、X-User-Id 等)透传到该智能体所使用的远程 MCP 服务,才能通过 MCP 后端的鉴权。

Phase 1 提供受控透传 + 占位符引擎:调用方通过 runtime metadata 的保留字段传入 header,由 runtime 在构造 MCP 会话时注入;同时支持管理员在 MCP 静态 header 里用 ${HeaderName} 占位符引用这些值。

变更内容

开关与迁移

  • ag_tenant_agent_t 新增两列 allow_mcp_header_passthrough、strict_mcp_placeholder_resolution,默认 false,存量 agent 行为完全不变(deploy/sql/migrations/v2.9.0_009_allow_mcp_header_passthrough.sql)
  • 同步更新 ORM 模型与 AgentInfoRequest 契约

请求侧准入(infrastructure/serialization/runtime_metadata.py)

  • 保留字段 metadata._mcp_headers(全局)与 _mcp_headers_by_server(按 MCP server URL 路由,优先于全局)
  • 白名单放行:authorization / cookie / x-tenant-id / x-user-id / x-request-id / x-trace-id
  • 拒绝 hop-by-hop 头(host、content-length、connection、transfer-encoding 等)
  • 单值上限 4KB,累计上限 16KB

注入引擎(management/services/agent/mcp_passthrough.py)

  • 提取 → 路由 → 合并 → 占位符解析四段式,全部收敛在单一模块
  • 静态优先:MCP server 级预设 header(含平台内部 token)不会被调用方覆盖;比较按 HTTP 语义做大小写不敏感处理,避免 Cookie/cookie 重复出站
  • 占位符:${HeaderName} 大小写不敏感解析;$${Name} 转义为字面量;开关关闭时不解析真实占位符并丢弃该条 header
  • fail-closed:任一占位符无法解析则整条 header 丢弃并告警;严格模式下直接返回 400
  • 审计日志只记录 header 名与占位符名,不记录任何值

错误码

码 含义 HTTP
010109 header key 被禁止(白名单外 / hop-by-hop) 400
010110 header 值超出大小限制 400
010111 _mcp_headers_by_server 的 URL 未匹配任何 MCP server 400
010112 严格模式下占位符未解析 400

prompt 隔离(sdk/nexent/core/agents/core_agent.py)

  • 序列化 runtime metadata 到 prompt 前递归剔除所有 _ 前缀键,保留字段不会泄漏进模型上下文

错误码透传修复

  • gateway/api/northbound.py 的兜底 except Exception 会吞掉 AppException 导致 500,已放行给全局处理器
  • services/northbound_service.py 原先把所有 metadata 校验错误统一降级为 010106,改为按校验码精确映射

测试

单元测试

  • 新增 test/backend/management/test_mcp_header_passthrough.py(覆盖提取、路由、静态优先、占位符、fail-closed、审计日志脱敏等)
  • 增补 test/backend/utils/test_runtime_metadata_utils.py(白名单、hop-by-hop、结构非法、4KB/16KB 边界)
  • 增补 test/sdk/core/agents/test_core_agent.py(保留字段剔除、不修改入参)
  • 增补 test/backend/services/test_northbound_service.py(错误码映射桩)

三套新增/增补用例 241 passed;回归 test_northbound_app.py 112 passed、test_northbound_service.py 118 passed。

集成验证

  • 数据层 14 条断言:开关门控、by_server 路由、URL 未匹配 400、严格模式 400、静态优先合并
  • 真实 MCP 出站抓包 5 条断言:静态 auth 保留、${Cookie} 解析、动态 header 注入、无字面量 ${ 残留
  • northbound 端到端:外部系统透传 5 个 header → runtime 记录 event=passthrough_injected → MCP 侧收到全部 header 且对话历史正常落库
a0d9ce26-0a29-469b-9031-782464b0b831

兼容性

  • 两个开关默认关闭,存量 agent 不传 metadata 时行为零变化
  • 未开启 allow_chat_metadata 的 agent 仍在准入层被 010105 拦截
  • 需要执行迁移 v2.9.0_009

yunshuang-hw and others added 3 commits November 10, 2026 19:30
Add per-agent switches (allow_mcp_header_passthrough,
strict_mcp_placeholder_resolution) and a ${HeaderName} placeholder engine
that lets northbound callers inject allowed HTTP headers into MCP sessions
via metadata._mcp_headers / _mcp_headers_by_server.

- migration + ORM/Pydantic for the two agent-level switches
- runtime_metadata validation for reserved fields (key whitelist, size limits)
- mcp_passthrough module: extraction, URL routing, static-priority merge,
  placeholder resolution with $${ escape, fail-closed + strict 400 mode
- run pipeline injects passthrough headers into mcp_host and logs auditable
  key-only events
- SDK prompt serialization strips underscore-prefixed reserved keys
- northbound error mapping for the new metadata validation codes

Co-authored-by: Trae <noreply@trae.ai>
Generated-by: trae
@yunshuang-hw yunshuang-hw added the ai-assisted PR authored or co-authored with AI assistance label Nov 11, 2026
Only add the headers key to mcp_host entries and only forward
runtime_metadata / metadata to the run payload when passthrough actually
contributes or the caller supplied metadata. This restores the previous
payload for agents that do not use the feature and drops two unused
bookkeeping flags. Register mcp_passthrough in the management service
architecture inventory.

Co-authored-by: Trae <noreply@trae.ai>
Generated-by: trae
@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Add cases for mode-less routing, switch-off by_server audit logging, header-less server shape preservation, blank header key predicate, serialization-failure wrapping, AppException propagation in the northbound chat route, and request metadata forwarding into agent run creation. Brings mcp_passthrough and runtime_metadata to full line and branch coverage.

Co-authored-by: Trae <noreply@trae.ai>

Generated-by: trae

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted PR authored or co-authored with AI assistance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant