Looking at [src/mcp_stdio_client.cpp:362]
for (const auto& [key, value] : env_vars_.items()) {
std::string env_var = key + "=" + convert_to_string(value);
if (putenv(const_cast<char*>(env_var.c_str())) != 0) { ... }
}
putenv() doesn't copy its argument — it stores the pointer. The local std::string env_var goes out of scope at the end of each iteration, leaving putenv with a dangling pointer to freed memory. By the time execvp runs (after the loop), the environment is corrupted, and the child sees no environment variables. (It should be setenv(key, value, 1), which copies.)
Looking at [src/mcp_stdio_client.cpp:362]
putenv() doesn't copy its argument — it stores the pointer. The local std::string env_var goes out of scope at the end of each iteration, leaving putenv with a dangling pointer to freed memory. By the time execvp runs (after the loop), the environment is corrupted, and the child sees no environment variables. (It should be setenv(key, value, 1), which copies.)