|
1 | 1 | import { JSONRPCMessage } from "../types.js"; |
2 | | -import { StdioClientTransport, StdioServerParameters } from "./stdio.js"; |
| 2 | +import { StdioClientTransport, StdioServerParameters, DEFAULT_INHERITED_ENV_VARS, getDefaultEnvironment } from "./stdio.js"; |
3 | 3 |
|
4 | 4 | const serverParameters: StdioServerParameters = { |
5 | 5 | command: "/usr/bin/tee", |
6 | 6 | }; |
7 | 7 |
|
| 8 | + |
| 9 | +let spawnEnv: Record<string, string> | undefined; |
| 10 | + |
| 11 | +jest.mock('cross-spawn', () => { |
| 12 | + const originalSpawn = jest.requireActual('cross-spawn'); |
| 13 | + return jest.fn((command, args, options) => { |
| 14 | + spawnEnv = options.env; |
| 15 | + return originalSpawn(command, args, options); |
| 16 | + }); |
| 17 | +}); |
| 18 | + |
8 | 19 | test("should start then close cleanly", async () => { |
9 | 20 | const client = new StdioClientTransport(serverParameters); |
10 | 21 | client.onerror = (error) => { |
@@ -60,32 +71,51 @@ test("should read messages", async () => { |
60 | 71 | await client.close(); |
61 | 72 | }); |
62 | 73 |
|
63 | | -test("should work with actual node mcp server", async () => { |
64 | | - const client = new StdioClientTransport({ |
65 | | - command: "npx", |
66 | | - args: ["-y", "@wrtnlabs/calculator-mcp"], |
67 | | - }); |
68 | | - |
69 | | - await client.start(); |
70 | | - await client.close(); |
71 | | -}); |
| 74 | +test("should properly set default environment variables in spawned process", async () => { |
| 75 | + const client = new StdioClientTransport(serverParameters); |
72 | 76 |
|
73 | | -test("should work with actual node mcp server and empty env", async () => { |
74 | | - const client = new StdioClientTransport({ |
75 | | - command: "npx", |
76 | | - args: ["-y", "@wrtnlabs/calculator-mcp"], |
77 | | - env: {}, |
78 | | - }); |
79 | 77 | await client.start(); |
80 | 78 | await client.close(); |
| 79 | + |
| 80 | + // Get the default environment variables |
| 81 | + const defaultEnv = getDefaultEnvironment(); |
| 82 | + |
| 83 | + // Verify that all default environment variables are present |
| 84 | + for (const key of DEFAULT_INHERITED_ENV_VARS) { |
| 85 | + if (process.env[key] && !process.env[key].startsWith("()")) { |
| 86 | + expect(spawnEnv).toHaveProperty(key); |
| 87 | + expect(spawnEnv![key]).toBe(process.env[key]); |
| 88 | + expect(spawnEnv![key]).toBe(defaultEnv[key]); |
| 89 | + } |
| 90 | + } |
81 | 91 | }); |
82 | 92 |
|
83 | | -test("should work with actual node mcp server and custom env", async () => { |
| 93 | +test("should override default environment variables with custom ones", async () => { |
| 94 | + const customEnv = { |
| 95 | + HOME: "/custom/home", |
| 96 | + PATH: "/custom/path", |
| 97 | + USER: "custom_user" |
| 98 | + }; |
| 99 | + |
84 | 100 | const client = new StdioClientTransport({ |
85 | | - command: "npx", |
86 | | - args: ["-y", "@wrtnlabs/calculator-mcp"], |
87 | | - env: {TEST_VAR: "test-value"}, |
| 101 | + ...serverParameters, |
| 102 | + env: customEnv |
88 | 103 | }); |
| 104 | + |
89 | 105 | await client.start(); |
90 | 106 | await client.close(); |
| 107 | + |
| 108 | + // Verify that custom environment variables override default ones |
| 109 | + for (const [key, value] of Object.entries(customEnv)) { |
| 110 | + expect(spawnEnv).toHaveProperty(key); |
| 111 | + expect(spawnEnv![key]).toBe(value); |
| 112 | + } |
| 113 | + |
| 114 | + // Verify that other default environment variables are still present |
| 115 | + for (const key of DEFAULT_INHERITED_ENV_VARS) { |
| 116 | + if (!(key in customEnv) && process.env[key] && !process.env[key].startsWith("()")) { |
| 117 | + expect(spawnEnv).toHaveProperty(key); |
| 118 | + expect(spawnEnv![key]).toBe(process.env[key]); |
| 119 | + } |
| 120 | + } |
91 | 121 | }); |
0 commit comments