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
5 changes: 5 additions & 0 deletions .changeset/fix-default-inherited-env-vars-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': patch
---

Add missing Windows environment variables to `DEFAULT_INHERITED_ENV_VARS`: `PATHEXT`, `COMSPEC`, `PROGRAMFILES(X86)`, `PROGRAMW6432`, and `WINDIR`. Without `PATHEXT`, spawning common tools like `npm` or `git` from a stdio MCP server fails with `ENOENT` on Windows because Node can't resolve the `.cmd`/`.exe` extension.
7 changes: 6 additions & 1 deletion packages/client/src/client/stdio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,22 @@ export const DEFAULT_INHERITED_ENV_VARS =
process.platform === 'win32'
? [
'APPDATA',
'COMSPEC',
'HOMEDRIVE',
'HOMEPATH',
'LOCALAPPDATA',
'PATH',
'PATHEXT',
'PROCESSOR_ARCHITECTURE',
'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
32 changes: 31 additions & 1 deletion packages/client/test/client/stdio.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { JSONRPCMessage } from '@modelcontextprotocol/core';

import type { StdioServerParameters } from '../../src/client/stdio.js';
import { StdioClientTransport } from '../../src/client/stdio.js';
import { DEFAULT_INHERITED_ENV_VARS, StdioClientTransport } from '../../src/client/stdio.js';

// Configure default server parameters based on OS
// Uses 'more' command for Windows and 'tee' command for Unix/Linux
Expand Down Expand Up @@ -77,3 +77,33 @@ test('should return child process pid', async () => {
await client.close();
expect(client.pid).toBeNull();
});

test('DEFAULT_INHERITED_ENV_VARS matches the host platform', () => {
if (process.platform === 'win32') {
// Variables Windows tooling needs to resolve executables and shells.
// Missing PATHEXT or COMSPEC causes spawn ENOENT for npm/git/etc.
expect(DEFAULT_INHERITED_ENV_VARS).toEqual(
expect.arrayContaining([
'APPDATA',
'COMSPEC',
'HOMEDRIVE',
'HOMEPATH',
'LOCALAPPDATA',
'PATH',
'PATHEXT',
'PROCESSOR_ARCHITECTURE',
'PROGRAMFILES',
'PROGRAMFILES(X86)',
'PROGRAMW6432',
'SYSTEMDRIVE',
'SYSTEMROOT',
'TEMP',
'USERNAME',
'USERPROFILE',
'WINDIR'
])
);
} else {
expect(DEFAULT_INHERITED_ENV_VARS).toEqual(['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER']);
}
});
Loading