Skip to content

Conversation

@25621
Copy link
Contributor

@25621 25621 commented Sep 18, 2025

What?

Fixes MCP server initialization failures on Windows when using script-based tools like npx, pnpm, and yarn that rely on .cmd/.bat files rather than .exe binaries.

Fixes #2945

Why?

Windows users encounter "program not found" errors when configuring MCP servers with commands like npx in their ~/.codex/config.toml. This happens because:

  • Tools like npx are batch scripts (npx.cmd) on Windows, not executable binaries
  • Rust's std::process::Command bypasses the shell and cannot execute these scripts directly
  • The Windows shell normally handles this by checking PATHEXT for executable extensions

Without this fix, Windows users must specify full paths or add .cmd extensions manually, which breaks cross-platform compatibility.

How?

Added platform-specific program resolution using the which crate to find the correct executable path:

  • Windows: Resolves programs through PATH/PATHEXT to find .cmd/.bat scripts
  • Unix: Returns the program unchanged (no-op, as Unix handles scripts natively)

Changes

  • Added which = "6" dependency to mcp-client/Cargo.toml
  • Implemented program_resolver module in mcp_client.rs with platform-specific resolution
  • Added comprehensive tests for both Windows and Unix behavior

Testing

Added platform-specific tests to verify:

  • Unix systems execute scripts without extensions
  • Windows fails without proper extensions
  • Windows succeeds with explicit extensions
  • Cross-platform resolution enables successful execution

Tested on:

  • Windows 11 (NT 10.0.26100.0 x64)
  • PowerShell 5.1 & 7+, CMD, Git Bash
  • MCP servers: playwright, context7, supabase
  • WSL (verified no regression)

Local checks passed:

cargo test && cargo clippy --tests && cargo fmt -- --config imports_granularity=Item

Results

Before:

🖐 MCP client for `playwright` failed to start: program not found

After:

🖐 MCP client for `playwright` failed to start: request timed out

Windows users can now use simple commands like npx in their config without specifying full paths or extensions. The timeout issue is a separate concern that will be addressed in a follow-up PR.

@github-actions
Copy link

github-actions bot commented Sep 18, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@25621
Copy link
Contributor Author

25621 commented Sep 18, 2025

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Sep 18, 2025
@wbdb wbdb mentioned this pull request Sep 22, 2025
dylan-hurd-oai pushed a commit that referenced this pull request Oct 29, 2025
# Preserve PATH precedence & fix Windows MCP env propagation

## Problem & intent

Preserve user PATH precedence and reduce Windows setup friction for MCP
servers by avoiding PATH reordering and ensuring Windows child processes
receive essential env vars.

- Addresses: #4180 #5225 #2945 #3245 #3385 #2892 #3310 #3457 #4370  
- Supersedes: #4182, #3866, #3828 (overlapping/inferior once this
merges)
- Notes: #2626 / #2646 are the original PATH-mutation sources being
corrected.

---

## Before / After

**Before**  
- PATH was **prepended** with an `apply_patch` helper dir (Rust + Node
wrapper), reordering tools and breaking virtualenvs/shims on
macOS/Linux.
- On Windows, MCP servers missed core env vars and often failed to start
without explicit per-server env blocks.

**After**  
- Helper dir is **appended** to PATH (preserves user/tool precedence).  
- Windows MCP child env now includes common core variables and mirrors
`PATH` → `Path`, so typical CLIs/plugins work **without** per-server env
blocks.

---

## Scope of change

### `codex-rs/arg0/src/lib.rs`
- Append temp/helper dir to `PATH` instead of prepending.

### `codex-cli/bin/codex.js`
- Mirror the same append behavior for the Node wrapper.

### `codex-rs/rmcp-client/src/utils.rs`
- Expand Windows `DEFAULT_ENV_VARS` (e.g., `COMSPEC`, `SYSTEMROOT`,
`PROGRAMFILES*`, `APPDATA`, etc.).
- Mirror `PATH` → `Path` for Windows child processes.  
- Small unit test; conditional `mut` + `clippy` cleanup.

---

## Security effects

No broadened privileges. Only environment propagation for well-known
Windows keys on stdio MCP child processes. No sandbox policy changes and
no network additions.

---

## Testing evidence

**Static**  
- `cargo fmt`  
- `cargo clippy -p codex-arg0 -D warnings` → **clean**  
- `cargo clippy -p codex-rmcp-client -D warnings` → **clean**  
- `cargo test -p codex-rmcp-client` → **13 passed**

**Manual**  
- Local verification on Windows PowerShell 5/7 and WSL (no `unused_mut`
warnings on non-Windows targets).

---

## Checklist

