diff --git a/autogpt_platform/backend/backend/copilot/permissions.py b/autogpt_platform/backend/backend/copilot/permissions.py index b201840cc9..2f149812c4 100644 --- a/autogpt_platform/backend/backend/copilot/permissions.py +++ b/autogpt_platform/backend/backend/copilot/permissions.py @@ -422,7 +422,7 @@ def apply_tool_permissions( permitted_sdk: set[str] = set() for s in effective: permitted_sdk.update(to_sdk_names(s)) - # Always include the internal Read tool (used by SDK for large/truncated outputs) + # Always include the internal read_tool_result tool (used by SDK for large/truncated outputs) permitted_sdk.add(f"{MCP_TOOL_PREFIX}{_READ_TOOL_NAME}") filtered_allowed = [t for t in base_allowed if t in permitted_sdk] diff --git a/autogpt_platform/backend/backend/copilot/permissions_test.py b/autogpt_platform/backend/backend/copilot/permissions_test.py index 2aaec60843..4410e8886d 100644 --- a/autogpt_platform/backend/backend/copilot/permissions_test.py +++ b/autogpt_platform/backend/backend/copilot/permissions_test.py @@ -408,12 +408,12 @@ class TestApplyToolPermissions: assert "Task" not in allowed def test_read_tool_always_included_even_when_blacklisted(self, mocker): - """mcp__copilot__Read must stay in allowed even if Read is explicitly blacklisted.""" + """mcp__copilot__read_tool_result must stay in allowed even if Read is explicitly blacklisted.""" mocker.patch( "backend.copilot.sdk.tool_adapter.get_copilot_tool_names", return_value=[ "mcp__copilot__run_block", - "mcp__copilot__Read", + "mcp__copilot__read_tool_result", "Task", ], ) @@ -432,17 +432,17 @@ class TestApplyToolPermissions: # Explicitly blacklist Read perms = CopilotPermissions(tools=["Read"], tools_exclude=True) allowed, _ = apply_tool_permissions(perms, use_e2b=False) - assert "mcp__copilot__Read" in allowed # always preserved for SDK internals + assert "mcp__copilot__read_tool_result" in allowed # always preserved for SDK internals assert "mcp__copilot__run_block" in allowed assert "Task" in allowed def test_read_tool_always_included_with_narrow_whitelist(self, mocker): - """mcp__copilot__Read must stay in allowed even when not in a whitelist.""" + """mcp__copilot__read_tool_result must stay in allowed even when not in a whitelist.""" mocker.patch( "backend.copilot.sdk.tool_adapter.get_copilot_tool_names", return_value=[ "mcp__copilot__run_block", - "mcp__copilot__Read", + "mcp__copilot__read_tool_result", "Task", ], ) @@ -461,7 +461,7 @@ class TestApplyToolPermissions: # Whitelist only run_block — Read not listed perms = CopilotPermissions(tools=["run_block"], tools_exclude=False) allowed, _ = apply_tool_permissions(perms, use_e2b=False) - assert "mcp__copilot__Read" in allowed # always preserved for SDK internals + assert "mcp__copilot__read_tool_result" in allowed # always preserved for SDK internals assert "mcp__copilot__run_block" in allowed def test_e2b_file_tools_included_when_sdk_builtin_whitelisted(self, mocker): @@ -470,7 +470,7 @@ class TestApplyToolPermissions: "backend.copilot.sdk.tool_adapter.get_copilot_tool_names", return_value=[ "mcp__copilot__run_block", - "mcp__copilot__Read", + "mcp__copilot__read_tool_result", "mcp__copilot__read_file", "mcp__copilot__write_file", "Task", @@ -506,7 +506,7 @@ class TestApplyToolPermissions: "backend.copilot.sdk.tool_adapter.get_copilot_tool_names", return_value=[ "mcp__copilot__run_block", - "mcp__copilot__Read", + "mcp__copilot__read_tool_result", "mcp__copilot__read_file", "Task", ], @@ -532,8 +532,8 @@ class TestApplyToolPermissions: allowed, _ = apply_tool_permissions(perms, use_e2b=True) assert "mcp__copilot__read_file" not in allowed assert "mcp__copilot__run_block" in allowed - # mcp__copilot__Read is always preserved for SDK internals - assert "mcp__copilot__Read" in allowed + # mcp__copilot__read_tool_result is always preserved for SDK internals + assert "mcp__copilot__read_tool_result" in allowed # --------------------------------------------------------------------------- diff --git a/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py b/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py index 1d9dc083d7..c3eb10bd13 100644 --- a/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py +++ b/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py @@ -428,7 +428,7 @@ async def _read_file_handler(args: dict[str, Any]) -> dict[str, Any]: return _mcp_ok(numbered) if not is_allowed_local_path(file_path, get_sdk_cwd()): - return _mcp_err(f"Path not allowed: {file_path}") + return _mcp_err(f"Path not allowed: {os.path.basename(file_path)}") resolved = os.path.realpath(os.path.expanduser(file_path)) try: @@ -452,9 +452,12 @@ async def _read_file_handler(args: dict[str, Any]) -> dict[str, Any]: return _mcp_err(f"Error reading file: {e}") -_READ_TOOL_NAME = "Read" +_READ_TOOL_NAME = "read_tool_result" _READ_TOOL_DESCRIPTION = ( - "Read a file from the local filesystem. " + "Read an SDK-internal tool-result file or a workspace:// URI. " + "Use this tool only for paths under ~/.claude/projects/.../tool-results/ " + "or tool-outputs/, and for workspace:// URIs returned by other tools. " + "For files in the working directory use read_file instead. " "Use offset and limit to read specific line ranges for large files." ) _READ_TOOL_SCHEMA = {