Summary
SessionInfo.title is the only title channel in the protocol, but it is agent-owned, optional, and has no defined semantics. In practice, agents fill it with an arbitrary user message (often the last or a middle one, not the first), or even with machine-generated text. Clients have no protocol-level way to set or correct a session title, so a client that wants reliable titles today must implement per-backend transcript parsing outside the protocol.
What the protocol offers today (audited)
Audited against schema v1.20.0 (stable + unstable), v2.0.0-alpha.2, and the Go SDK's bundled schema:
| Surface |
Direction |
Notes |
SessionInfo.title |
agent → client |
Doc: "Human-readable title for the session" — that is the entire spec. No semantics, no derivation rule. |
SessionInfoUpdate.title (notification) |
agent → client |
Lets the agent push a better title; the client cannot request or set one. |
session/new params |
client → agent |
No title field to seed a title. |
session/rename (or similar) |
— |
Does not exist in any current schema version. |
Observed behavior (claude-agent-acp adapter)
From the adapter source (session/list handler):
sessions.push({
sessionId: session.sessionId,
title: sanitizeTitle(session.summary), // auto-generated by the agent SDK
...
})
and at turn end it pushes updates preferring a user-set name:
const rawTitle = info?.customTitle ?? info.summary;
So the agent side already maintains two distinct notions — a user-set name and an auto-generated one — but only the auto-generated one reaches session/list, and only the agent can act.
Measured distribution (one machine, 22 sessions via session/list)
| Reported title equals |
Count |
| the last user message |
8 |
| some middle user message |
10 |
| the first user message |
1 |
| first = last (single-message session) |
2 |
| a user-set/custom title |
1 |
Synthetic illustration of the failure: a session whose first message is "How do I configure the backup schedule?" is listed as "run the tests again" (its last message). A client showing "recent sessions" surfaces text the user never associates with that session's intent.
Machine-generated titles
Some clients inject rule blocks or context headers into user turns (system-prompt blocks, compaction headers such as continuation summaries). When the agent derives the title from such a turn, the reported title is machine text, e.g. a truncated system-prompt block or a "This session is being continued…" header — worse than useless in a session list.
Why this matters for clients
In ClawBench (mobile AI-workstation client speaking ACP to multiple CLIs) we had to solve this entirely client-side: read each backend's on-disk session transcript, extract a user-set title record if present, else the first human message with machine prefixes stripped, and only fall back to the agent-reported title. That is one bespoke parser per backend — exactly the kind of thing a protocol field with defined semantics should make unnecessary.
Proposals (for discussion)
- Add
session/rename (client → agent): set/correct the display title for a session; agents MAY persist it (the claude adapter already persists a user /rename as customTitle, so the concept exists on the agent side). Gate behind a capability like the existing session.fork pattern.
- Define
SessionInfo.title semantics, e.g. "SHOULD be derived from the first user message, or a user-set name when one exists", so clients can rely on it instead of re-deriving.
- Optional
title param on session/new so a client can seed the title at creation.
(1) + (2) together would let clients display trustworthy titles and keep them consistent across devices/clients.
Environment
- audited schemas: v1.20.0 stable/unstable, v2.0.0-alpha.2
- observed via:
@agentclientprotocol/claude-agent-acp (npx, current) + coder/acp-go-sdk v0.13.5
Summary
SessionInfo.titleis the only title channel in the protocol, but it is agent-owned, optional, and has no defined semantics. In practice, agents fill it with an arbitrary user message (often the last or a middle one, not the first), or even with machine-generated text. Clients have no protocol-level way to set or correct a session title, so a client that wants reliable titles today must implement per-backend transcript parsing outside the protocol.What the protocol offers today (audited)
Audited against schema v1.20.0 (stable + unstable), v2.0.0-alpha.2, and the Go SDK's bundled schema:
SessionInfo.titleSessionInfoUpdate.title(notification)session/newparamstitlefield to seed a title.session/rename(or similar)Observed behavior (claude-agent-acp adapter)
From the adapter source (
session/listhandler):and at turn end it pushes updates preferring a user-set name:
So the agent side already maintains two distinct notions — a user-set name and an auto-generated one — but only the auto-generated one reaches
session/list, and only the agent can act.Measured distribution (one machine, 22 sessions via
session/list)Synthetic illustration of the failure: a session whose first message is "How do I configure the backup schedule?" is listed as "run the tests again" (its last message). A client showing "recent sessions" surfaces text the user never associates with that session's intent.
Machine-generated titles
Some clients inject rule blocks or context headers into user turns (system-prompt blocks, compaction headers such as continuation summaries). When the agent derives the title from such a turn, the reported title is machine text, e.g. a truncated system-prompt block or a "This session is being continued…" header — worse than useless in a session list.
Why this matters for clients
In ClawBench (mobile AI-workstation client speaking ACP to multiple CLIs) we had to solve this entirely client-side: read each backend's on-disk session transcript, extract a user-set title record if present, else the first human message with machine prefixes stripped, and only fall back to the agent-reported title. That is one bespoke parser per backend — exactly the kind of thing a protocol field with defined semantics should make unnecessary.
Proposals (for discussion)
session/rename(client → agent): set/correct the display title for a session; agents MAY persist it (the claude adapter already persists a user/renameascustomTitle, so the concept exists on the agent side). Gate behind a capability like the existingsession.forkpattern.SessionInfo.titlesemantics, e.g. "SHOULD be derived from the first user message, or a user-set name when one exists", so clients can rely on it instead of re-deriving.titleparam onsession/newso a client can seed the title at creation.(1) + (2) together would let clients display trustworthy titles and keep them consistent across devices/clients.
Environment
@agentclientprotocol/claude-agent-acp(npx, current) +coder/acp-go-sdkv0.13.5