[MCP] Allow specifying cwd and additional env vars (#5246)

This makes stdio mcp servers more flexible by allowing users to specify
the cwd to run the server command from and adding additional environment
variables to be passed through to the server.

Example config using the test server in this repo:
```toml
[mcp_servers.test_stdio]
cwd = "/Users/<user>/code/codex/codex-rs"
command = "cargo"
args = ["run", "--bin", "test_stdio_server"]
env_vars = ["MCP_TEST_VALUE"]
```

@bolinfest I know you hate these env var tests but let's roll with this
for now. I may take a stab at the env guard + serial macro at some
point.
This commit is contained in:
Gabriel Peal authored and GitHub committed 2025-10-17 00:24:43 -04:00
1 parent da5492694b
commit bdda762deb
17 files changed
+650 -76

No files matched your search

+15 -9
View File
@@ -20,6 +20,7 @@ use crate::wrapping::RtOptions;
use crate::wrapping::word_wrap_line;
use crate::wrapping::word_wrap_lines;
use base64::Engine;
use codex_common::format_env_display::format_env_display;
use codex_core::config::Config;
use codex_core::config_types::McpServerTransportConfig;
use codex_core::config_types::ReasoningSummaryFormat;
@@ -1013,7 +1014,13 @@ pub(crate) fn new_mcp_tools_output(
lines.push(vec![" • Auth: ".into(), status.to_string().into()].into());
match &cfg.transport {
McpServerTransportConfig::Stdio { command, args, env } => {
McpServerTransportConfig::Stdio {
command,
args,
env,
env_vars,
cwd,
} => {
let args_suffix = if args.is_empty() {
String::new()
} else {
@@ -1022,13 +1029,13 @@ pub(crate) fn new_mcp_tools_output(
let cmd_display = format!("{command}{args_suffix}");
lines.push(vec![" • Command: ".into(), cmd_display.into()].into());
if let Some(env) = env.as_ref()
&& !env.is_empty()
{
let mut env_pairs: Vec<String> =
env.iter().map(|(k, v)| format!("{k}={v}")).collect();
env_pairs.sort();
lines.push(vec![" • Env: ".into(), env_pairs.join(" ").into()].into());
if let Some(cwd) = cwd.as_ref() {
lines.push(vec![" • Cwd: ".into(), cwd.display().to_string().into()].into());
}
let env_display = format_env_display(env.as_ref(), env_vars);
if env_display != "-" {
lines.push(vec![" • Env: ".into(), env_display.into()].into());
}
}
McpServerTransportConfig::StreamableHttp {
@@ -1077,7 +1084,6 @@ pub(crate) fn new_mcp_tools_output(
PlainHistoryCell { lines }
}
pub(crate) fn new_info_event(message: String, hint: Option<String>) -> PlainHistoryCell {
let mut line = vec!["• ".dim(), message.into()];
if let Some(hint) = hint {