- [x] Append (not prepend) helper dir to PATH in Rust and Node wrappers
- [x] Windows MCP child inherits core env vars; `PATH` mirrored to
`Path`
- [x] `cargo fmt` / `clippy` clean across touched crates  
- [x] Unit tests updated/passing where applicable  
- [x] Cross-platform behavior preserved (macOS/Linux PATH precedence
intact)
vinhnx pushed a commit to vinhnx/codex that referenced this pull request Nov 2, 2025
…#5579)

# Preserve PATH precedence & fix Windows MCP env propagation

## Problem & intent

Preserve user PATH precedence and reduce Windows setup friction for MCP
servers by avoiding PATH reordering and ensuring Windows child processes
receive essential env vars.

- Addresses: openai#4180 openai#5225 openai#2945 openai#3245 openai#3385 openai#2892 openai#3310 openai#3457 openai#4370  
- Supersedes: openai#4182, openai#3866, openai#3828 (overlapping/inferior once this
merges)
- Notes: openai#2626 / openai#2646 are the original PATH-mutation sources being
corrected.

---

## Before / After

**Before**  
- PATH was **prepended** with an `apply_patch` helper dir (Rust + Node
wrapper), reordering tools and breaking virtualenvs/shims on
macOS/Linux.
- On Windows, MCP servers missed core env vars and often failed to start
without explicit per-server env blocks.

**After**  
- Helper dir is **appended** to PATH (preserves user/tool precedence).  
- Windows MCP child env now includes common core variables and mirrors
`PATH` → `Path`, so typical CLIs/plugins work **without** per-server env
blocks.

---

## Scope of change

### `codex-rs/arg0/src/lib.rs`
- Append temp/helper dir to `PATH` instead of prepending.

### `codex-cli/bin/codex.js`
- Mirror the same append behavior for the Node wrapper.

### `codex-rs/rmcp-client/src/utils.rs`
- Expand Windows `DEFAULT_ENV_VARS` (e.g., `COMSPEC`, `SYSTEMROOT`,
`PROGRAMFILES*`, `APPDATA`, etc.).
- Mirror `PATH` → `Path` for Windows child processes.  
- Small unit test; conditional `mut` + `clippy` cleanup.

---

## Security effects

No broadened privileges. Only environment propagation for well-known
Windows keys on stdio MCP child processes. No sandbox policy changes and
no network additions.

---

## Testing evidence

**Static**  
- `cargo fmt`  
- `cargo clippy -p codex-arg0 -D warnings` → **clean**  
- `cargo clippy -p codex-rmcp-client -D warnings` → **clean**  
- `cargo test -p codex-rmcp-client` → **13 passed**

**Manual**  
- Local verification on Windows PowerShell 5/7 and WSL (no `unused_mut`
warnings on non-Windows targets).

---

## Checklist

- [x] Append (not prepend) helper dir to PATH in Rust and Node wrappers
- [x] Windows MCP child inherits core env vars; `PATH` mirrored to
`Path`
- [x] `cargo fmt` / `clippy` clean across touched crates  
- [x] Unit tests updated/passing where applicable  
- [x] Cross-platform behavior preserved (macOS/Linux PATH precedence
intact)
@etraut-openai
Copy link
Collaborator

Thanks for the contribution, and apologies for the slow response. We received a large number of PRs, and we're just now getting through the backlog.

It looks like this PR has gone stale. If this PR is still relevant, could you please resolve the merge conflicts and make sure the tests still run? Thanks!

@etraut-openai etraut-openai added the needs-response Additional information is requested label Nov 7, 2025
@25621 25621 force-pushed the fix/windows-mcp-script-resolution branch from b12b045 to 5c75710 Compare November 7, 2025 15:07
25621 added a commit to 25621/codex that referenced this pull request Nov 7, 2025
…ed tools

This ports the fix from the original PR openai#3828 to rmcp-client,
which replaced mcp-client in PR openai#5529.

On Windows, script-based MCP servers (e.g., npx, pnpm, yarn) that
rely on .cmd or .bat files fail to execute. This happens because
Rust's Command does not resolve scripts via PATHEXT like the
shell does.

This fix uses the which crate to resolve the full executable path
(including .cmd/.bat extensions) before spawning the process,
allowing these tools to run correctly.

Changes:
- Add which crate dependency to rmcp-client/Cargo.toml
- Implement program_resolver module with platform-specific logic:
  * Windows: Resolves .cmd/.bat scripts using which::which_in
  * Unix: No-op (OS handles shebangs natively)
- Modify new_stdio_client to resolve program path before Command::new
- Add unit tests for program resolution on both platforms

Fixes: openai#2945
@25621 25621 force-pushed the fix/windows-mcp-script-resolution branch from 5c75710 to 74e4237 Compare November 7, 2025 15:17
@25621
Copy link
Contributor Author

