An Oda process can serve a program of yours instead of a person: the automation profile speaks the Agent Client Protocol (ACP) over standard input and output, and your client manages persistent Oda sessions through it. Use this page when you build or debug such a client; Automation clients covers the serving profiles, and the Oda SDK overview and The Oda Remote API cover the other ways a program can drive Oda.
initialize. The answer names the protocol version the server speaks and the server's name and version. If your client requests a version the server does not support, the handshake still succeeds and the answer names the version the server speaks.authenticate. It succeeds immediately: the server requires no authentication and advertises no authentication methods.Standard output carries protocol messages only. Keep anything else, such as a logger, off that stream.
The initialize answer tells your client what the connection supports:
Your client drives the server with these calls:
| Call | What it does |
|---|---|
initialize | Opens the connection; names the protocol version and the server. |
authenticate | Succeeds immediately; no authentication is required. |
session/ | Creates a session. It needs an absolute working folder, and the MCP servers are declared here. An empty session is stored before the call returns. |
session/ | Sends one prompt. One prompt can be in flight per session, and several sessions can run over one connection. |
session/ ($/) | Cancels the prompt in flight; it settles as cancelled. With nothing in flight, it cancels autonomous work, and an unknown session id is a no-op. |
session/ | Lists the sessions that can be resumed, newest first, with a cursor for the next page. |
session/ | Reopens a stored session: it verifies the working folder, restores the latest model route and reconnects the declared MCP servers. |
session/ | Changes the Model or the Reasoning effort for the next turn. |
session/ | Closes the session. After a close, the session can be listed and resumed again. |
The server also sends messages of its own:
| Message | What it carries |
|---|---|
session/ | What the session is doing while it works, as the updates section describes. |
session/ | A request to allow or reject one action; see Permissions. |
session/ new and session/ resume need one (cwd must be an absolute path: <cwd>), and there is no second folder: additionalDirectories is not supported.a prompt is already in flight for this session; other sessions are not affected.session/ list leaves out sessions that are live in the process, subagent sessions, forked sessions, and sessions with a missing or relative folder. It returns newest first, with a cursor for the next page (at most 100 summaries per page by default), and answers a bad cursor with session/ list cursor is invalid.session is already active: <id>), not when it is not resumable (session is not resumable: <id>), and only from the same folder (session cwd does not match: <cwd>). A resume restores the latest model route and reconnects the MCP servers the request declares; earlier updates are not replayed.session close failed: <detail>). New work sent during a close is refused with session is closing: <id>.unknown session: <id>.empty prompt.image/ png, image/ jpeg, image/ webp or image/ gif, sent as canonical base64. Anything else is refused: image mimeType must be image/ png, image/ jpeg, image/ webp, or image/ gif and image data must be canonical base64.inline image prompts were not advertised by this connection or model "<model>" does not declare image input.mcpServers[N] transport <type> is not supported.mcp__<server>__<tool>; a server name that does not match the simple pattern of letters, digits, underscores and hyphens is normalised.mcpServers contains duplicate normalized name: <name>, mcpServers[N]. command must be an absolute path, <field> must be an absolute HTTP(S) URL.session/ update messages: agent thought chunks, assistant message chunks, tool calls that start and then complete or fail, and a usage update when the runtime can measure usage.| The turn ends | Your client is told |
|---|---|
| Completed | end_turn |
| At its token limit | max_tokens |
| Cancelled by your client | cancelled |
| Interrupted | cancelled |
| Blocked or failed | end_turn |
| Aborted by a hook or another owner | end_turn |
session/ set_config_option offers a Model selector and a Reasoning effort selector. The effort selector appears only when the exact model declares reasoning, and it includes a Provider default choice when the model declares no default effort.unknown model option: <value>, unknown reasoning effort for <provider>/ <model>: <value>, unknown session config option: <configId>.session/ load, session deletion, forks, additional directories, SSE and ACP transports for MCP, modes, commands, plans, terminals, client filesystem operations, and elicitation.initialize answer with?The protocol version the server speaks, the server's name and version, and what the connection supports: HTTP MCP, image prompts when the runtime has them, session close, list and resume, and no authentication methods. A request for a version the server does not support still gets an answer naming the server's version.
No. authenticate succeeds immediately, and the server advertises no authentication methods. The connection is trusted: the server adds no authentication of its own.
Yes. Sessions are independent of each other, and each runs one prompt at a time; a second prompt for the same session is refused until the first settles: a prompt is already in flight for this session.
Send session/ (or $/); the prompt settles as cancelled. With nothing in flight, the same call cancels autonomous work, and an unknown session id makes it a no-op.
Three common reasons: it is active elsewhere (session is already active: <id>), it is not a stored root session (session is not resumable: <id>), or the folder you gave differs from the session's (session cwd does not match: <cwd>). Subagent and forked sessions cannot be resumed.
session/ list?The list leaves out sessions that are live in the process, subagent sessions, forked sessions, and sessions with a missing or relative folder. Only sessions that can be resumed are listed, newest first, one page at a time.
Closing cancels the prompt in flight first, then lets updates and subagent work drain, flushes what is stored and disposes the session; a failure in that sequence is reported (session close failed: <detail>). New work during the close is refused with session is closing: <id>, and afterwards the session can still be listed and resumed.
PNG, JPEG, WebP or GIF, as canonical base64, and only when the connection advertised image support and the selected model accepts image input. Otherwise the prompt is refused with inline image prompts were not advertised by this connection or model "<model>" does not declare image input.
It applies to the next turn. The turn that is running keeps the model and effort it started with, so one turn never mixes routes. An unknown value is refused, for example unknown model option: <value>.
session/ messages: thought chunks, message chunks, tool calls and their completions, and a usage update when usage can be measured. The prompt then settles with a reason such as end_turn, max_tokens or cancelled.
session/ new fail?Most often because the working folder is not absolute (cwd must be an absolute path: <cwd>), because the request carried additional directories (additionalDirectories is not supported), or because one MCP declaration was invalid; declarations are checked before the session starts, so nothing is left behind.