Skip to content

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

Merged
gpeal merged 6 commits into
mainfrom
gpeal/cwd-and-env-stdio
Oct 17, 2025
Merged

gpeal merged 6 commits into
mainfrom
gpeal/cwd-and-env-stdio

Conversation

@gpeal

@gpeal gpeal commented Oct 16, 2025 •

Copy link
Copy Markdown
Contributor

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:

[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.

@gpeal
gpeal force-pushed the gpeal/cwd-and-env-stdio branch from 96d1d25 to 5175155 Compare October 16, 2025 06:41
@gpeal
gpeal force-pushed the gpeal/cwd-and-env-stdio branch from 5175155 to 16c3867 Compare October 16, 2025 06:44
@gpeal
gpeal marked this pull request as ready for review October 16, 2025 06:49
@gpeal
gpeal requested review from bolinfest and jif-oai October 16, 2025 06:51
env,
env_vars,
cwd,
} => serde_json::json!({

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why aren't we just using serde for this again? Because this is UI, I guess?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm just adding a couple of fields and didn't want to expand the scope of this PR to refactor all of the code around it since this PR is big enough already.

Comment thread codex-rs/cli/src/mcp_cmd.rs Outdated
Comment thread codex-rs/core/src/mcp_connection_manager.rs
Comment thread codex-rs/core/src/mcp_connection_manager.rs Outdated
Comment thread codex-rs/core/tests/suite/rmcp_client.rs Outdated
Comment on lines +477 to +487
fn set_env_var(key: &str, value: &str) {
unsafe {
std::env::set_var(key, value);
}
}

fn remove_env_var(key: &str) {
unsafe {
std::env::remove_var(key);
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we have confidence this use case is sufficiently covered through some other means?

I do not want this in the codebase: I can't personally police all the places this happens and the risk of copy/paste here is very high.

If you think it is important to have a unit test for create_env_for_mcp_server(), then please pass in an abstraction around std::env::var.

}

#[test]
#[serial(extra_rmcp_env)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you insist on continuing to use this pattern, please add detailed information to AGENTS.md so that we have some chance of catching when it is being misused/abused.

}

if let Some(cwd) = cwd {
entry["cwd"] = toml_edit::value(cwd.to_string_lossy().to_string());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is cwd guaranteed to be an absolute, normalized path?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We write the same PathBuf that we read without modifying it.

Comment thread docs/config.md Outdated
@gpeal
gpeal requested a review from bolinfest October 16, 2025 17:41
Comment thread codex-rs/cli/tests/mcp_list.rs Outdated
.assert()
.success();

let runtime = tokio::runtime::Runtime::new()?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This seems unusual: is there a reason why you need to introduce a Runtime instead of making this an async test? Also, I see the runtime is explicitly dropped. Can you change to async or add a comment why this is being done?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bad Codex. Thanks 🙏

@gpeal
gpeal merged commit bdda762 into main Oct 17, 2025
34 of 36 checks passed
@gpeal
gpeal deleted the gpeal/cwd-and-env-stdio branch October 17, 2025 04:24
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 17, 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.

2 participants