Skip to content

agentHost: preserve MCP App tool-result _meta for restored cards - #344856

Merged
Connor Peet (connor4312) merged 3 commits into
mainfrom
copeet/mcp-result-meta
Oct 29, 2026
Merged

Connor Peet (connor4312) merged 3 commits into
mainfrom
copeet/mcp-result-meta

Conversation

@connor4312

@connor4312 Connor Peet (connor4312) commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Fixes #343243

Agent Host rebuilt MCP App ui/notifications/tool-result notifications from session state without the server's result _meta. App-only data (e.g. _meta.flint.board in the issue) was lost when a card was reconstructed, including after reopening a session or restarting.

Changes

  • The Copilot runtime now reports the verbatim MCP CallToolResult._meta on tool.execution_complete as result.mcpResultMeta, for MCP App tools only (github/copilot-agent-runtime#30458). It is separate from the IFC-only mcpMeta.
  • Adds resultMetadata?: Record<string, unknown> to AHP ToolCallResult, mirroring MCP CallToolResult._meta the same way structuredContent mirrors structuredContent. The canonical protocol change is chat: add ToolCallResult.resultMetadata mirroring MCP CallToolResult._meta agent-host-protocol#549; the synced types here are updated to match. The protocol reducer, result confirmation (agentSideEffects), and conversation import validation carry it like structuredContent.
  • copilotAgentSession.ts (live completion) and mapSessionEvents.ts (history replay) set resultMetadata from the runtime's mcpResultMeta. Host-owned tool-call _meta (ui, toolKind, ...) is untouched.
  • stateToProgressAdapter.ts (toMcpCallToolResult) rebuilds resultMetadata as the MCP result _meta for completed tools only. Metadata-only (content: []) and error results count as real results.
  • Model-facing conversion (agentHostMcpAppToolsService._convertResult) is unchanged and does not include result _meta.
  • The pinned @github/copilot-sdk does not declare mcpResultMeta yet, so getSdkMcpResultMeta reads it through a narrow cast (TODO to remove after the SDK bump). With an older runtime the field is absent and behavior is unchanged.

How to test

  1. Run a runtime/SDK build that includes github/copilot-agent-runtime#30458.
  2. Add an MCP App server whose tool result carries _meta. The ext-apps basic-server-vanillajs example with a per-call _meta.example.verificationToken works; it displays the received token.
  3. In an Agent Host chat, have the model call the tool. The card shows the token. Reopen the session and restart VS Code: the same token is shown. Get Server Time shows a new one.

Validation

  • scripts/test.bat --run on agentMetaReaders, agentHostCreateSessionImportMeta, copilotAgentSession, mapSessionEvents, reducers, agentSideEffects, stateToProgressAdapter, and agentHostMcpAppToolsService tests: 2334 passing.
  • npm run typecheck-client: passes against the pinned SDK, and against a local SDK that declares the field.
  • npm run eslint on the changed files: clean.
  • Manual end to end with a local runtime build and the example above: live, reopened, and cold-restarted cards all received the original token.

Written by Connor's agent

Fixes #343243. Agent Host rebuilt MCP App ui/notifications/tool-result from
state without the server's result _meta, so app-only data was lost on live
reconstruction and after restoring a session.

Carry the runtime's tool.execution_complete result.mcpResultMeta in a
namespaced vscode.mcpToolResultMeta tool-call meta slot on live completion and
history replay, and rebuild it as the MCP result _meta, including
metadata-only and error results. It stays isolated from host-owned meta and out
of model-facing content. The SDK field is read through a narrow cast until the
pinned @github/copilot-sdk declares it.

Co-authored-by: Copilot <[email protected]>
Copilot AI balanced review requested due to automatic review settings October 28, 2026 22:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the change preserving MCP App result metadata across session restoration.

No open issues 🎉

What changed in this PR

Addresses #343243 by preserving MCP App result _meta through Agent Host session state, so restored cards retain app-only data without exposing it to the model. This relies on a runtime that supplies mcpResultMeta; older runtimes remain unchanged.

Changes:

  • Capture result metadata during live completion and history replay in an isolated, namespaced slot.
  • Restore metadata in completed MCP results, including metadata-only and error results.
  • Add coverage for validation, persistence, live/restored parity, and model-facing exclusion.
File Description
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​stateToProgressAdapter.test.ts Tests live/restored metadata parity and running-tool exclusion.
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​agentHostMcpAppToolsService.test.ts Verifies app-only metadata stays out of model-facing content.
src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​stateToProgressAdapter.ts Restores _meta when rebuilding completed MCP results.
src/​vs/​platform/​agentHost/​test/​node/​mapSessionEvents.test.ts Tests metadata preservation during history replay.
src/​vs/​platform/​agentHost/​test/​node/​copilotTestEvents.ts Adds result metadata to the test event shape.
src/​vs/​platform/​agentHost/​test/​node/​copilotAgentSession.test.ts Tests live completion metadata for success and error results.
src/​vs/​platform/​agentHost/​test/​common/​agentMetaReaders.test.ts Tests validation, host-key isolation, and presentation fallbacks.
src/​vs/​platform/​agentHost/​test/​common/​agentHostCreateSessionImportMeta.test.ts Tests metadata survival through serialization and staged import.
src/​vs/​platform/​agentHost/​node/​copilot/​mapSessionEvents.ts Adds an SDK compatibility reader and preserves metadata during replay.
src/​vs/​platform/​agentHost/​node/​copilot/​copilotAgentSession.ts Captures result metadata on live tool completion.
src/​vs/​platform/​agentHost/​common/​meta/​vscode/​agentToolCallMeta.ts Defines and validates the namespaced result metadata slot.

Review effort: Balanced

@connor4312
Connor Peet (connor4312) marked this pull request as draft October 28, 2026 22:24
Replace the namespaced vscode.mcpToolResultMeta tool-call meta slot with a
first-class AHP ToolCallResult.resultMetadata field mirroring MCP
CallToolResult._meta. Mirrors microsoft/agent-host-protocol; the field is
copied through the protocol reducer, result confirmation, and conversation
import like structuredContent.

Co-authored-by: Copilot <[email protected]>
# Conflicts:
#	src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts
@connor4312

Copy link
Copy Markdown
Member Author

Merged main to fix a conflict (one import line in copilotAgentSession.ts), which dismissed the earlier approvals. No functional changes since approval. The agent-host-protocol counterpart, microsoft/agent-host-protocol#549, is now merged, so resultMetadata matches upstream AHP. Auto-merge is enabled.

Written by Connor's agent

@connor4312
Connor Peet (connor4312) merged commit 8078df0 into main Oct 29, 2026
55 checks passed
@connor4312
Connor Peet (connor4312) deleted the copeet/mcp-result-meta branch October 29, 2026 18:23
@vs-code-engineering vs-code-engineering Bot added this to the 1.145.0 milestone Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP Apps: Agent Host drops _meta from the rebuilt tool-result, so restored app cards render empty

6 participants