mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-15 12:58:04 +00:00
fix: preserve pythonpath for built-in mcp servers (#5117)
This commit is contained in:
+16
-1
@@ -104,6 +104,21 @@ def _spawn_bg(coro) -> asyncio.Task:
|
|||||||
return task
|
return task
|
||||||
|
|
||||||
|
|
||||||
|
def builtin_python_env(base_dir: str) -> dict[str, str]:
|
||||||
|
"""Environment for built-in Python MCP subprocesses.
|
||||||
|
|
||||||
|
The app root must be importable so mcp_servers can import local modules, but
|
||||||
|
replacing PYTHONPATH entirely hides site-packages in container/dev launches
|
||||||
|
that rely on PYTHONPATH for their active environment.
|
||||||
|
"""
|
||||||
|
existing = os.environ.get("PYTHONPATH", "")
|
||||||
|
parts = [base_dir]
|
||||||
|
for item in existing.split(os.pathsep):
|
||||||
|
if item and item not in parts:
|
||||||
|
parts.append(item)
|
||||||
|
return {"PYTHONPATH": os.pathsep.join(parts)}
|
||||||
|
|
||||||
|
|
||||||
async def register_builtin_servers(mcp_manager):
|
async def register_builtin_servers(mcp_manager):
|
||||||
"""Connect all built-in MCP servers to the manager."""
|
"""Connect all built-in MCP servers to the manager."""
|
||||||
if MCP_DISABLED:
|
if MCP_DISABLED:
|
||||||
@@ -121,7 +136,7 @@ async def register_builtin_servers(mcp_manager):
|
|||||||
transport="stdio",
|
transport="stdio",
|
||||||
command=python,
|
command=python,
|
||||||
args=[script_path],
|
args=[script_path],
|
||||||
env={"PYTHONPATH": base_dir},
|
env=builtin_python_env(base_dir),
|
||||||
)
|
)
|
||||||
if ok:
|
if ok:
|
||||||
logger.info(f"Built-in MCP server registered: {name}")
|
logger.info(f"Built-in MCP server registered: {name}")
|
||||||
|
|||||||
+2
-2
@@ -504,7 +504,7 @@ class McpManager:
|
|||||||
async def _reconnect_builtin(self, server_id: str) -> bool:
|
async def _reconnect_builtin(self, server_id: str) -> bool:
|
||||||
"""Tear down and reconnect a crashed builtin MCP server."""
|
"""Tear down and reconnect a crashed builtin MCP server."""
|
||||||
import sys
|
import sys
|
||||||
from src.builtin_mcp import _BUILTIN_SERVERS
|
from src.builtin_mcp import _BUILTIN_SERVERS, builtin_python_env
|
||||||
|
|
||||||
if server_id not in _BUILTIN_SERVERS:
|
if server_id not in _BUILTIN_SERVERS:
|
||||||
return False
|
return False
|
||||||
@@ -523,7 +523,7 @@ class McpManager:
|
|||||||
transport="stdio",
|
transport="stdio",
|
||||||
command=sys.executable,
|
command=sys.executable,
|
||||||
args=[script_path],
|
args=[script_path],
|
||||||
env={"PYTHONPATH": base_dir},
|
env=builtin_python_env(base_dir),
|
||||||
)
|
)
|
||||||
if ok:
|
if ok:
|
||||||
logger.info(f"Reconnected builtin MCP server: {name}")
|
logger.info(f"Reconnected builtin MCP server: {name}")
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from src.builtin_mcp import builtin_python_env
|
||||||
|
|
||||||
|
|
||||||
|
def test_builtin_python_env_preserves_existing_pythonpath(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
"PYTHONPATH",
|
||||||
|
os.pathsep.join(["/app/venv/lib/python3.13/site-packages", "/app", "/extra"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
env = builtin_python_env("/app")
|
||||||
|
|
||||||
|
assert env == {
|
||||||
|
"PYTHONPATH": os.pathsep.join(["/app", "/app/venv/lib/python3.13/site-packages", "/extra"])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_builtin_python_env_uses_app_root_without_existing_pythonpath(monkeypatch):
|
||||||
|
monkeypatch.delenv("PYTHONPATH", raising=False)
|
||||||
|
|
||||||
|
assert builtin_python_env("/srv/odysseus") == {"PYTHONPATH": "/srv/odysseus"}
|
||||||
Reference in New Issue
Block a user