Skip to content

MCP Apps and canvas bridge

This page documents the UI-capability bridge added in the refreshed @github/copilot 1.0.54 package. It covers two related but distinct surfaces:

  • Canvas renderer support lets SDK/server clients register renderable canvases, expose model tools for opening and acting on those canvases, and receive canvas lifecycle events.
  • MCP Apps support lets MCP servers expose UI metadata/resources behind an opt-in mcp-apps session capability, with app-originated MCP tool calls reported back through session events.

Read this with Embedded server, ACP, and JSON-RPC protocol for session create/resume APIs, MCP host, transports, and tools for MCP server lifecycle, and Copilot SDK extension bridge for SDK extension process boundaries.

Source anchors

app.js is bundled/minified, so semantic aliases below are explanatory. Approximate line numbers refer to the extracted 1.0.54 package.

AreaSemantic aliasMinified anchor / stringApprox. lineWhat it proves
Feature gateMCP Apps gateMCP_APPS, COPILOT_MCP_APPS, bqe(...)240, 4593MCP Apps is experimental by default and can be enabled through the environment override.
Canvas model toolsCanvas tool providerlist_canvas_capabilities, open_canvas, invoke_canvas_action372The model-visible tool layer can inspect, open, and act on canvases.
Canvas system promptCanvas instructions<canvases>, open_canvas, list_canvas_capabilities4260The prompt tells the model when and how to use canvases.
Canvas managerCanvas registry/instancesA0t, registerProvider, openInstances, availability4821Providers register canvas declarations; open instances become ready/stale and emit events.
Canvas eventsSession canvas eventssession.canvas.opened, session.canvas.registry_changed4821Canvas lifecycle updates are ephemeral session events.
SDK/server capability ingressSession capability optionsrequestCanvasRenderer, requestMcpApps, buildSdkSessionCapabilities6375SDK/server create/resume can opt sessions into canvas and MCP Apps capabilities.
SDK connection registrationCanvas provider registrationregisterCanvasesForConnection(...)6375Connected SDK/server clients can register canvas providers by connection.
MCP Apps diagnosticsMCP Apps API surfacemcp.apps.diagnose, _meta.ui, McpAppsDiagnoseResult4856Runtime exposes a diagnostic API for capability and _meta.ui visibility.
MCP Apps tool callsApp-originated MCP call eventmcp_app.tool_call_complete, supportsMcpApps()4940App-originated MCP calls emit success/error/duration/result metadata.

Capability model

Canvas and MCP Apps are both session capabilities, but they enter through different gates.

flowchart TD
Client[SDK / server client] --> Create[session.create or session.resume]
Create --> CanvasReq{requestCanvasRenderer?}
Create --> McpAppsReq{requestMcpApps?}
CanvasReq -->|yes| CanvasCap[add canvas-renderer capability]
McpAppsReq -->|yes| McpGate{MCP_APPS or COPILOT_MCP_APPS=true?}
McpGate -->|yes| McpAppsCap[add mcp-apps capability]
McpGate -->|no| Drop[warn and do not advertise mcpApps]
CanvasCap --> Caps[capabilities.changed / session capabilities]
McpAppsCap --> Caps

The server returns UI capability flags such as ui.canvases and ui.mcpApps from session create/resume/get-foreground paths. Capability provider changes are also projected through capabilities.changed.

Canvas lifecycle

Canvas providers are registered by connected SDK/server clients rather than discovered from the filesystem. A provider contributes one or more canvas declarations with:

FieldRole
idProvider-local canvas identifier.
displayNameHuman-readable name.
descriptionShort description shown to the agent in canvas catalogs.
inputSchemaOptional JSON schema for opening the canvas.
actionsOptional action names, descriptions, and input schemas for open instances.

The runtime validates declarations before accepting them:

  • canvas IDs must be present and unique for a provider;
  • action names cannot use the reserved canvas. prefix;
  • open/action input schemas are compiled and invalid schemas reject registration;
  • a provider cannot overwrite another live provider’s extensionId/canvasId pair.

When registration succeeds, the runtime emits session.canvas.registry_changed with the currently available canvases.

Opening and using a canvas

The model sees canvas-specific tools when the canvas renderer capability is present:

ToolPurpose
list_canvas_capabilitiesInspect a specific canvas declaration and action schemas.
open_canvasOpen or focus a canvas using a caller-chosen stable instanceId.
invoke_canvas_actionInvoke a named action on an open canvas instance.

open_canvas is idempotent for an existing instanceId; re-opening focuses or no-ops the existing surface. Open results are normalized, and URL results are limited to http: or https: schemes. When a canvas opens, focuses, is rehydrated, or changes availability, the runtime emits session.canvas.opened.

Provider disconnect and reconnect

Open canvas instances survive provider disconnects as stale records:

sequenceDiagram
participant Client as SDK/server client
participant Registry as Canvas registry
participant Session as Session events
participant Model as Model tools
Client->>Registry: registerProvider(canvases)
Registry->>Session: session.canvas.registry_changed
Model->>Registry: open_canvas(instanceId, canvasId)
Registry->>Client: canvas.open request
Registry->>Session: session.canvas.opened(ready)
Client--xRegistry: disconnect / unregisterProvider
Registry->>Session: session.canvas.opened(stale, reopen=true)
Client->>Registry: registerProvider(canvases)
Registry->>Session: session.canvas.opened(ready, reopen=true)

If the model tries to act on a stale instance, routing fails with a provider-unavailable error and the model should re-issue open_canvas after a provider reconnects.

MCP Apps lifecycle

MCP Apps is separate from canvas providers. It starts from MCP server tool/resource metadata and is gated by MCP_APPS or COPILOT_MCP_APPS=true.

Runtime behavior visible in the bundle:

  1. Session create/resume requests requestMcpApps.
  2. The server only adds mcp-apps if the feature gate or env override is enabled.
  3. MCP clients advertise UI capability to capable servers.
  4. The MCP tool list path tolerates _meta.ui through a lenient schema path.
  5. Runtime diagnostics can report whether the session has mcp-apps, whether the gate is enabled, and how many tools expose _meta.ui.
  6. App-originated MCP calls emit mcp_app.tool_call_complete.

The mcp_app.tool_call_complete event includes:

FieldMeaning
serverName / toolNameMCP server and tool invoked by the app view.
argumentsOptional arguments passed to the underlying tools/call.
successFalse if the call threw or returned an MCP isError result.
durationMsWall-clock duration for the underlying call.
result / errorNormal MCP result or thrown error message.
toolMeta.uiRelevant UI metadata copied from the MCP tool.

MCP Apps does not bypass normal MCP setup. Servers still come from the MCP config merge, pass through policy filters, authenticate via the existing OAuth path when needed, and expose tools through the same host/client registry.

Relationship between canvas and MCP Apps

Canvas and MCP Apps both create richer UI paths, but they are not the same mechanism.

ConcernCanvas rendererMCP Apps
Primary providerSDK/server client connection.MCP server tool/resource metadata.
Capability flagcanvas-renderer, returned as ui.canvases.mcp-apps, returned as ui.mcpApps.
Model toolslist_canvas_capabilities, open_canvas, invoke_canvas_action.Normal MCP tools plus app-originated tool/resource operations.
Main eventssession.canvas.registry_changed, session.canvas.opened.mcp_app.tool_call_complete.
GateSession request/capability support.Session request plus MCP_APPS or COPILOT_MCP_APPS=true.

The shared operational point is that both surfaces make a connected host UI more capable while keeping the session event stream and MCP/SDK boundaries explicit.

Failure modes and caveats

CaseRuntime behavior
requestMcpApps without gate/envServer logs a warning and does not advertise ui.mcpApps.
Canvas provider missingopen_canvas fails with a canvas-not-found error.
Canvas ID ambiguous across providersRuntime asks the model/client to provide extensionId.
Canvas provider disconnectsOpen instances become stale; re-open or provider reconnect is needed.
Canvas provider returns unsupported URL schemeRuntime rejects the open result.
App calls an MCP tool without mcp-apps capabilitySession rejects the app-originated call/resource path.
MCP tool has no callable UI metadataApp-originated call path rejects it as not callable from MCP Apps.

Documentation action from the 1.0.54 delta

This subsystem is the only new atlas delta from the 1.0.54 update that warranted a dedicated page. Other deltas were narrower and are covered in existing pages:

DeltaDocumentation action
security-review built-in agent and /security-reviewCovered in Built-in agents, Agent and task orchestration, and Prompt sources.
deferred-tool-loading custom-agent frontmatterCovered in Custom agents and skills packaging.
preMcpToolCall hookCovered in Hooks, events, and automation.
New env/gate strings such as COPILOT_PLUGIN_DIR_ONLY, COPILOT_ENABLE_SECRET_FILTERING, and TARGETED_VALIDATION_PROMPTNarrow knobs or gated support surfaces; keep with existing plugin/redaction/feature-gate docs unless a future question needs a deeper runtime pass.

Created and maintained by Yingting Huang.