-
Notifications
You must be signed in to change notification settings - Fork 696
Add InheritEnvironmentVariables to StdioClientTransportOptions
#1563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
36ee0da
d3dd518
57fe209
9ce7245
94a2dff
b930b3e
d6505bb
0ea6451
4614095
3191335
f696235
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,11 +39,63 @@ Key <xref:ModelContextProtocol.Client.StdioClientTransportOptions> properties: | |
| | `Command` | The executable to launch (required) | | ||
| | `Arguments` | Command-line arguments for the process | | ||
| | `WorkingDirectory` | Working directory for the server process | | ||
| | `EnvironmentVariables` | Environment variables (merged with current; `null` values remove variables) | | ||
| | `EnvironmentVariables` | Environment variables (merged with current when inheriting; `null` values remove variables) | | ||
| | `InheritEnvironmentVariables` | Whether the server process inherits the current process's environment variables (default: `true`) | | ||
| | `ShutdownTimeout` | Graceful shutdown timeout (default: 5 seconds) | | ||
| | `StandardErrorLines` | Callback for stderr output from the server process | | ||
| | `Name` | Optional transport identifier for logging | | ||
|
|
||
| #### Environment variable inheritance | ||
|
|
||
| By default, the server process inherits **all** environment variables from the current process. This includes credentials, tokens, proxy settings, and internal configuration that may be sensitive or irrelevant to the server. When running third-party or untrusted MCP servers, consider disabling inheritance to prevent unintentional credential leakage: | ||
|
|
||
| ```csharp | ||
| var transport = new StdioClientTransport(new StdioClientTransportOptions | ||
| { | ||
| Command = "my-mcp-server", | ||
| InheritEnvironmentVariables = false, | ||
| EnvironmentVariables = StdioClientTransportOptions.GetDefaultEnvironmentVariables(), | ||
| }); | ||
| ``` | ||
|
|
||
| `GetDefaultEnvironmentVariables()` returns a curated set of environment variables (such as `PATH`, `HOME`, and standard system directories) that most child processes need to start correctly, without leaking credentials or other sensitive values from the parent process. The allowlist is aligned with the defaults used by the TypeScript and Python MCP SDKs. On Windows it also includes `PATHEXT`, which is required for the OS to recognize `.cmd` and `.bat` files as executable. You can add server-specific variables on top: | ||
|
|
||
| ```csharp | ||
| var env = StdioClientTransportOptions.GetDefaultEnvironmentVariables(); | ||
| env["MY_SERVER_API_KEY"] = apiKey; | ||
|
|
||
| var transport = new StdioClientTransport(new StdioClientTransportOptions | ||
| { | ||
| Command = "my-mcp-server", | ||
| InheritEnvironmentVariables = false, | ||
| EnvironmentVariables = env, | ||
| }); | ||
| ``` | ||
|
|
||
| If you need to selectively forward a specific set of variables from the parent environment rather than using the curated allowlist, build the dictionary manually: | ||
|
|
||
| ```csharp | ||
| var env = new Dictionary<string, string?>(); | ||
| foreach (var name in new[] { "PATH", "HOME", "HTTP_PROXY", "HTTPS_PROXY" }) | ||
| { | ||
| var value = Environment.GetEnvironmentVariable(name); | ||
| if (value is not null) | ||
| env[name] = value; | ||
| } | ||
|
|
||
| var transport = new StdioClientTransport(new StdioClientTransportOptions | ||
| { | ||
| Command = "my-mcp-server", | ||
| InheritEnvironmentVariables = false, | ||
| EnvironmentVariables = env, | ||
| }); | ||
| ``` | ||
|
|
||
| > [!WARNING] | ||
| > **Security risk (inheriting):** Variables such as `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, `OPENAI_API_KEY`, and similar credentials present in the parent process automatically flow into the child process unless inheritance is disabled. This can unintentionally expose sensitive values to third-party or untrusted MCP servers. | ||
| > | ||
| > **Compatibility risk (not inheriting):** Disabling inheritance can cause the child process to fail to start or behave incorrectly if it relies on variables provided by the OS or shell. `GetDefaultEnvironmentVariables()` covers the most common requirements — `PATH`, `HOME`, and standard system directories — so for most servers it is a safe starting point. For servers that need additional variables not in the default set (such as `DOTNET_ROOT`, `LD_LIBRARY_PATH`, `JAVA_HOME`, or proxy settings like `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`), add them on top as shown in the example above. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we want to roll out a breaking change around this in a future major version. I could imagine an analyzer that tells folks to set this to false. Let that percolate a couple releases, then change the default and update the analyzer to only flag when folks set it to true.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That might make sense. We are thinking about doing something similar for changing the stateless defaults. See #1471. I need to update that, so I could include something for this there as well. |
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Might be worth while showing the pattern to selectively inherit. Maybe for a set of variables by name, copy those to |
||
| #### stdio server | ||
|
|
||
| Use <xref:ModelContextProtocol.Server.StdioServerTransport> for servers that communicate over stdin/stdout: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to mention anything regarding Windows shell wrapping?