Skip to content

MCP session reuse and host identity

Read this when…

You integrate an MCP client or host wrapper and need stable sessions across reconnects, tabs, or subagents.

What to know first: Concepts, Incremental DOMAIN prompts (symbol stability).

Practical takeaway: intent (host-supplied) defines the logical session—not MCP-Session-Id. Keep intent stable for the life of a task; rotate it only when you intentionally want a new logical session.


This document is the canonical description of how plasm_context, plasm, and execute session reuse interact. The MCP transport (MCP-Session-Id) does not identify a host agent, window, or subagent. That boundary is always defined by the host via the intent string on plasm_context and the resulting logical session.

See also: MCP logical sessions, incremental DOMAIN prompts, MCP trace correlation.

1. Flow

  1. plasm_context with intent and non-empty seeds
  2. The server is idempotent on (tenant_scope, intent): the same string yields the same canonical logical_session_id and the same per-transport logical_session_ref (e.g. s0).
  3. If a live execute session is already bound for that logical id, the server expands or federates into that session (no fresh-open path).
  4. Duplicate seeds (already exposed): if the request does not add new entity picks, the expand path returns a short notice only—the full DOMAIN / TSV teaching table is not replayed (token-saving). Steady state remains plasm / plasm_run with the existing logical_session_ref.
  5. If there is no binding, or the stored binding points at an expired or missing execute row, the server may open a new (prompt_hash, session).
  6. The primary entry_id for the first open is chosen in lexicographic order among distinct catalog ids in the seed set, so two calls with the same set of catalog seeds in different order still agree on the same primary for SessionReuseKey matching.
  7. The tool response JSON includes logical_session_id, logical_session_ref, and execute_binding: { prompt_hash, session_id }.
  8. plasm with logical_session_ref and program
  9. Steady state for most user turns: use plasm only; do not repeat plasm_context unless you need a new intent or new seeds.

2. intent (host contract)

  • Role: Opaque string selected by the host to mean “this agent / window / subagent / task isolation boundary / whatever the host needs to separate.”
  • Stability: Must stay stable for the duration of that context. Rotating intent per message or per unrelated micro-step breaks idempotent logical session recovery and will fragment reuse.
  • Not inferable: The Plasm server does not infer a stable “ongoing user task” from the transport, workspace path, or prompt text. The host must supply intent when it wants continuity.

3. SessionReuseKey (when execute open can reuse a row)

Defined in execute_session.rs as the key for in-memory try_reuse_session on new open:

Field Role
tenant_scope Incoming-auth tenant / anonymous scope.
entry_id Primary catalog id for the open (lexicographically first among seed catalogs).
catalog_cgs_hash Pinned CGS digest.
entities Sorted, deduplicated primary-catalog entity seeds.
principal Present when PLASM_AUTH_RESOLUTION=delegated.
plugin_generation_id Compile-plugin pin when a compile plugin is loaded.
logical_session_id Logical UUID string; scopes reuse per logical session. Absent when a host opens execution without binding a logical id.

If any of these differ from a prior open, a new execute row may be created. Changing catalog hash or plugin generation is intentional: the old session is not a safe match.

4. Stale execute binding (continuity break)

MCP can retain a logical handle (logical_session_ref) and a binding (prompt_hash, session_id) in memory or in the host-wide map after the in-memory ExecuteSessionStore row was dropped (e.g. idle TTL). The next plasm_context will treat the binding as missing and may open a new execute session.

When that happens, the plasm_context result includes:

  • Markdown: a prominent notice that the prior in-memory session was missing or expired, that all earlier e# / m# / p# from this chat are void, and that the model must re-read the new DOMAIN/TSV from this response only.
  • _meta.plasm.continuity: on every plasm_context response, stale_binding_recovered (boolean) and new_symbol_space (boolean — true when a new execute row with a new symbol table was bound, e.g. first open or a non-reused open after an expiry). When stale_binding_recovered is true, previous_execute may name the old (prompt_hash, session_id). When new_symbol_space is true, discard_cached_plasm_symbols is also true (same meaning as new_symbol_space for tool clients that key off a dedicated key).

5. Execute-time projection and result summaries

  • Projection (path expressions, batch steps): selects which fields and rows the executor materializes. This is the authoritative narrowing for what the engine computes.
  • Table / TSV / Markdown on the wire: may still cap, summarize lossy fields, or point at resources/read for full JSON snapshots, even when the execution already used projection. That is transport shaping, not a second projection system.

Large-result guidance: prefer projection in expressions first; when the surface must still be shortened for the tool channel, use snapshot links and _meta.plasm as today.