Elevator pitch
What are you proposing to change?Add a
session/status method that lets a Client ask an Agent about a single session without changing anything:
- Active: the Agent has this session in memory right now.
- Inactive: the Agent knows this session and it can be resumed, but it is not in memory.
- Unknown: the Agent does not know this session. This is returned as a
-32002error.
session/status never loads, resumes, creates, or changes a session.
Status quo
How do things work today and what problems does this cause? Why would we change things?All the session lifecycle methods change Agent state:
session/newcreates a session.session/loadandsession/resumemake the Agent start handling a session for the connection that sent them. In v2,session/loadis gone and replay is areplayFromoption onsession/resume.session/closecancels a session’s work and frees its resources.
session/list says which sessions exist, but not which ones the Agent has in memory right now.
So a Client has no way to ask “do you have this session right now?” without becoming a participant in it. This matters when:
- A routing layer runs several Agent instances. It needs to find which instance has a session before it forwards a
session/resume. Sendingsession/resumeto an instance just to find out loads the session there, so two instances could end up running the same session. - A Client reconnects over a long-lived transport. After a network drop, it wants to know whether the session is still in memory or the Agent restarted, before deciding how to recover and what to show the user.
- A Client checks a session ID before using it. Today an unknown ID only shows up as an error from whichever method it used first, and there is no shared error code for it.
What we propose to do about it
What are you proposing to improve the situation?Add
session/status, a read-only request from the Client to the Agent.
Status values
active: The Agent has this session in memory, for any connection. This does not mean the requesting connection is attached to it. A Client that did not create or resume the session on its own connection MUST still callsession/resume(orsession/loadin v1) before sendingsession/promptor expectingsession/updatenotifications.inactive: The Agent knows the session and can resume it, but it is not in memory. The Client can callsession/resume(orsession/loadin v1) to start it.
status value they don’t recognize as inactive. That keeps a later status value from being read as permission to skip session/resume.
Foreground state (v2)
In v2, anactive response SHOULD also include state: the session’s current foreground state, using the same StateUpdate snapshot the Agent sends in state_update notifications (running, idle, or requires_action). SubagentUpdate.state already reuses this snapshot the same way.
stateis optional. If it is omitted,null, or malformed, the Agent is not reporting foreground state. Clients MUST NOT read that asidle.- Like the snapshot
session/resumesends, this is a snapshot. It is not a new transition, completion, or usage report. Anidlesnapshot may carry the laststopReasonfor context, and Clients MUST NOT count it as a new completion. - v1 has no foreground state model, so the v1 response has no
statefield.
Errors
If the Agent does not know the session, it MUST return error-32002 (Resource not found) with the requested sessionId in data. Unknown session IDs are an error, not a normal answer, so session/status reports them the same way other session methods should.
Contract
session/statusMUST NOT have side effects. It must not load, resume, create, close, or change the session, and it must not attach the requesting connection to it.- Checking whether a session is
activeSHOULD be cheap (an in-memory lookup), and Clients may call it often, for example as a routing probe. - Telling
inactiveapart from unknown may require a storage lookup. If an Agent cannot do that cheaply, it MAY returninactivefor any session it does not have in memory. A latersession/resumewill then fail with-32002if the session does not exist. - The result is a snapshot. A session reported
activemay be closed or evicted before the Client’s next request, so Clients MUST still handle errors from later session methods.
Shiny future
How will things will play out once this feature exists?
- Routing layers ask each Agent instance for
session/statusto find the one with the sessionactive, and sendsession/resumethere instead of loading it on the wrong instance. - Clients reconnecting over a long-lived transport can tell “the Agent still has my session” from “the Agent restarted and the session needs resuming”, and show the right thing right away.
- v2 Clients and dashboards can show whether a session is working, idle, or waiting on the user without attaching to it. For example, they can surface a session blocked on a permission request elsewhere.
- Agents report unknown session IDs with one error code, which other session methods can adopt too.
Implementation details and plan
Tell me more about your implementation. What is your detailed implementation plan?
Capability
session/status is optional. Agents advertise it with a session capability marker.
v1:
session/status unless the Agent advertises this capability. Like other session capability markers, an invalid value means the capability is unsupported.
Schema
Following the existing naming rules (session/status → session_status):
SessionStatusRequest:sessionId(required),_meta(optional).SessionStatusResponse:status(required),_meta(optional). In v2 only, it also hasstate(optionalStateUpdate, deserialized withDefaultOnError, since a fallback just means no foreground state was reported).SessionStatus: string enum,active|inactive, open to future values (see the unrecognized-value rule above).SessionStatusCapabilities: empty object with optional_meta, added asstatuson the v1SessionCapabilitiesand the v2 session capabilities.
Plan
- Add the method behind an
unstable_session_statusfeature flag in the v1 and v2 schemas. - Document it in the session setup docs, including the
-32002error. - Implement it in at least one Agent and one routing layer or Client before stabilizing.
Frequently asked questions
What questions have arisen over the course of authoring this document or during subsequent discussions?
Why not just call session/resume?
session/resume attaches the requesting connection and makes the Agent start handling the session. That is what a Client wants once it has decided where the session should run, but not when it is only asking. A routing layer that probes by resuming loads the session on every instance it asks.
Why is an unknown session an error instead of a not_found status?
active and inactive are expected answers about a session the Agent knows. An ID the Agent has never seen is a bad request, and other session methods already fail on it. Returning -32002 here gives that failure one consistent shape instead of a second way to say it.
Does active mean I can send session/prompt right away?
Only if your connection already created or resumed the session. active means the Agent has the session in memory, maybe for another connection. Multi-client attach semantics are covered separately in the Multi-Client Session Attach RFD.
Why not add this to session/list?
session/list is paged and filtered by cwd. It is the wrong tool for a cheap, frequent check on one known ID. Optional row fields on session/list (such as a turn state) can still exist alongside session/status.
Why is foreground state v2-only?
v1 has no foreground state model. Turn completion is only signaled by thesession/prompt response, so a v1 Agent has no defined snapshot to report. v2 already defines StateUpdate and requires session/resume to send it, so session/status can return the same snapshot without any new semantics.
Should the response include the session’s current position?
Not yet. Once message IDs and replay cursors are stable, the response could include the session’s current position, so a reconnecting Client can choose areplayFrom cursor. That can be added as an optional response field later without breaking this proposal.
What alternative approaches did you consider, and why did you settle on this one?
- Transport-level heartbeats: these only show the connection is alive, not that the Agent still has a particular session.
- Probing with
session/resume: this has side effects (see above). - Two states, with unknown sessions as a
not_foundstatus: this merges “can be resumed” with “never existed”, which a reconnecting Client needs to tell apart. It also reports unknown IDs differently from other session methods.
Revision history
- 2026-10-26: Reworked to three states (
active/inactive/-32002error), dropped thelivenaming so it isn’t confused with v2 turn state, pointed recovery atsession/resume, added v2 capability and connection semantics, added a v2-onlystateforeground snapshot onactiveresponses, and made the contract a snapshot rather than a guarantee. - 2026-04-15: Initial draft.