2025-09-26 10:13:37 -07:00
|
|
|
[package]
|
|
|
|
|
name = "codex-rmcp-client"
|
2025-11-24 12:22:18 -08:00
|
|
|
version.workspace = true
|
|
|
|
|
edition.workspace = true
|
|
|
|
|
license.workspace = true
|
2025-09-26 10:13:37 -07:00
|
|
|
|
|
|
|
|
[lints]
|
|
|
|
|
workspace = true
|
|
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
|
anyhow = "1"
|
2025-10-03 10:43:12 -07:00
|
|
|
axum = { workspace = true, default-features = false, features = [
|
|
|
|
|
"http1",
|
|
|
|
|
"tokio",
|
|
|
|
|
] }
|
2025-10-27 12:10:11 -07:00
|
|
|
codex-keyring-store = { workspace = true }
|
2025-10-08 14:37:57 -07:00
|
|
|
codex-protocol = { workspace = true }
|
2026-02-06 21:26:36 -08:00
|
|
|
codex-utils-pty = { workspace = true }
|
2026-01-30 15:46:33 -08:00
|
|
|
codex-utils-home-dir = { workspace = true }
|
2025-10-27 12:10:11 -07:00
|
|
|
futures = { workspace = true, default-features = false, features = ["std"] }
|
2025-11-16 23:07:34 -06:00
|
|
|
keyring = { workspace = true, features = ["crypto-rust"] }
|
2025-10-27 12:10:11 -07:00
|
|
|
oauth2 = "5"
|
|
|
|
|
reqwest = { version = "0.12", default-features = false, features = [
|
|
|
|
|
"json",
|
|
|
|
|
"stream",
|
2026-01-22 07:57:18 -08:00
|
|
|
"rustls-tls",
|
2025-10-27 12:10:11 -07:00
|
|
|
] }
|
2025-10-03 10:43:12 -07:00
|
|
|
rmcp = { workspace = true, default-features = false, features = [
|
|
|
|
|
"auth",
|
2025-09-26 10:13:37 -07:00
|
|
|
"base64",
|
|
|
|
|
"client",
|
|
|
|
|
"macros",
|
|
|
|
|
"schemars",
|
|
|
|
|
"server",
|
|
|
|
|
"transport-child-process",
|
2025-09-26 18:24:01 -07:00
|
|
|
"transport-streamable-http-client-reqwest",
|
|
|
|
|
"transport-streamable-http-server",
|
|
|
|
|
] }
|
2026-01-13 10:22:51 -08:00
|
|
|
schemars = { workspace = true }
|
2025-10-03 10:43:12 -07:00
|
|
|
serde = { workspace = true, features = ["derive"] }
|
|
|
|
|
serde_json = { workspace = true }
|
|
|
|
|
sha2 = { workspace = true }
|
|
|
|
|
tiny_http = { workspace = true }
|
|
|
|
|
tokio = { workspace = true, features = [
|
2025-09-26 10:13:37 -07:00
|
|
|
"io-util",
|
|
|
|
|
"macros",
|
|
|
|
|
"process",
|
|
|
|
|
"rt-multi-thread",
|
|
|
|
|
"sync",
|
|
|
|
|
"io-std",
|
|
|
|
|
"time",
|
|
|
|
|
] }
|
2025-10-03 10:43:12 -07:00
|
|
|
tracing = { workspace = true, features = ["log"] }
|
|
|
|
|
urlencoding = { workspace = true }
|
|
|
|
|
webbrowser = { workspace = true }
|
fix: resolve Windows MCP server execution for script-based tools (#3828)
## 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:**
```bash
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.
---------
Co-authored-by: Eric Traut <etraut@openai.com>
2025-11-17 06:41:10 +09:00
|
|
|
which = { workspace = true }
|
2025-09-26 10:13:37 -07:00
|
|
|
|
|
|
|
|
[dev-dependencies]
|
2025-12-23 19:29:32 -08:00
|
|
|
codex-utils-cargo-bin = { workspace = true }
|
2025-10-03 10:43:12 -07:00
|
|
|
pretty_assertions = { workspace = true }
|
2025-10-16 21:24:43 -07:00
|
|
|
serial_test = { workspace = true }
|
2025-10-03 10:43:12 -07:00
|
|
|
tempfile = { workspace = true }
|
2025-11-16 23:07:34 -06:00
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
|
|
|
keyring = { workspace = true, features = ["linux-native-async-persistent"] }
|
|
|
|
|
|
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
|
|
|
keyring = { workspace = true, features = ["apple-native"] }
|
|
|
|
|
|
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
|
|
|
keyring = { workspace = true, features = ["windows-native"] }
|
|
|
|
|
|
|
|
|
|
[target.'cfg(any(target_os = "freebsd", target_os = "openbsd"))'.dependencies]
|
|
|
|
|
keyring = { workspace = true, features = ["sync-secret-service"] }
|