Track remote MCP header environment variables (#39930)

## Why

Remote HTTP MCP connections can source header values from the host environment,
so those variables must remain part of the connection identity even when the MCP
server runs in an executor environment.

## What changed

- Track `env_http_headers` variables for remote HTTP MCP connections.
- Continue tracking `bearer_token_env_var` only for local environments, where the
  host resolves the token.

## Testing

Add coverage that verifies remote connections track host header variables without
tracking executor bearer-token variables, while local connections track both.

GitOrigin-RevId: 8fe175c54a101721a27b76495dcd298f0c2bc6a3
This commit is contained in:
jif
2026-08-21 13:22:25 +00:00
committed by copyberry
parent 93c54bca38
commit 9c3da20b3f
2 changed files with 37 additions and 3 deletions
+5 -3
View File
@@ -329,15 +329,13 @@ fn referenced_environment_variables(config: &McpServerConfig) -> Vec<(String, Op
.filter(|env_var| !env_var.is_remote_source())
.map(|env_var| env_var.name().to_string())
.collect::<Vec<_>>(),
McpServerTransportConfig::StreamableHttp { .. } if !config.is_local_environment() => {
Vec::new()
}
McpServerTransportConfig::StreamableHttp {
bearer_token_env_var,
env_http_headers,
..
} => bearer_token_env_var
.iter()
.filter(|_| config.is_local_environment())
.chain(env_http_headers.iter().flat_map(|headers| headers.values()))
.cloned()
.collect(),
@@ -421,3 +419,7 @@ impl From<&EffectiveMcpServer> for McpServerMetadata {
}
}
}
#[cfg(test)]
#[path = "server_tests.rs"]
mod tests;
+32
View File
@@ -0,0 +1,32 @@
use super::referenced_environment_variables;
use codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID;
use codex_config::McpServerConfig;
use pretty_assertions::assert_eq;
#[test]
fn remote_http_connections_track_host_headers_but_not_executor_bearer_tokens() {
let mut config: McpServerConfig = serde_json::from_value(serde_json::json!({
"url": "https://example.com/mcp",
"environment_id": "executor-1",
"bearer_token_env_var": "NODE_REPL_AUTH_TOKEN",
"env_http_headers": {"X-Api-Key": "PATH"},
}))
.expect("remote MCP configuration should deserialize");
assert_eq!(
referenced_environment_variables(&config),
vec![("PATH".to_string(), std::env::var_os("PATH"))],
);
config.environment_id = DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string();
assert_eq!(
referenced_environment_variables(&config),
vec![
(
"NODE_REPL_AUTH_TOKEN".to_string(),
std::env::var_os("NODE_REPL_AUTH_TOKEN"),
),
("PATH".to_string(), std::env::var_os("PATH")),
],
);
}