Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/fix-default-inherited-env-vars-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@modelcontextprotocol/sdk': patch
---

On Windows, stdio servers spawned by `StdioClientTransport` now also inherit `COMSPEC`, `PATHEXT`, `PROGRAMDATA`, `PROGRAMFILES(X86)`, `PROGRAMW6432`, and `WINDIR` (added to `DEFAULT_INHERITED_ENV_VARS`). Programs a server launches can depend on them: PowerShell finds no native
executables without `PATHEXT`, and Windows OpenSSH exits 255 without `ProgramData`.

This is a backport of the same fix already merged on `main` in #2043, and resolves #2037 for the v1 line.
8 changes: 7 additions & 1 deletion src/client/stdio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,23 @@ export const DEFAULT_INHERITED_ENV_VARS =
process.platform === 'win32'
? [
'APPDATA',
'COMSPEC',
'HOMEDRIVE',
'HOMEPATH',
'LOCALAPPDATA',
'PATH',
'PATHEXT',
'PROCESSOR_ARCHITECTURE',
'PROGRAMDATA',
'PROGRAMFILES',
'PROGRAMFILES(X86)',
'PROGRAMW6432',
'SYSTEMDRIVE',
'SYSTEMROOT',
'TEMP',
'USERNAME',
'USERPROFILE',
'PROGRAMFILES'
'WINDIR'
]
: /* list inspired by the default env inheritance of sudo */
['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER'];
Expand Down
33 changes: 33 additions & 0 deletions test/client/stdio.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,36 @@ test('should fire onerror and close when ReadBuffer overflows', async () => {
expect(error.message).toMatch(/ReadBuffer exceeded maximum size/);
await closed;
});

test('should inherit the Windows variables that child tools need by default', async () => {
const originalPlatform = process.platform;
// DEFAULT_INHERITED_ENV_VARS is computed at import time, so load a fresh copy of the module as if on Windows.
Object.defineProperty(process, 'platform', { value: 'win32' });
try {
vi.resetModules();
const { DEFAULT_INHERITED_ENV_VARS } = await import('../../src/client/stdio.js');
expect(DEFAULT_INHERITED_ENV_VARS).toEqual([
'APPDATA',
'COMSPEC',
'HOMEDRIVE',
'HOMEPATH',
'LOCALAPPDATA',
'PATH',
'PATHEXT',
'PROCESSOR_ARCHITECTURE',
'PROGRAMDATA',
'PROGRAMFILES',
'PROGRAMFILES(X86)',
'PROGRAMW6432',
'SYSTEMDRIVE',
'SYSTEMROOT',
'TEMP',
'USERNAME',
'USERPROFILE',
'WINDIR'
]);
} finally {
Object.defineProperty(process, 'platform', { value: originalPlatform });
vi.resetModules();
}
});
Loading