On a stdio connection, a client has two active subscriptions, opened by subscriptions/listen requests with ids 7 and 9. Notifications from both arrive interleaved on the server's stdout. How does the client tell them apart?
Select an answer to reveal the explanation.
Short Explanation
On stdio everything shares one pipe, so you need each notification to wear a name tag. That tag is subscriptionId in _meta, and it equals the listen request's id. Notifications don't have their own id, which is the trap.
Full Explanation
A client may hold several subscriptions concurrently. Each subscription is identified by the JSON-RPC id of the subscriptions/listen request that opened it, and every notification on that subscription, including the initial acknowledgment, carries io.modelcontextprotocol/subscriptionId in _meta with that value. On stdio, where all messages share a single channel and there are no per-request streams, clients MUST use this field to correlate notifications with their originating subscription, so the client routes each message to subscription 7 or 9 by reading it. JSON-RPC notifications MUST NOT include an id, so no notification can repeat the listen request's id in that position; the correlation value lives in _meta instead. Arrival order is unreliable because the specification allows messages belonging to other subscriptions to be interleaved, with acknowledgment ordering defined per subscription rather than per channel. A progressToken opts a request into progress notifications for that request's work; it is not used to tag subscription notifications, and progress is request-scoped and never delivered on a listen stream. Exam caveat: if the stdio connection is terminated and re-established, the client MUST re-send subscriptions/listen because the server holds no subscription state across reconnections. Operational check: log the subscriptionId of every incoming notification and confirm each value matches the id of an open listen request.