-
Notifications
You must be signed in to change notification settings - Fork 111
RFD: session/list API for session discovery and management #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
benbrandt
merged 4 commits into
agentclientprotocol:main
from
ahmedhesham6:rfd/sessions-list
Oct 31, 2025
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4fa5b7a
RFD: session/list API for session discovery and management
ahmedhesham6 80b6d99
docs(rfd): use _meta for session info metadata
ahmedhesham6 88e2d0f
docs(rfd): refactor session/list API design
ahmedhesham6 173ba0f
Add usernamess and format the document
benbrandt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,347 @@ | ||
| --- | ||
| title: "Session List API" | ||
| --- | ||
|
|
||
| Author(s): [@ahmedhesham6](https://github.com/ahmedhesham6) | ||
| Champion: [@benbrandt](https://github.com/benbrandt) | ||
|
|
||
| ## Elevator pitch | ||
|
|
||
| Add a `session/list` endpoint to the ACP protocol that allows clients to query and enumerate existing sessions from an agent, enabling session management features like session history, session switching, and session cleanup. | ||
|
|
||
| ## Status quo | ||
|
|
||
| Currently, the ACP protocol provides session management through `session/new` and `session/load` endpoints. However, there is no way for clients to: | ||
|
|
||
| 1. **Discover existing sessions** - Clients cannot query what sessions exist on an agent | ||
| 2. **Display session history** - Users cannot see a list of their past conversations | ||
| 3. **Manage multiple sessions** - Switching between sessions requires clients to track session IDs themselves | ||
| 4. **Clean up old sessions** - No way to discover stale or abandoned sessions for cleanup | ||
|
|
||
| This creates several problems: | ||
|
|
||
| - **Poor user experience** - Users cannot browse their conversation history or resume previous sessions easily | ||
| - **Client-side complexity** - Each client must implement its own session tracking and persistence | ||
| - **Inconsistent behavior** - Different clients handle session management differently, leading to fragmented experiences | ||
|
|
||
| The current workaround is for clients to maintain their own session registry, but this: | ||
|
|
||
| - Requires persistent storage on the client side | ||
| - Can get out of sync if sessions are created/destroyed outside the client | ||
| - Doesn't work across different client instances or devices | ||
| - Cannot leverage agent-side session metadata or state | ||
|
|
||
| ## What we propose to do about it | ||
|
|
||
| Add a new `session/list` JSON-RPC method to the protocol that returns metadata about sessions known to the agent. This endpoint would: | ||
|
|
||
| 1. **Return a list of sessions** with essential metadata: | ||
| - `sessionId` - Unique identifier | ||
| - `createdAt` - Timestamp when session was created | ||
| - `updatedAt` - Timestamp of last update to the session | ||
| - `cwd` - Working directory for the session | ||
| - `title` - Optional human-readable title (could be auto-generated from first prompt) | ||
| - `_meta` - Optional agent-specific metadata | ||
|
|
||
| 2. **Support filtering and pagination**: | ||
| - Filter by creation date, last accessed date, or working directory | ||
| - Limit the number of results returned | ||
| - Search by title or agent-provided metadata | ||
|
|
||
| 3. **Be an optional capability**: | ||
| - Agents advertise `listSessions: true` in initialization if they support this feature | ||
| - Clients check for this capability before attempting to call `session/list` | ||
| - Agents without persistent session storage don't need to implement this | ||
|
|
||
| ### JSON-RPC Request | ||
|
|
||
| The client calls `session/list` with optional filtering and pagination parameters: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "method": "session/list", | ||
| "params": { | ||
| "cwd": "/home/user/project", | ||
| "createdAfter": "2025-10-20T00:00:00Z", | ||
| "limit": 20, | ||
| "continuationToken": "offset:20", | ||
| "search": "auth" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### Request Parameters | ||
|
|
||
| All parameters are optional: | ||
|
|
||
| - `cwd` (string) - Filter sessions by working directory | ||
| - `createdAfter` (string) - ISO 8601 timestamp, only return sessions created after this time | ||
| - `createdBefore` (string) - ISO 8601 timestamp, only return sessions created before this time | ||
| - `updatedAfter` (string) - ISO 8601 timestamp, only return sessions updated after this time | ||
| - `limit` (number) - Maximum number of results to return (default: 50, max: 1000) | ||
| - `continuationToken` (string) - Opaque/stringified token from a previous response for cursor-based pagination | ||
| - `search` (string) - Free-text search across titles or agent metadata | ||
|
|
||
| #### Minimal Request Example | ||
|
|
||
| A request with no filters returns all sessions with default sorting: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "method": "session/list", | ||
| "params": {} | ||
| } | ||
| ``` | ||
|
|
||
| ### JSON-RPC Response | ||
|
|
||
| The agent responds with a list of sessions and cursor pagination metadata: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "result": { | ||
| "sessions": [ | ||
| { | ||
| "sessionId": "sess_abc123def456", | ||
| "createdAt": "2025-10-29T10:30:00Z", | ||
| "updatedAt": "2025-10-29T14:22:15Z", | ||
| "cwd": "/home/user/project", | ||
| "title": "Implement session list API", | ||
| "_meta": { | ||
| "messageCount": 12, | ||
| "hasErrors": false | ||
| } | ||
| }, | ||
| { | ||
| "sessionId": "sess_xyz789ghi012", | ||
| "createdAt": "2025-10-28T09:15:00Z", | ||
| "updatedAt": "2025-10-28T16:45:30Z", | ||
| "cwd": "/home/user/another-project", | ||
| "title": "Debug authentication flow" | ||
| }, | ||
| { | ||
| "sessionId": "sess_uvw345rst678", | ||
| "createdAt": "2025-10-27T14:00:00Z", | ||
| "updatedAt": "2025-10-27T15:30:00Z", | ||
| "cwd": "/home/user/project" | ||
| } | ||
| ], | ||
| "hasMore": true, | ||
| "nextContinuationToken": "offset:40" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### Response Fields | ||
|
|
||
| **Response object:** | ||
|
|
||
| - `sessions` (array) - Array of session information objects | ||
| - `hasMore` (boolean) - Whether more results are available after this page | ||
| - `nextContinuationToken` (string, optional) - Pass this token in the next request's `continuationToken` to fetch the next page | ||
|
|
||
| **SessionInfo object:** | ||
|
|
||
| - `sessionId` (string, required) - Unique identifier for the session | ||
| - `createdAt` (string, required) - ISO 8601 timestamp when session was created | ||
| - `updatedAt` (string, required) - ISO 8601 timestamp of last activity | ||
| - `cwd` (string, required) - Working directory for the session | ||
| - `title` (string, optional) - Human-readable title (may be auto-generated from first prompt) | ||
| - `_meta` (object, optional) - Agent-specific metadata (e.g., message count, error status, tags) | ||
|
|
||
| #### Empty Result Example | ||
|
|
||
| When no sessions match the criteria: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "result": { | ||
| "sessions": [], | ||
| "hasMore": false | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Shiny future | ||
|
|
||
| Once this feature exists: | ||
|
|
||
| 1. **Clients can build session browsers** - Users can view a list of all their conversations, sorted by recency or relevance | ||
| 2. **Session switching becomes seamless** - Users can easily switch between ongoing conversations | ||
| 3. **Better resource management** - Clients can identify and clean up old or inactive sessions | ||
| 4. **Cross-device continuity** - Users could potentially access their sessions from different devices (if agent supports it) | ||
| 5. **Improved UX patterns**: | ||
| - "Recent conversations" sidebar | ||
| - Search through past sessions | ||
| - Archive/delete old sessions | ||
| - Resume interrupted work easily | ||
|
|
||
| Agents that implement this feature gain: | ||
|
|
||
| - Better visibility into active sessions | ||
| - Opportunity to implement session lifecycle policies | ||
| - Foundation for future features like session sharing or collaboration | ||
|
|
||
| ## Implementation details and plan | ||
|
|
||
| ### Phase 1: Core Protocol Changes | ||
|
|
||
| 1. **Update schema.json** to add: | ||
| - `session/list` method definition | ||
| - `ListSessionsRequest` and `ListSessionsResponse` types | ||
| - `SessionInfo` type | ||
| - `listSessions` capability flag | ||
|
|
||
| 2. **Update protocol documentation** in `/docs/protocol/session-setup.mdx`: | ||
| - Document the new endpoint | ||
| - Explain when to use it vs. maintaining client-side session tracking | ||
| - Provide examples of common use cases | ||
|
|
||
| ### Phase 2: Reference Implementation | ||
|
|
||
| 3. **Implement in Rust SDK** (`rust/agent.rs` and `rust/client.rs`): | ||
ahmedhesham6 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - Add `list_sessions` method to agent trait | ||
| - Provide default implementation (empty list) for agents without persistence | ||
| - Add client method to call `session/list` | ||
|
|
||
| 4. **Add to TypeScript SDKs** (if applicable): | ||
| - Update TypeScript types | ||
| - Add client methods | ||
|
|
||
| ### Phase 3: Example Implementation | ||
|
|
||
| 5. **Create example agent** that demonstrates: | ||
| - In-memory session registry | ||
| - Automatic title generation from first prompt | ||
| - Session lifecycle management (cleanup after N days) | ||
| - Pagination and filtering | ||
|
|
||
| ### Compatibility Considerations | ||
|
|
||
| - **Backward compatible**: Existing agents continue working without implementing this | ||
| - **Capability-based**: Clients check for `listSessions` capability before using | ||
| - **No breaking changes**: No modifications to existing endpoints | ||
|
|
||
| ### Security Considerations | ||
|
|
||
| - **Session isolation**: Agents must ensure sessions are only listed for the authenticated client | ||
| - **Resource limits**: Agents should enforce reasonable limits on pagination to prevent abuse | ||
|
|
||
| ## Frequently asked questions | ||
|
|
||
| ### What alternative approaches did you consider, and why did you settle on this one? | ||
|
|
||
| Several alternatives were considered: | ||
|
|
||
| 1. **Client-side session tracking only** - This is the current approach, but it has limitations: | ||
| - Doesn't work across devices | ||
| - Can get out of sync | ||
| - Adds complexity to every client implementation | ||
|
|
||
| 2. **Session events/notifications** - Push notifications when sessions are created/destroyed: | ||
| - More complex to implement | ||
| - Requires long-lived connections | ||
| - Still requires client-side state management | ||
| - Better suited as a future enhancement, not a replacement | ||
|
|
||
| 3. **File-based session manifest** - Agent writes session list to a file that clients read: | ||
| - Couples agent and client file system access | ||
| - Doesn't work for remote agents | ||
| - No standard format | ||
|
|
||
| The proposed RPC approach is: | ||
|
|
||
| - **Consistent with existing protocol design** - Uses same RPC patterns as other endpoints | ||
| - **Flexible** - Supports filtering, pagination, and agent-specific metadata | ||
| - **Optional** - Agents can opt-in based on their architecture | ||
| - **Simple** - Single request/response pattern, easy to implement and use | ||
|
|
||
| ### Why not make this mandatory for all agents? | ||
|
|
||
| Many agents may not have persistent storage or multi-session capabilities. Making this optional: | ||
ahmedhesham6 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - Allows simple, stateless agents to remain compliant | ||
| - Reduces implementation burden | ||
| - Lets agents evolve session management over time | ||
|
|
||
| ### How does this interact with `session/load`? | ||
|
|
||
| `session/load` remains the mechanism to actually restore a session. `session/list` is for discovery only: | ||
|
|
||
| 1. Client calls `session/list` to get available sessions | ||
| 2. User selects a session | ||
| 3. Client calls `session/load` with the chosen `sessionId` | ||
|
|
||
| Agents may support `session/list` without supporting `session/load` (e.g., for read-only session browsing). | ||
|
|
||
| ### Should we include session content in the list response? | ||
|
|
||
| No, for several reasons: | ||
|
|
||
| - **Performance** - Full conversation history could be large | ||
| - **Privacy** - Listing sessions might be less sensitive than exposing full content | ||
| - **Separation of concerns** - Use `session/load` to get full session content | ||
|
|
||
| ### What about session deletion? | ||
|
|
||
| Session deletion is intentionally left out of this RFD to keep scope focused. A future `session/delete` endpoint could be proposed separately. For now, agents can implement their own lifecycle policies. | ||
|
|
||
| ### How should pagination work for large session lists? | ||
|
|
||
| We use cursor-based pagination with an opaque continuation token: | ||
|
|
||
| - Request includes `limit` and optional `continuationToken` | ||
| - Response includes `hasMore` and `nextContinuationToken` when more data is available | ||
| - Clients should not assume anything about the token's contents; treat it as opaque | ||
| - The token MUST be a string; never send a raw JSON object as the token | ||
|
|
||
| Good request example: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "method": "session/list", | ||
| "params": { | ||
| "cwd": "/home/user/project", | ||
| "createdAfter": "2025-10-20T00:00:00Z", | ||
| "limit": 20, | ||
| "continuationToken": "offset:0", | ||
| "search": "auth" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Corresponding response example: | ||
|
|
||
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 2, | ||
| "result": { | ||
| "sessions": [ | ||
| /* ... */ | ||
| ], | ||
| "hasMore": true, | ||
| "nextContinuationToken": "offset:20" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Revision history | ||
|
|
||
| - **2025-10-29**: Initial draft proposal | ||
| - **2025-10-30**: Update to use `_meta` field for agent-specific metadata | ||
| - **2025-10-30**: Switch from offset-based to cursor-based pagination using continuation tokens | ||
| - **2025-10-30**: Rename `lastAccessedAt` to `updatedAt` for consistency | ||
| - **2025-10-30**: Remove `preview` field from SessionInfo (out of scope) | ||
| - **2025-10-30**: Remove session orphaning from problem statement | ||
| - **2025-10-30**: Replace `sortBy`/`sortOrder` with `search` parameter; remove `total` count from response | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of following MCP's pattern here?: https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/pagination
They call it
nextCursorand you use the presence of it for the same meaning as your hasMore boolean, which I think makes sense