Skip to content

STDIO MCP server 透传认证用户身份(opt-in per server,供 on-behalf-of 调用 REST 后端) #459

Description

@ncw1992120

需求

把发起调用的认证用户身份透传给 STDIO MCP server,让 MCP server 能代表该用户调用底层 RESTful 后端(on-behalf-of)。

为什么现状做不到

  • STDIO MCP client 是每个 server 配置一个共享、长期存活的子进程McpClientManager.clients = ConcurrentHashMap<serverId, McpSyncClient>),所有用户/workspace/会话共用。
  • env(envJson)在子进程 spawn 时一次性注入,expandEnvVars 只展开 JVM system property + OS env,没有 per-user 上下文,spawn 后不可变。
  • STDIO 没有 HTTP 那种 per-request header 通道。

所以身份不能走 env(共享进程 + 静态),必须随每次 tool call 在带内传递。而当前 PrefixedNameToolCallback.call(toolInput, toolContext) 只把 LLM 产生的参数原样发给子进程,没有注入身份。

方案:受信层每次调用注入身份(opt-in per server)

  • MateClaw 在 tool-call 时已知道认证用户:ToolExecutionContext.username(toolContext)
  • McpClientManager.wrapServerCallbacks 里,对显式开启的 server,把每个 callback 再包一层 IdentityForwardingToolCallback:调用前把 __mateclaw_user__ 注入进 toolInput 的 JSON(覆盖 LLM 可能伪造的同名值),再转发。
  • MCP server 侧读出该字段、剥掉,作为 header(如 X-On-Behalf-Of)连同后端 API Key 一起调 REST。

安全要点

  • 必须 opt-in per server:默认全量注入会把用户名泄漏给任意第三方 MCP server。用配置允许清单 mateclaw.mcp.identity-forward.servers(按 server name 或 id)开启。
  • 身份由受信 Java 代码注入、不经 LLM;LLM 若塞了同名字段会被覆盖。
  • 明文 username 仅适合 REST 在内网、且信任 MCP 子进程的场景;更强场景应改为 MateClaw 签发短时 JWT(本 issue 先做明文 opt-in,签名 token 可作后续)。

范围

  • 新增 IdentityForwardingToolCallback + McpIdentityForwardProperties(允许清单)。
  • McpClientManager.wrapServerCallbacks 对 opt-in server 包装。
  • 单测覆盖:注入存在、覆盖 LLM 值、未 opt-in 不注入、无用户名不注入。
  • 文档:MCP 接入说明里写明 opt-in 配置 + MCP server 侧如何读取 __mateclaw_user__

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions