Repository navigation
feat(agent): support northbound MCP header passthrough (Phase 1) - #4329
Open
yunshuang-hw wants to merge 5 commits into
Open
yunshuang-hw wants to merge 5 commits into
yunshuang-hw wants to merge 5 commits into
Conversation
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
requested review from
Dallas98,
Jasonxia007,
WMC001,
YehongPan and
jeffwu-1999
as code owners
November 11, 2026 07:01
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 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
北向调用方(外部 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)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-idhost、content-length、connection、transfer-encoding等)注入引擎(
management/services/agent/mcp_passthrough.py)Cookie/cookie重复出站${HeaderName}大小写不敏感解析;$${Name}转义为字面量;开关关闭时不解析真实占位符并丢弃该条 header错误码
_mcp_headers_by_server的 URL 未匹配任何 MCP serverprompt 隔离(
sdk/nexent/core/agents/core_agent.py)_前缀键,保留字段不会泄漏进模型上下文错误码透传修复
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.py112 passed、test_northbound_service.py118 passed。集成验证
${Cookie}解析、动态 header 注入、无字面量${残留event=passthrough_injected→ MCP 侧收到全部 header 且对话历史正常落库兼容性
allow_chat_metadata的 agent 仍在准入层被010105拦截v2.9.0_009