Skip to content

Proposal: Slot-based updateModelContext() for independent context channels #500

@psylch

Description

@psylch

Problem

updateModelContext() is replacement-based — each call overwrites all previous context. This forces developers to re-bundle all context dimensions into every single update, even when only one dimension changed.

In practice, an MCP App maintains several independent context channels:

Channel Update frequency Content
Current state On every edit (debounced) Full artifact code/data
Selection On selection change (debounced) Which elements the user is pointing at
Change history Accumulated over time Semantic deltas (rename, add, delete)
Metadata Rarely Diagram type, view mode, etc.

Today, updating selection requires re-sending the full artifact code + change history + metadata, because any updateModelContext() call replaces everything. This creates:

  1. Redundant data transmission — re-sending unchanged state on every update
  2. Timing coupling — all context dimensions must be synchronized at the same debounce interval
  3. Code complexity — developers must maintain a "context assembler" that merges all dimensions before every update

Proposal

Support named slots that update independently:

// Each slot is independently replaceable
app.updateModelContext({ content: [...] }, { slot: "state" });      // current code
app.updateModelContext({ content: [...] }, { slot: "selection" });   // selected elements
app.updateModelContext({ content: [...] }, { slot: "history" });     // change log

// Updating one slot does NOT affect other slots
// Model sees the merged result of all slots

Semantics

  • Each slot is independently replacement-based (updating "selection" only replaces the previous "selection" content)
  • The model sees the concatenation of all active slots (ordering: by slot creation time, or alphabetical, or developer-specified priority)
  • A call without slot behaves as today (replaces everything) for backward compatibility
  • Clearing a slot: app.updateModelContext({ content: [] }, { slot: "selection" }) or app.clearModelContext({ slot: "selection" })

Alternative: Append mode

A simpler variant would be append-mode:

app.updateModelContext({ content: [...] }, { mode: "append" });

This is less flexible (can't independently update/clear specific dimensions) but simpler to implement.

Real-world context

We build MCP Apps (Mermaid diagrams, PlantUML, Music composer) and documented our context design patterns. The key insight: effective AI context has four independent layers (current state, user focus/selection, change history, user intent), each with different update frequencies and lifecycles. The current single-replacement API forces them into one monolithic blob.

This is especially painful combined with debouncing — selection changes (1.5s debounce) and code edits (500ms debounce) happen at different rates, but both must trigger a full context rebuild because any update overwrites the other.

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