[GH-ISSUE #6174] [Bug] MCP capture_process_scenario ignores the server's selected environment #3771

Closed
opened 2026-10-31 00:43:51 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @Adolanium on GitHub (Oct 21, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6174

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

The MCP capture_process_scenario tool runs captures with the ambient process.env instead of the environment the MCP server was created with. A server created with createServer(..., { environment }) uses that environment for capability probes, but process capture ignores it: a bare executable name is resolved on the ambient PATH, and the child inherits ambient variables instead of the selected ones. rea capture-process-scenario passes its selected environment, so the same request can behave differently over MCP and the CLI.

Reproduction

Executed on Linux (WSL Ubuntu, Node 24.18.0) at upstream/main 76dbc32f3, through the in-memory MCP client in a test:

  1. Create a server with createServer({ kind: "session", session }, { environment: { PATH: "<dir with a probe script>", REA_CAPTURE_INJECTED_MARKER: "injected-value", REA_CAPTURE_SCENARIO_OVERRIDE: "host-value" } }). The probe script prints $REA_CAPTURE_INJECTED_MARKER|$REA_CAPTURE_SCENARIO_OVERRIDE.
  2. Call capture_process_scenario with executable: "rea-injected-process-probe" and environment: { REA_CAPTURE_SCENARIO_OVERRIDE: "scenario-value" }.
  3. With process.env in the handler (current main), this test fails: the capture does not print injected-value|scenario-value. A second test that mocks the capture owner shows the handler passes the ambient process.env as its environment argument.

Expected behavior

An MCP capture resolves the executable and builds the child's environment from the server's selected environment, with the scenario's environment entries overriding it, as the CLI does. The probe prints injected-value|scenario-value.

Impact and scope

Embedders and tests that select an environment for the MCP server, for example a PATH or provider variables, get ambient values for process capture only. The stdio entry point creates its server from the process environment, so its default behavior is the same either way.

REA version

6.7.0, revision 76dbc32f3

Runtime and platform

Linux (WSL Ubuntu), Node 24.18.0

Target and artifact context

A local shell-script probe; no target binary.

Interface

MCP

Earliest failure stage

Capture or observation

Relevant output or evidence

src/server/registerSessionTools.ts, registerProcessTools:

captureProcessScenario(
  input,
  context.mcpReq.signal,
  process.platform,
  process.env,
  ...

createServer snapshots options.environment (snapshotEnvironment(options.environment ?? process.env)) and passes its selected options to registerSessionTools, but SessionToolOptions has no environment, so the handler cannot use it. ProcessCli.ts passes its selected environment to the same function.

Typed outcome or recovery expected

No new error. The capture result should reflect the selected environment.

Analysis or suspected cause

The MCP session tool registration predates the server's environment snapshot and still reads process.env directly. Passing the snapshot through SessionToolOptions lets the handler use the same environment as the rest of the server.

Additional context

Fixed by #6173.

Originally created by @Adolanium on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6174 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior The MCP `capture_process_scenario` tool runs captures with the ambient `process.env` instead of the environment the MCP server was created with. A server created with `createServer(..., { environment })` uses that environment for capability probes, but process capture ignores it: a bare executable name is resolved on the ambient `PATH`, and the child inherits ambient variables instead of the selected ones. `rea capture-process-scenario` passes its selected environment, so the same request can behave differently over MCP and the CLI. ### Reproduction Executed on Linux (WSL Ubuntu, Node 24.18.0) at upstream/main 76dbc32f3, through the in-memory MCP client in a test: 1. Create a server with `createServer({ kind: "session", session }, { environment: { PATH: "<dir with a probe script>", REA_CAPTURE_INJECTED_MARKER: "injected-value", REA_CAPTURE_SCENARIO_OVERRIDE: "host-value" } })`. The probe script prints `$REA_CAPTURE_INJECTED_MARKER|$REA_CAPTURE_SCENARIO_OVERRIDE`. 2. Call `capture_process_scenario` with `executable: "rea-injected-process-probe"` and `environment: { REA_CAPTURE_SCENARIO_OVERRIDE: "scenario-value" }`. 3. With `process.env` in the handler (current main), this test fails: the capture does not print `injected-value|scenario-value`. A second test that mocks the capture owner shows the handler passes the ambient `process.env` as its environment argument. ### Expected behavior An MCP capture resolves the executable and builds the child's environment from the server's selected environment, with the scenario's `environment` entries overriding it, as the CLI does. The probe prints `injected-value|scenario-value`. ### Impact and scope Embedders and tests that select an environment for the MCP server, for example a `PATH` or provider variables, get ambient values for process capture only. The stdio entry point creates its server from the process environment, so its default behavior is the same either way. ### REA version 6.7.0, revision `76dbc32f3` ### Runtime and platform Linux (WSL Ubuntu), Node 24.18.0 ### Target and artifact context A local shell-script probe; no target binary. ### Interface MCP ### Earliest failure stage Capture or observation ### Relevant output or evidence `src/server/registerSessionTools.ts`, `registerProcessTools`: ```ts captureProcessScenario( input, context.mcpReq.signal, process.platform, process.env, ... ``` `createServer` snapshots `options.environment` (`snapshotEnvironment(options.environment ?? process.env)`) and passes its selected options to `registerSessionTools`, but `SessionToolOptions` has no `environment`, so the handler cannot use it. `ProcessCli.ts` passes its selected `environment` to the same function. ### Typed outcome or recovery expected No new error. The capture result should reflect the selected environment. ### Analysis or suspected cause The MCP session tool registration predates the server's environment snapshot and still reads `process.env` directly. Passing the snapshot through `SessionToolOptions` lets the handler use the same environment as the rest of the server. ### Additional context Fixed by #6173.
Author
Owner

@XinwangTao commented on GitHub (Oct 22, 2026):

确认这是环境隔离语义不一致的问题:服务器创建时显式传入的 { environment } 应该覆盖 ambient env,capture 却绕开了它,导致同一请求在 CLI 和 MCP 下行为不同,这对"进程观测结果可复现"很伤。建议 #6173 修复时顺带扫一遍其它会启动子进程的 MCP tool(capability probe、各类 decoder 等)是否也有"用 ambient env 而非 server env"的同类问题,别让同一根因漏在别的工具里;验收用例里最好加上"server env 与 ambient env 同时存在时以 server env 为准"的断言,并把 CLI 与 MCP 两条路径的输出放一起对比。

<!-- gh-comment-id:6330358894 --> @XinwangTao commented on GitHub (Oct 22, 2026): 确认这是环境隔离语义不一致的问题:服务器创建时显式传入的 { environment } 应该覆盖 ambient env,capture 却绕开了它,导致同一请求在 CLI 和 MCP 下行为不同,这对"进程观测结果可复现"很伤。建议 #6173 修复时顺带扫一遍其它会启动子进程的 MCP tool(capability probe、各类 decoder 等)是否也有"用 ambient env 而非 server env"的同类问题,别让同一根因漏在别的工具里;验收用例里最好加上"server env 与 ambient env 同时存在时以 server env 为准"的断言,并把 CLI 与 MCP 两条路径的输出放一起对比。
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3771
No description provided.