25621 commented Nov 7, 2025

Hi @etraut-openai,

Thank you for reviewing! I've resolved the conflicts and updated the PR:

The Windows script resolution logic remains unchanged - using the which crate to properly resolve .cmd/.bat scripts that Windows requires for tools like npx, pnpm, and yarn.

Ready for merge. Let me know if you need any adjustments!

@etraut-openai
Copy link
Collaborator

@25621, looks like there are some lint (cargo clippy) issues remaining.

…ed tools

This ports the fix from the original PR openai#3828 to rmcp-client,
which replaced mcp-client in PR openai#5529.

On Windows, script-based MCP servers (e.g., npx, pnpm, yarn) that
rely on .cmd or .bat files fail to execute. This happens because
Rust's Command does not resolve scripts via PATHEXT like the
shell does.

This fix uses the which crate to resolve the full executable path
(including .cmd/.bat extensions) before spawning the process,
allowing these tools to run correctly.

Changes:
- Add which crate dependency to rmcp-client/Cargo.toml
- Implement program_resolver module with platform-specific logic:
  * Windows: Resolves .cmd/.bat scripts using which::which_in
  * Unix: No-op (OS handles shebangs natively)
- Modify new_stdio_client to resolve program path before Command::new
- Add unit tests for program resolution on both platforms

Fixes: openai#2945
@25621 25621 force-pushed the fix/windows-mcp-script-resolution branch from 74e4237 to 577b2a6 Compare November 8, 2025 01:35
@25621
Copy link
Contributor Author

25621 commented Nov 9, 2025

@etraut-openai Fixed! Thanks for catching that.

Issue: The tracing::debug import was only used in Windows-specific code but included on all platforms.

Fix: Wrapped the import with #[cfg(windows)] to match its usage scope.

Verification:

  • cargo clippy -p codex-rmcp-client --tests - no warnings
  • cargo test -p codex-rmcp-client - all tests pass

The workflows are awaiting maintainer approval to run. Would appreciate if you could approve them when you get a chance. Thanks!

@etraut-openai etraut-openai removed the needs-response Additional information is requested label Nov 9, 2025
DioNanos pushed a commit to DioNanos/codex-termux that referenced this pull request Nov 10, 2025
…#5579)

# Preserve PATH precedence & fix Windows MCP env propagation

## Problem & intent

Preserve user PATH precedence and reduce Windows setup friction for MCP
servers by avoiding PATH reordering and ensuring Windows child processes
receive essential env vars.

- Addresses: openai#4180 openai#5225 openai#2945 openai#3245 openai#3385 openai#2892 openai#3310 openai#3457 openai#4370  
- Supersedes: openai#4182, openai#3866, openai#3828 (overlapping/inferior once this
merges)
- Notes: openai#2626 / openai#2646 are the original PATH-mutation sources being
corrected.

---

## Before / After

**Before**  
- PATH was **prepended** with an `apply_patch` helper dir (Rust + Node
wrapper), reordering tools and breaking virtualenvs/shims on
macOS/Linux.
- On Windows, MCP servers missed core env vars and often failed to start
without explicit per-server env blocks.

**After**  
- Helper dir is **appended** to PATH (preserves user/tool precedence).  
- Windows MCP child env now includes common core variables and mirrors
`PATH` → `Path`, so typical CLIs/plugins work **without** per-server env
blocks.

---

## Scope of change

### `codex-rs/arg0/src/lib.rs`
- Append temp/helper dir to `PATH` instead of prepending.

### `codex-cli/bin/codex.js`
- Mirror the same append behavior for the Node wrapper.

### `codex-rs/rmcp-client/src/utils.rs`
- Expand Windows `DEFAULT_ENV_VARS` (e.g., `COMSPEC`, `SYSTEMROOT`,
`PROGRAMFILES*`, `APPDATA`, etc.).
- Mirror `PATH` → `Path` for Windows child processes.  
- Small unit test; conditional `mut` + `clippy` cleanup.

---

## Security effects

No broadened privileges. Only environment propagation for well-known
Windows keys on stdio MCP child processes. No sandbox policy changes and
no network additions.

---

## Testing evidence

**Static**  
- `cargo fmt`  
- `cargo clippy -p codex-arg0 -D warnings` → **clean**  
- `cargo clippy -p codex-rmcp-client -D warnings` → **clean**  
- `cargo test -p codex-rmcp-client` → **13 passed**

**Manual**  
- Local verification on Windows PowerShell 5/7 and WSL (no `unused_mut`
warnings on non-Windows targets).

---

## Checklist

