Skip to content

Commit 67a3293

Browse files
author
huangzhimou
committed
fix(tools): restrict get-env to accept key parameter only
Security fix: get-env tool was returning full process.env to any caller. Now requires a 'key' parameter and returns only process.env[key]. Closes #3986
1 parent 4503e2d commit 67a3293

3 files changed

Lines changed: 37 additions & 19 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@modelcontextprotocol/server-everything": patch
3+
---
4+
5+
Fix security issue in get-env tool: require a specific key parameter instead of returning the entire process.env object unfiltered. The tool now accepts a required `key` argument and returns only the value of that specific environment variable, preventing accidental exposure of sensitive data such as API keys, tokens, and credentials.

src/everything/__tests__/tools.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,31 +151,33 @@ describe('Tools', () => {
151151
});
152152

153153
describe('get-env', () => {
154-
it('should return all environment variables as JSON', async () => {
154+
it('should return the value of a specific environment variable', async () => {
155155
const { mockServer, handlers } = createMockServer();
156156
registerGetEnvTool(mockServer);
157157

158158
const handler = handlers.get('get-env')!;
159159
process.env.TEST_VAR_EVERYTHING = 'test_value';
160-
const result = await handler({});
160+
const result = await handler({ key: 'TEST_VAR_EVERYTHING' });
161161

162162
expect(result.content).toHaveLength(1);
163163
expect(result.content[0].type).toBe('text');
164-
165-
const envJson = JSON.parse(result.content[0].text);
166-
expect(envJson.TEST_VAR_EVERYTHING).toBe('test_value');
164+
expect(result.content[0].text).toBe('test_value');
167165

168166
delete process.env.TEST_VAR_EVERYTHING;
169167
});
170168

171-
it('should return valid JSON', async () => {
169+
it('should return a message when the key does not exist', async () => {
172170
const { mockServer, handlers } = createMockServer();
173171
registerGetEnvTool(mockServer);
174172

175173
const handler = handlers.get('get-env')!;
176-
const result = await handler({});
174+
const result = await handler({ key: 'NONEXISTENT_VAR_12345' });
177175

178-
expect(() => JSON.parse(result.content[0].text)).not.toThrow();
176+
expect(result.content).toHaveLength(1);
177+
expect(result.content[0].type).toBe('text');
178+
expect(result.content[0].text).toBe(
179+
'Environment variable "NONEXISTENT_VAR_12345" is not set.'
180+
);
179181
});
180182
});
181183

src/everything/tools/get-env.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,44 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3+
import { z } from "zod";
4+
5+
// Tool input schema
6+
const GetEnvSchema = z.object({
7+
key: z.string().describe("Specific environment variable name"),
8+
});
39

410
// Tool configuration
511
const name = "get-env";
612
const config = {
7-
title: "Print Environment Tool",
13+
title: "Get Environment Variable",
814
description:
9-
"Returns all environment variables, helpful for debugging MCP server configuration",
10-
inputSchema: {},
15+
'Returns the value of a specific environment variable. Pass the variable name via the "key" argument.',
16+
inputSchema: GetEnvSchema,
1117
};
1218

1319
/**
1420
* Registers the 'get-env' tool.
1521
*
16-
* The registered tool Retrieves and returns the environment variables
17-
* of the current process as a JSON-formatted string encapsulated in a text response.
22+
* The registered tool retrieves and returns the value of a specific
23+
* environment variable specified by the 'key' argument.
1824
*
1925
* @param {McpServer} server - The McpServer instance where the tool will be registered.
2026
* @returns {void}
2127
*/
2228
export const registerGetEnvTool = (server: McpServer) => {
2329
server.registerTool(name, config, async (args): Promise<CallToolResult> => {
30+
const { key } = GetEnvSchema.parse(args);
31+
const value = process.env[key];
32+
33+
// Return a clear message if the key doesn't exist rather than exposing the full env
34+
if (value === undefined) {
35+
return {
36+
content: [{ type: "text", text: `Environment variable "${key}" is not set.` }],
37+
};
38+
}
39+
2440
return {
25-
content: [
26-
{
27-
type: "text",
28-
text: JSON.stringify(process.env, null, 2),
29-
},
30-
],
41+
content: [{ type: "text", text: value }],
3142
};
3243
});
3344
};

0 commit comments

Comments
 (0)