modelcontextprotocol / modelcontextprotocol/ext-apps

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

Open
#500 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.9k
Forks
387
Avg merge
3h 21m
Merged PRs (30d)
6

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the TypeScript SDK's updateModelContext() entry point and trace how replacement-based context is represented and exposed. Compare the proposed independent slot, clearing, ordering, and no-slot backward-compatibility semantics, then define acceptance checks showing that updating one slot preserves the others.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.