- [x] Append (not prepend) helper dir to PATH in Rust and Node wrappers
- [x] Windows MCP child inherits core env vars; `PATH` mirrored to
`Path`
- [x] `cargo fmt` / `clippy` clean across touched crates  
- [x] Unit tests updated/passing where applicable  
- [x] Cross-platform behavior preserved (macOS/Linux PATH precedence
intact)
youta7 added a commit to youta7/ta-codex that referenced this pull request Nov 10, 2025
@dylan-hurd-oai dylan-hurd-oai self-requested a review November 14, 2025 06:27
willy3087 pushed a commit to nextlw/elai_codex that referenced this pull request Nov 14, 2025
…#5579)

# Preserve PATH precedence & fix Windows MCP env propagation

## Problem & intent

Preserve user PATH precedence and reduce Windows setup friction for MCP
servers by avoiding PATH reordering and ensuring Windows child processes
receive essential env vars.

- Addresses: openai#4180 openai#5225 openai#2945 openai#3245 openai#3385 openai#2892 openai#3310 openai#3457 openai#4370  
- Supersedes: openai#4182, openai#3866, openai#3828 (overlapping/inferior once this
merges)
- Notes: openai#2626 / openai#2646 are the original PATH-mutation sources being
corrected.

---

## Before / After

**Before**  
- PATH was **prepended** with an `apply_patch` helper dir (Rust + Node
wrapper), reordering tools and breaking virtualenvs/shims on
macOS/Linux.
- On Windows, MCP servers missed core env vars and often failed to start
without explicit per-server env blocks.

**After**  
- Helper dir is **appended** to PATH (preserves user/tool precedence).  
- Windows MCP child env now includes common core variables and mirrors
`PATH` → `Path`, so typical CLIs/plugins work **without** per-server env
blocks.

---

## Scope of change

### `codex-rs/arg0/src/lib.rs`
- Append temp/helper dir to `PATH` instead of prepending.

### `codex-cli/bin/codex.js`
- Mirror the same append behavior for the Node wrapper.

### `codex-rs/rmcp-client/src/utils.rs`
- Expand Windows `DEFAULT_ENV_VARS` (e.g., `COMSPEC`, `SYSTEMROOT`,
`PROGRAMFILES*`, `APPDATA`, etc.).
- Mirror `PATH` → `Path` for Windows child processes.  
- Small unit test; conditional `mut` + `clippy` cleanup.

---

## Security effects

No broadened privileges. Only environment propagation for well-known
Windows keys on stdio MCP child processes. No sandbox policy changes and
no network additions.

---

## Testing evidence

**Static**  
- `cargo fmt`  
- `cargo clippy -p codex-arg0 -D warnings` → **clean**  
- `cargo clippy -p codex-rmcp-client -D warnings` → **clean**  
- `cargo test -p codex-rmcp-client` → **13 passed**

**Manual**  
- Local verification on Windows PowerShell 5/7 and WSL (no `unused_mut`
warnings on non-Windows targets).

---

## Checklist

- [x] Append (not prepend) helper dir to PATH in Rust and Node wrappers
- [x] Windows MCP child inherits core env vars; `PATH` mirrored to
`Path`
- [x] `cargo fmt` / `clippy` clean across touched crates  
- [x] Unit tests updated/passing where applicable  
- [x] Cross-platform behavior preserved (macOS/Linux PATH precedence
intact)
Copy link
Collaborator

@dylan-hurd-oai dylan-hurd-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! 2 small organizational comments to address, but overall this looks good to me

…penai#3828)

Per review feedback, extracting program_resolver module to its own file
for better code organization and maintainability.

- Move program_resolver mod to src/program_resolver.rs
- Reorder Unix/Windows functions (Unix first as simpler)
- Move related tests to the new module file
- Add module declaration to lib.rs
@etraut-openai etraut-openai added the needs-response Additional information is requested label Nov 14, 2025
@25621
Copy link
Contributor Author

25621 commented Nov 15, 2025

@dylan-hurd-oai Thanks for the review! I've addressed both comments:

  1. Reordered functions: Moved the Unix implementation first as it's simpler/shorter
  2. Extracted to separate file: Created src/program_resolver.rs with the module and its tests

The tests are now co-located with the module they're testing for better maintainability. All existing functionality remains unchanged - this is purely a refactoring for better code organization.

Ready for another review!

@etraut-openai etraut-openai removed the needs-response Additional information is requested label Nov 15, 2025
@dylan-hurd-oai
Copy link
Collaborator

Noting that I've tested this on a Windows device as well. Thanks for the fix! cc @gpeal for mcp visibility.

@dylan-hurd-oai dylan-hurd-oai merged commit f828cd2 into openai:main Nov 16, 2025
25 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Nov 16, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP client for playwright failed to start: program not found

3 participants