Skip to content

Rust external session + MCP tools fail with 'Unhandled permission result kind: [object Object]' #1440

@cay7man

Description

@cay7man

Summary

Using the Rust SDK against an external headless Copilot CLI, MCP tools can connect and be invoked, but the runtime fails during the permission flow with:

Unhandled permission result kind: [object Object]

I can reproduce this with a read-only MCP server tool (readOnlyHint: true) over an external/TCP session.

Environment

  • SDK: github-copilot-sdk = "0.1" (Rust)
  • Client OS: Windows
  • Transport: external TCP connection to a Linux headless Copilot CLI server
  • Model: gpt-5.4
  • MCP server type: local/stdio on the Linux host

Repro shape

Rust session config includes:

  • with_transport(Transport::External { host, port })
  • with_mcp_servers(...)
  • with_env_value_mode("direct")
  • with_streaming(true)
  • with_request_permission(false)

The MCP server exposes two tools:

  • search_markdown
  • read_markdown_file

Both are advertised with MCP annotations like:

"annotations": {
  "title": "Search Markdown",
  "readOnlyHint": true
}

The server is healthy:

  • initialize works
  • tools/list works
  • the SDK reports the server as connected

Observed behavior

The MCP server connects successfully:

[session.mcp_server_status_changed] {"serverName":"search-md","status":"connected"}
[session.mcp_servers_loaded] {"servers":[{"name":"search-md","status":"connected"}]}

The model then invokes the MCP tool:

[tool.execution_start] {"arguments":{"max_matches":10,"query":"IPF"},"mcpServerName":"search-md","mcpToolName":"search_markdown","toolName":"search-md-search_markdown"}

The runtime still requests permission even though the MCP tool is marked read-only:

[permission.requested] {"permissionRequest":{"args":{"max_matches":10,"query":"IPF"},"kind":"mcp","readOnly":true,"serverName":"search-md","toolName":"search-md-search_markdown","toolTitle":"Search Markdown"},"requestId":"50439ba3-35a3-4cb5-8f96-bdba2e229a79"}

Then it reports a reject result and immediately fails with the permission-kind error:

[permission.completed] {"requestId":"50439ba3-35a3-4cb5-8f96-bdba2e229a79","result":{"kind":"reject"}}
[tool.execution_complete] {"error":{"code":"failure","message":"Unhandled permission result kind: [object Object]"},"success":false,"toolName":"search-md-search_markdown"}

The same happens for read_markdown_file:

[permission.requested] {"permissionRequest":{"args":{"end_line":120,"max_lines":120,"path":"685592_IPF_Client_UG_Rev9p0.md","start_line":1},"kind":"mcp","readOnly":true,"serverName":"search-md","toolName":"search-md-read_markdown_file"}}
[permission.completed] {"result":{"kind":"reject"}}
[tool.execution_complete] {"error":{"code":"failure","message":"Unhandled permission result kind: [object Object]"}}

Expected behavior

One of these should happen:

  1. read-only MCP tools should not go through a broken permission round-trip here, or
  2. if permission is still required, the runtime should handle the permission result without crashing the tool call.

Notes

If helpful, I can provide a minimal Rust repro plus the tiny Python MCP server used for search_markdown / read_markdown_file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions