fix: unconditionally enrich shell PATH for MCP stdio subprocesses#4220
Closed
weikejia123 wants to merge 1 commit into
Closed
fix: unconditionally enrich shell PATH for MCP stdio subprocesses#4220weikejia123 wants to merge 1 commit into
weikejia123 wants to merge 1 commit into
Conversation
MCP plugin 使用绝对路径命令(如 /path/to/wrapper.sh)时, resolveStdioExecutable 识别到路径中含分隔符后直接返回, 跳过了 defaultStdioShellPATH 对子进程环境变量 PATH 的富化。 这导致 wrapper 脚本中 exec 的子工具(如 uvx、npx)在 macOS GUI 启动环境下找不到,报类似这样的错误: plugin "MiniMax": read: EOF: stderr: uvx: not found 将 shell PATH 探测从"命令查找失败的回退路径"提升为 resolveStdioExecutable 中独立的、无条件的初始化步骤。 新辅助函数 enrichStdioShellPATH 在 hasPathSeparator 检查 和 lookPathInEnv 之前执行,确保每个 MCP stdio 子进程 都继承用户交互式 shell 的完整 PATH。 影响范围: - 使用绝对/相对路径命令的 MCP stdio plugins 获得完整 shell PATH - 裸命令名路径不受影响(之前已能正确查找) - Windows 行为不变(由独立的 windowsStdioFallbackPATH 处理) - shell 探测有 2 秒超时保护,无 shell 环境无副作用 - 向后兼容:现有工作配置不受影响
Owner
|
Thanks @weikejia123 — sharp diagnosis and the right fix. The point that "the command resolving" and "the command's children resolving" are two different things is exactly it. Landed in #4268 with your commit preserved, plus one small follow-on: since the enrichment now probes the login shell for every stdio server, I memoized the first non-empty probe so it's a single shell spawn per process instead of one per server. Appreciate the clear root-cause writeup. |
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.
问题
MCP stdio transport 启动子进程时,如果命令是绝对路径(如
/path/to/wrapper.sh),子进程环境变量PATH不包含用户交互式 shell 的完整路径(如/opt/homebrew/bin),导致 wrapper 脚本中exec的子工具(uvx、npx等)找不到。报错示例:
根因
resolveStdioExecutable(internal/plugin/transport_stdio.go)中有三条路径:shell PATH 探测(
defaultStdioShellPATH)的触发条件是"命令未在 PATH 中找到",但"命令本身能否被找到"和"命令的运行时依赖能否被找到"是两件事。用绝对路径写的命令入口同样需要正确的 PATH 才能让它的子进程正常工作。此外,macOS GUI 应用(Finder / Dock /
open(1))启动时不继承用户~/.zshrc中配置的 PATH(如/opt/homebrew/bin),defaultStdioShellPATH正是为弥补此缺陷而设计的。但它被错误地限定在了"命令未找到"的回退路径中。修复
将 shell PATH 富化从"命令查找失败的回退路径"提升为
resolveStdioExecutable中独立的、无条件的初始化步骤。提取了辅助函数enrichStdioShellPATH,在hasPathSeparator检查和lookPathInEnv查找之前执行,确保每个 MCP stdio 子进程都继承用户交互式 shell 的完整 PATH。修复前:
修复后:
影响范围
windowsStdioFallbackPATH处理)测试
go vet无警告go test ./internal/plugin/全部 11 个测试通过