fix(mcp): context-aware project_root detection (cwd + script_root fallback)
The MCP server's project_root was hardcoded to the script's parent dir. When opencode launches the MCP from a sibling clone (e.g., main repo launches the tier2 clone's MCP via the hardcoded path in main repo's opencode.json), the MCP only allowed paths inside the tier2 clone — even when the user was working in the main repo. Fix: use os.getcwd() as the primary project_root (the user's actual working dir) and fall back to the script's home. Read mcp_paths.toml from cwd first, then script home. This way: - MCP launched from tier2 + cwd=main -> allows [main, tier2] - MCP launched from main + cwd=main -> allows [main] - MCP launched from tier2 + cwd=tier2 -> allows [tier2] (preserves sandbox) Takes effect after the next opencode restart.
This commit is contained in:
+26
-9
@@ -79,16 +79,33 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
||||
return [TextContent(type="text", text=f"ERROR: {e}")]
|
||||
|
||||
async def main() -> None:
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
# Robust context detection: project_root is os.getcwd() (the directory
|
||||
# the user is actually working in), not just where the script lives.
|
||||
# The script's own home is a secondary fallback. This handles the case
|
||||
# where opencode launches the MCP from a sibling clone (e.g., main repo
|
||||
# launches the tier2 clone's MCP via a hardcoded path in opencode.json)
|
||||
# — the MCP should allow access to the user's working directory too.
|
||||
cwd = os.getcwd()
|
||||
script_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
extra_dirs = [project_root]
|
||||
mcp_paths_toml = os.path.join(project_root, "mcp_paths.toml")
|
||||
if os.path.exists(mcp_paths_toml):
|
||||
import tomllib
|
||||
with open(mcp_paths_toml, "rb") as f:
|
||||
config = tomllib.load(f)
|
||||
allowed = config.get("allowed_paths", {}).get("extra_dirs", [])
|
||||
extra_dirs.extend(allowed)
|
||||
extra_dirs: list[str] = []
|
||||
for d in (cwd, script_root):
|
||||
if d and d not in extra_dirs:
|
||||
extra_dirs.append(d)
|
||||
|
||||
# Read mcp_paths.toml from cwd first (the user's working dir takes
|
||||
# precedence), then fall back to the script's home dir.
|
||||
for mcp_paths_toml in (os.path.join(cwd, "mcp_paths.toml"),
|
||||
os.path.join(script_root, "mcp_paths.toml")):
|
||||
if os.path.exists(mcp_paths_toml):
|
||||
import tomllib
|
||||
with open(mcp_paths_toml, "rb") as f:
|
||||
config = tomllib.load(f)
|
||||
allowed = config.get("allowed_paths", {}).get("extra_dirs", [])
|
||||
for p in allowed:
|
||||
if p not in extra_dirs:
|
||||
extra_dirs.append(p)
|
||||
break
|
||||
|
||||
mcp_client.configure([], extra_base_dirs=extra_dirs)
|
||||
async with stdio_server() as (read_stream, write_stream):
|
||||
|
||||
Reference in New Issue
Block a user