OceanCode
Xcode and other ACP editors — oceancode acp
oceancode acp runs the Ocean engine as an Agent Client Protocol (ACP) agent on the process's
stdin/stdout. An ACP editor — Xcode 26.6 and later, Zed, JetBrains, Neovim — starts the binary itself
as a subprocess and talks newline-delimited JSON-RPC over the pipe. There is no URL, no port and no API
key for the editor: the editor is the client, the subprocess is the agent, and the editor asks you for
consent the first time it launches it.
It uses the same ACP backend and engine as the pager: the same model and credentials, permissions,
agents (build · plan · ask · debug), ledger and session store. The editor launches oceancode acp
directly; it does not route requests through the pager or require an HTTP server. ACP agent and
Ocean extension handlers live in crates/ocean-acp/; the pager is another client that embeds the
backend in-process (crates/ocean-cli/src/acp.rs, crates/ocean-acp/src/stdio.rs).
| Flag | Default | Meaning |
|---|---|---|
--db <path> | oceancode.db | the session store |
--directory <dir> | cwd | the working directory the engine starts in; the editor's session/new cwd wins per session |
--verbose, -v | off | trace every provider request/response to stderr (credentials masked) |
stdout is the wire. Every byte the process writes to stdout is one JSON-RPC message; the banner, diagnostics and tracing go to stderr. The process exits 0 when the editor closes stdin.
Xcode
Source: Apple, Setting up coding intelligence (opens in a new tab) — "To enable an agent that doesn't appear in Intelligence settings and supports the Agent Client Protocol (ACP), click Add an Agent under Agents, enter information in the next sheet, and click Add."
Find the binary's absolute path:
which oceancode(for example/Users/you/.local/bin/oceancode). Xcode needs the absolute path — no~, no relative path, and it validates nothing until first launch.Xcode › Settings › Intelligence, under Agents click Add an Agent… and fill the sheet:
Field Value Name Ocean CodeExecutable the path from step 1 Interpreter leave blank ( oceancodeis a native binary, not a script)Arguments acp— one argument per rowEnvironment Variables none needed (see Credentials) Click Add. Ocean Code now appears under Agents.
In the Intelligence sidebar click New Conversation and pick Ocean Code. The first time, Xcode asks whether to allow the agent to run — click Allow.
Do not confuse the Agents sheet with Chat › Add a Chat Provider: that door takes a URL (or a local
port) serving /v1/models and /v1/chat/completions plus an API key and gives a chat box without
tools. The coding agent lives behind the Agents sheet.
Credentials
Xcode starts the agent through your login shell (observed on Xcode 27: the agent's PATH carries
~/.local/bin, Homebrew and Xcode's Developer/usr/bin), so MCP servers started with npx or uvx
spawn fine — but do not rely on a shell export for the credential. Log in once from a terminal and
the stored credential is used by every Xcode session:
oceancode auth # API key or Claude Pro/Max subscription → auth.json in the data directory(01 · Getting started lists the locations.) A key in oceancode.json works
too. The sheet's Environment Variables rows also work, but Xcode writes their values into a plist under
~/Library/Developer/Xcode/CodingAssistant/ACP/ — prefer the stored login.
Xcode runs the agent with ~/Library/Developer/Xcode/CodingAssistant/<agent-id>/ as its working
directory, so that is where oceancode.db — the transcripts of your Xcode conversations — lands;
each session's own cwd is the project folder Xcode hands over in session/new.
Xcode's tools
When Xcode starts a session it hands the agent its own tools — build, test, run, SwiftUI previews,
documentation search, diagnostics — as an MCP server (xcode-tools) in session/new. The engine
registers every server the editor supplies before the session is created
(crates/ocean-acp/src/mcp_servers.rs:19, crates/ocean-acp/src/agent.rs:158), so the first step
already offers them; the tools are named xcode-tools_<Tool> in the registry. Nothing to configure:
"build the project" in an Xcode conversation uses Xcode's build, and Xcode asks before the first
build/test tool runs, as it does for every agent.
For a session you start outside Xcode — the pager, oceancode run — the same tools come from
Xcode's MCP bridge: in Intelligence settings turn on Allow external agents to use Xcode tools, then
oceancode mcp add xcode --command xcrun --arg mcpbridgewith the project open in Xcode (11 · MCP; Apple: Giving external agents access to Xcode (opens in a new tab)).
Permissions and questions
A tool call that needs approval becomes an ACP session/request_permission with allow once,
allow always, and reject choices. The shared outbound driver resolves replies and rejects them on
cancellation or disconnect (crates/ocean-acp/src/outbound.rs, permission.rs). The engine's
questionnaire tool has no equivalent in base ACP. A client that advertises Ocean's questionnaire
extension receives the structured question request; a generic ACP client receives the question
text in the transcript and the blocked tool is rejected so the model can continue conversationally.
This fallback avoids claiming that an unsupported form was shown. Xcode's actual questionnaire
behavior has not yet been validated in its UI. Always-approve and the Shift+Tab agent ring are
reachable through the editor's mode picker where it has one; Xcode exposes the session modes it is
given (build · plan · ask · debug).
Verify by hand
Two requests on stdin, one reply or notification per line on stdout, exit 0 at EOF — no Xcode needed. Hold stdin open for a moment: the host returns as soon as the pipe closes, and a request still in flight at that instant is dropped (an editor keeps the pipe open for the life of the conversation).
{ printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}' \
'{"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"'"$PWD"'","mcpServers":[]}}'
sleep 3
} | oceancode acp 2>/dev/nullThe first line answers with agentCapabilities (loadSession, mcpCapabilities.http/sse), the last
with a sessionId plus the model and mode lists; between them an _ocean/sessions/changed
notification — an Ocean extension the pager uses and a plain ACP client ignores. Add a
session/prompt line with that id to see the turn stream as session/update notifications. This is
what crates/ocean-cli/tests/acp_mode.rs pins on every build.
See also
- 19 · Ocean pager — the terminal UI on the same engine.
- 07 · Headless and server —
serve,run,goal,workflow. - 12 · Permissions and sandbox — the rules behind every approval prompt.