Preamble
- Title: Open-Ended Streams
- Author: @ContextVM-org
- Type: Standards Track
Abstract
This proposal defines an open-ended stream transfer profile for ContextVM using MCP notifications/progress as the framing envelope. Unlike bounded transfer in CEP-22, this proposal is intended for exchanges where no single final reassembled payload is the right abstraction, such as incremental generation, event feeds, and long-lived result streams. The proposal uses the request progressToken as the stream identifier and defines ordered stream frames carried inside progress notifications. It includes stream lifecycle control, receiver acknowledgement for bootstrap when support is not already known, and explicit keepalive and termination semantics for long-lived streams. The goal is to standardize interoperable open streaming over the existing ContextVM transport model without introducing a separate transport channel or redefining MCP semantics.
Motivation
ContextVM already supports ordinary request/response delivery well, and CEP-22 covers bounded oversized payload transfer. However, some workloads are fundamentally stream-shaped rather than bounded-message-shaped. Examples include token-by-token generation, progressive computation output, subscriptions, event feeds, and other long-running operations that produce useful partial results over time.
Without a standard stream profile, implementations are forced into ad hoc patterns for partial output, lifecycle signaling, liveness, and receiver coordination. That creates avoidable interoperability problems and increases the chance that different SDKs and services will drift toward incompatible conventions.
This proposal addresses that gap by defining a single open-stream profile that remains compatible with the existing ContextVM event transport, reuses MCP progress notifications, and aligns shared handshake semantics with CEP-22 instead of inventing a parallel mechanism.
Rationale
The design reuses MCP notifications/progress because ContextVM already carries MCP messages through Nostr events, and progressToken already provides a natural per-request correlation mechanism. This avoids introducing a second transport abstraction solely for streaming.
The proposal is intentionally distinct from CEP-22. CEP-22 is for bounded reassembly of one final logical message, while this proposal is for open-ended streams where partial consumption is part of the intended semantics.
The handshake behavior is kept aligned with CEP-22: if sender support knowledge for the exchange already exists, transmission may proceed directly after start; otherwise the sender must wait for accept before sending chunk frames. This preserves shared semantics across both CEPs and reduces semantic drift.
The framing model is minimal on purpose. It uses start, accept, chunk, ping, pong, close, and abort frames, with progress as the normative ordering field. The proposal also keeps stream liveness explicit by requiring idle-time probing through ping and pong, rather than leaving long-lived stream health entirely to local heuristics.
Security Implications
Open-ended streams can consume memory, CPU, relay bandwidth, and implementation attention for extended periods. Implementations therefore need clear limits on stream lifetime, buffering, idle handling, and concurrent active streams.
This proposal includes explicit stream termination and keepalive behavior so that abandoned or half-dead streams do not remain indefinitely ambiguous. A peer that observes idle timeout must probe with ping, and failure to receive the matching pong before probe timeout causes the stream to fail. Implementations should still enforce hard resource ceilings, including maximum stream duration or other local policy limits.
As with other ContextVM transport features, implementations must validate framing strictly, reject malformed or out-of-order traffic, and treat abort as terminal. These measures reduce ambiguity and lower the risk of resource exhaustion through malformed or intentionally abusive stream flows.
Specification
Specification PR
Preamble
Abstract
This proposal defines an open-ended stream transfer profile for ContextVM using MCP
notifications/progressas the framing envelope. Unlike bounded transfer inCEP-22, this proposal is intended for exchanges where no single final reassembled payload is the right abstraction, such as incremental generation, event feeds, and long-lived result streams. The proposal uses the requestprogressTokenas the stream identifier and defines ordered stream frames carried inside progress notifications. It includes stream lifecycle control, receiver acknowledgement for bootstrap when support is not already known, and explicit keepalive and termination semantics for long-lived streams. The goal is to standardize interoperable open streaming over the existing ContextVM transport model without introducing a separate transport channel or redefining MCP semantics.Motivation
ContextVM already supports ordinary request/response delivery well, and
CEP-22covers bounded oversized payload transfer. However, some workloads are fundamentally stream-shaped rather than bounded-message-shaped. Examples include token-by-token generation, progressive computation output, subscriptions, event feeds, and other long-running operations that produce useful partial results over time.Without a standard stream profile, implementations are forced into ad hoc patterns for partial output, lifecycle signaling, liveness, and receiver coordination. That creates avoidable interoperability problems and increases the chance that different SDKs and services will drift toward incompatible conventions.
This proposal addresses that gap by defining a single open-stream profile that remains compatible with the existing ContextVM event transport, reuses MCP progress notifications, and aligns shared handshake semantics with
CEP-22instead of inventing a parallel mechanism.Rationale
The design reuses MCP
notifications/progressbecause ContextVM already carries MCP messages through Nostr events, andprogressTokenalready provides a natural per-request correlation mechanism. This avoids introducing a second transport abstraction solely for streaming.The proposal is intentionally distinct from
CEP-22.CEP-22is for bounded reassembly of one final logical message, while this proposal is for open-ended streams where partial consumption is part of the intended semantics.The handshake behavior is kept aligned with
CEP-22: if sender support knowledge for the exchange already exists, transmission may proceed directly afterstart; otherwise the sender must wait foracceptbefore sendingchunkframes. This preserves shared semantics across both CEPs and reduces semantic drift.The framing model is minimal on purpose. It uses
start,accept,chunk,ping,pong,close, andabortframes, withprogressas the normative ordering field. The proposal also keeps stream liveness explicit by requiring idle-time probing throughpingandpong, rather than leaving long-lived stream health entirely to local heuristics.Security Implications
Open-ended streams can consume memory, CPU, relay bandwidth, and implementation attention for extended periods. Implementations therefore need clear limits on stream lifetime, buffering, idle handling, and concurrent active streams.
This proposal includes explicit stream termination and keepalive behavior so that abandoned or half-dead streams do not remain indefinitely ambiguous. A peer that observes idle timeout must probe with
ping, and failure to receive the matchingpongbefore probe timeout causes the stream to fail. Implementations should still enforce hard resource ceilings, including maximum stream duration or other local policy limits.As with other ContextVM transport features, implementations must validate framing strictly, reject malformed or out-of-order traffic, and treat
abortas terminal. These measures reduce ambiguity and lower the risk of resource exhaustion through malformed or intentionally abusive stream flows.Specification
Specification PR