|
11 | 11 | import tempfile |
12 | 12 | import subprocess |
13 | 13 | import ast |
| 14 | +import sys |
| 15 | + |
| 16 | +# Environment variables to inherit by default |
| 17 | +DEFAULT_INHERITED_ENV_VARS = ( |
| 18 | + [ |
| 19 | + "APPDATA", |
| 20 | + "HOMEDRIVE", |
| 21 | + "HOMEPATH", |
| 22 | + "LOCALAPPDATA", |
| 23 | + "PATH", |
| 24 | + "PROCESSOR_ARCHITECTURE", |
| 25 | + "SYSTEMDRIVE", |
| 26 | + "SYSTEMROOT", |
| 27 | + "TEMP", |
| 28 | + "USERNAME", |
| 29 | + "USERPROFILE", |
| 30 | + ] |
| 31 | + if sys.platform == "win32" |
| 32 | + else ["HOME", "LOGNAME", "PATH", "SHELL", "TERM", "USER"] |
| 33 | +) |
| 34 | + |
| 35 | + |
| 36 | +def get_default_environment() -> dict[str, str]: |
| 37 | + """ |
| 38 | + Returns a default environment object including only environment variables deemed |
| 39 | + safe to inherit. |
| 40 | + """ |
| 41 | + env: dict[str, str] = {} |
| 42 | + |
| 43 | + for key in DEFAULT_INHERITED_ENV_VARS: |
| 44 | + value = os.environ.get(key) |
| 45 | + if value is None: |
| 46 | + continue |
| 47 | + |
| 48 | + if value.startswith("()"): |
| 49 | + # Skip functions, which are a security risk |
| 50 | + continue |
| 51 | + |
| 52 | + env[key] = value |
| 53 | + |
| 54 | + return env |
14 | 55 |
|
15 | 56 |
|
16 | 57 | def sanitize_name(name: str) -> str: |
@@ -42,8 +83,13 @@ async def get_mcp_servers() -> list[StdioServerParameters]: |
42 | 83 | # Convert empty lists and dicts to None |
43 | 84 | if "args" in params and not params["args"]: |
44 | 85 | params["args"] = None |
45 | | - if "env" in params and not params["env"]: |
46 | | - params["env"] = None |
| 86 | + |
| 87 | + # Merge environment variables |
| 88 | + params["env"] = { |
| 89 | + **get_default_environment(), |
| 90 | + **(params.get("env") or {}), |
| 91 | + } |
| 92 | + |
47 | 93 | server_params.append(StdioServerParameters(**params)) |
48 | 94 | return server_params |
49 | 95 | except Exception: |
@@ -118,8 +164,11 @@ async def get_custom_mcp_servers() -> list[StdioServerParameters]: |
118 | 164 | params["command"] = "uv" |
119 | 165 | params["args"] = ["run", script_path] + params.get("additionalArgs", []) |
120 | 166 |
|
121 | | - if "env" in params and not params["env"]: |
122 | | - params["env"] = None |
| 167 | + # Merge environment variables |
| 168 | + params["env"] = { |
| 169 | + **get_default_environment(), |
| 170 | + **(params.get("env") or {}), |
| 171 | + } |
123 | 172 |
|
124 | 173 | server_params.append(StdioServerParameters(**params)) |
125 | 174 | return server_params |
@@ -212,7 +261,7 @@ async def serve(): |
212 | 261 | write_stream, |
213 | 262 | InitializationOptions( |
214 | 263 | server_name="metatool", |
215 | | - server_version="0.0.1", |
| 264 | + server_version="0.0.4", |
216 | 265 | capabilities=server.get_capabilities( |
217 | 266 | notification_options=NotificationOptions(), |
218 | 267 | experimental_capabilities={}, |
|
0 commit comments