|
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