Skip to content

Extension SDK: Allow mid-turn tool list rebuild after MCP enable/disable #3577

@lowdrag84

Description

@lowdrag84

Describe the feature or problem you'd like to solve

When an extension calls rpc.mcp.enable() mid-turn, the MCP server connects successfully (confirmed via mcp_server_status_changed events), but its tools don't appear in the LLM's tool list until tools_changed_notice fires at the next turn. session.rpc.tools.initializeAndValidate() is callable from joinSession() extensions but is a no-op (returns {} instantly). There is no way for an extension to force the runtime to rebuild the LLM's active tool list mid-turn. Tested with 3 MCP servers (mail, workiq, s360-breeze) — none had tools available same-turn.

Proposed solution

Expose an API that lets extensions trigger a mid-turn tool list rebuild. Options:

  1. session.rpc.tools.rebuild() — new method that forces the runtime to rebuild and inject the tool list mid-turn
  2. Make initializeAndValidate() functional for extension sessions via joinSession() (currently a no-op)
  3. Allow extensions to programmatically trigger tools_changed_notice mid-turn

This would benefit any extension that dynamically loads/unloads MCP servers for token optimization. Currently users must waste a turn after every MCP load, degrading the experience.

Diagnostic evidence and test methodology: https://github.com/gacurtin_microsoft/constellation/issues/4

Example prompts or workflows

  1. User: "Check my S360 compliance" → Extension loads s360-breeze MCP → Extension calls tools.rebuild() → LLM immediately calls s360-breeze tools — all in one turn

  2. User: "Switch to comms profile" → Extension enables teams + mail MCPs, disables others → calls tools.rebuild() once → LLM sees all new tools immediately

  3. User: "Search my email for the budget report" → Extension loads mail MCP on demand → rebuild → LLM calls mail-SearchMessages — no wasted turn

Use case: Constellation (https://github.com/lowdrag84/constellation) — profile-based MCP manager saving 16K-33K tokens/turn by only loading needed MCPs. Everything works except this one-turn delay.

Additional context

Diagnostic Evidence

APIs tested from extension via joinSession():

API Status
session.rpc.tools.initializeAndValidate() Callable but no-op — returns {} in ~29ms
session.rpc.tools (full namespace) Only has: handlePendingToolCall, initializeAndValidate
session.on('mcp_server_status_changed') Works — events fire with "connected" status
session.rpc.mcp.list() Works — returns {servers: [...]}
tools_changed_notice Only fires between turns, not triggerable

Live Test Results

MCP Server Connected? Tools Same-Turn? Tools Appeared Via
mail tools_changed_notice (next turn)
workiq tools_changed_notice (~90s later)
s360-breeze tools_changed_notice (~90s later)

Environment

  • Copilot CLI v1.0.56-1
  • Extension SDK: @github/copilot-sdk/extension via joinSession()
  • OS: Windows 11
  • Extension: Constellation (profile-based MCP manager)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registryarea:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agents
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions