mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-10 14:30:45 +08:00
feat(mcp): pass all mcp_local.env keys to subprocess; allowlist supplements host-only
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
48d5e468e6
commit
274a9b8ddd
7 changed files with 44 additions and 15 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
"""MCP 相关进程环境:默认 allowlist + 可选本地 env 文件(首选 `oclaw/_local/mcp_local.env`)。"""
|
||||
"""MCP 相关进程环境:``mcp_local.env`` 中的键视为 MCP 专用并传入子进程;allowlist 仅补充宿主环境里未写入该文件的变量名。"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
|
@ -29,12 +29,14 @@ def _dedupe_preserve_order(keys: list[str]) -> list[str]:
|
|||
|
||||
|
||||
def mcp_env_allowlist_keys() -> list[str]:
|
||||
"""MCP 子进程可继承的环境变量名:主列表 + EXTRA 合并去重。
|
||||
"""宿主环境 → MCP 子进程的补充白名单(与 ``mcp_local.env`` 中的键取并集)。
|
||||
|
||||
- 未设置 ``AIA_MCP_ENV_ALLOWLIST``:主列表为内置默认(含常用 MCP 密钥名)。
|
||||
- 已设置:主列表仅为该项(完全替换默认),用于刻意缩小暴露面。
|
||||
- ``AIA_MCP_ENV_ALLOWLIST_EXTRA``(或兼容 ``OPS_MCP_ENV_ALLOWLIST_EXTRA``):
|
||||
始终在主列表之后追加,避免为新增 MCP 手抄整份默认名单。
|
||||
``mcp_local.env``(含 ``data/mcp_local.env`` 等合并路径)里**出现且非空**的变量名会始终尝试传入
|
||||
MCP 子进程(见 ``McpProcessRuntime._build_runtime_env``),无需出现在本列表中。
|
||||
|
||||
- 未设置 ``AIA_MCP_ENV_ALLOWLIST``:本列表为内置默认(常用仅写在 Docker/系统 env 的密钥名)。
|
||||
- 已设置:本列表仅为该项(完全替换内置默认),用于补充「未写入 mcp_local 文件」的透传名。
|
||||
- ``AIA_MCP_ENV_ALLOWLIST_EXTRA``(或 ``OPS_MCP_ENV_ALLOWLIST_EXTRA``):始终追加到本列表之后,合并去重。
|
||||
"""
|
||||
primary_raw = str(os.getenv("AIA_MCP_ENV_ALLOWLIST") or "").strip()
|
||||
primary = _split_csv_keys(primary_raw) if primary_raw else _split_csv_keys(_DEFAULT_ALLOWLIST)
|
||||
|
|
|
|||
|
|
@ -25,14 +25,26 @@ class McpProcessRuntime:
|
|||
def _build_runtime_env(env_allowlist: list[str] | None) -> dict[str, str] | None:
|
||||
if env_allowlist is None:
|
||||
return None
|
||||
from oclaw.runtime.operations.mcp_env import mcp_local_env_merged
|
||||
|
||||
keep_keys = {"PATH", "PATHEXT", "SYSTEMROOT", "WINDIR", "COMSPEC", "TEMP", "TMP", "HOME", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "PROGRAMDATA", "PROGRAMFILES", "PROGRAMFILES(X86)", "SYSTEMDRIVE"}
|
||||
env: dict[str, str] = {}
|
||||
for k in keep_keys:
|
||||
if k in os.environ:
|
||||
env[k] = os.environ[k]
|
||||
# Keys declared in mcp_local.env (any merged path): treat as MCP-scoped; always pass
|
||||
# through when non-empty (values come from os.environ after gateway merge, else file literal).
|
||||
for k, v in mcp_local_env_merged().items():
|
||||
if not str(v or "").strip():
|
||||
continue
|
||||
live = str(os.environ.get(k, "") or "").strip()
|
||||
if live:
|
||||
env[k] = os.environ[k]
|
||||
else:
|
||||
env[k] = str(v).strip()
|
||||
for k in env_allowlist:
|
||||
key = str(k or "").strip()
|
||||
if key and key in os.environ:
|
||||
if key and key in os.environ and str(os.environ[key] or "").strip():
|
||||
env[key] = os.environ[key]
|
||||
return env
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue