Skip to content

ui/update-model-context: How should hosts handle multiple instances of the same app resource? #558

@aharvard

Description

@aharvard

Problem

When a host renders the same MCP App resource URI multiple times in a single session (e.g., the same tool is invoked twice, producing two iframes for the same ui:// resource), each instance independently calls ui/update-model-context. The spec doesn't provide guidance on how the host should scope these updates.

A natural host-side key for storing context is {extension}_{resourceUri}, but this means all instances of the same resource share a single slot. The last instance to send an update overwrites the others, and the model sees only that instance's state on the next turn — potentially the wrong one.

Example

  1. User invokes a tool that renders ui://my-extension/editorInstance A appears
  2. User invokes the same tool again — Instance B appears
  3. User interacts with Instance A, which sends ui/update-model-context with { counter: 5 }
  4. User interacts with Instance B, which sends ui/update-model-context with { counter: 0 }
  5. On the next turn, the model sees counter: 0 — Instance B's state silently overwrote Instance A's

Questions

  1. Should the spec recommend instance-scoped keys? For example, the host could append a render-specific identifier (message ID, sequence number) to the context key so each instance gets its own slot.

  2. Or should last-write-wins be the expected behavior? If the spec considers each resource URI to represent a single logical piece of state, then the latest update is correct by definition — the "active" instance is whichever the user touched last.

  3. Does this interact with the slots proposal (Proposal: Slot-based updateModelContext() for independent context channels #500)? Slots address multiple context dimensions within a single app instance. Multi-instance scoping is orthogonal — you could have per-instance slots, or per-instance single context. But the two proposals share the question of key granularity.

Context

We ran into this while implementing ui/update-model-context in goose. Our current implementation uses last-write-wins keyed by {extension}__{resourceUri}, which is simple and works for the common case (one instance per resource). We'd like spec guidance before adding instance-scoped keys, since it affects how apps reason about their context lifecycle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions