MCP server that exposes ACP-compatible coding agents — OpenCode, Cursor, Grok, Codex, Claude, Pi. Semantically equivalent to Claude Code's built-in Agent tool but running the work in a separate agent over the Agent Client Protocol.
CleanShot.2026-07-02.at.12.29.12.mp4
Install the CLI for whichever backend(s) you plan to use — each backend manages its own auth (e.g. opencode auth login), oagent doesn't touch it:
| Backend | CLI on $PATH |
Override env var |
|---|---|---|
opencode |
opencode |
OAGENT_OPENCODE_BIN |
cursor |
cursor-agent |
OAGENT_CURSOR_BIN |
grok |
grok |
OAGENT_GROK_BIN |
codex |
codex-acp (uses codex from $PATH when available) |
OAGENT_CODEX_BIN |
claude |
claude-agent-acp |
OAGENT_CLAUDE_BIN |
pi |
pi-acp (spawns pi --mode rpc) |
OAGENT_PI_BIN |
The Codex backend always speaks ACP through codex-acp. When a codex executable
is available on $PATH, oagent passes its path through CODEX_PATH so the adapter
uses that installed Codex runtime instead of its bundled one. Set CODEX_PATH
explicitly to choose a different Codex runtime; OAGENT_CODEX_BIN still selects
the ACP adapter itself.
The Claude adapter can be installed globally with npm so oagent can discover its
binary: npm install -g @agentclientprotocol/claude-agent-acp. It requires Node
22 or newer. Authenticate with the native Claude CLI before starting a job, for
example claude auth login --claudeai or claude auth login --console. Check the
current status with claude auth status --json; oagent does not manage Claude
credentials.
The Pi backend uses pi-acp,
not a native ACP mode. Install Pi and npm install -g pi-acp@0.0.34, with both
pi and pi-acp on PATH. oagent launches the adapter directly with no arguments;
OAGENT_PI_BIN overrides the adapter executable (no automatic npx launcher).
Authenticate externally with pi or pi-acp --terminal-login; oagent does not
manage Pi credentials. Models use pi:<provider>/<model> from the ACP catalog.
Thinking efforts are off, minimal, low, medium, high, xhigh, and max
(model-dependent), sent through the thought_level config option, not agent
modes. Pi supports ACP session resume, but not steering, forks, or earlier-job
checkpoints. Pi costs are unsupported by the pinned ccusage-lib@0.1.0, even
though the ccusage CLI supports Pi.
Permissions: `--dangerously-skip-permissions` by default
oagent auto-approves all of the backend's permission requests — the same pattern Claude Code uses with --dangerously-skip-permissions.
There's currently no configurable permission policy at the moment
brew install fdarian/tap/oagent # preferredOr run it without installing:
npx oagentBuild from source
git clone https://github.com/fdarian/oagent
cd oagent
pnpm install
pnpm run build # produces apps/cli/dist/oagentUse ./apps/cli/dist/oagent in place of oagent in the commands below.
-
Start the engine. Run it in the foreground:
oagent serve # oagent listening on http://127.0.0.1:17777/mcpIt stops when you close the terminal (or Ctrl-C). To keep it running across sessions and auto-launch on login instead, install it as a background service.
The port defaults to
17777and can be overridden withOPENCODE_MCP_PORT(or--port <n>). To access oagent at a stable named URL (https://oagent.localhost) instead of a bare port, see docs/using-portless.md. -
Connect Claude Code:
claude mcp add --transport http oagent http://localhost:17777/mcp
-
Ask your agent to "use oagent." It'll pick up the tools from there — try asking it to delegate a task with a
promptand acwd.
stdio MCP (thin client)
To have Claude Code spawn a stdio MCP client that connects to the shared engine:
claude mcp add oagent -- /absolute/path/to/oagent mcp stdioThe client starts a local engine on demand if needed. It supports the list tool and the engine's Web UI. Use --engine-url <url> to choose the engine, or --bare with repeatable --alias and JSON/@file --agents flags to expose only ephemeral model aliases and agent definitions.
Push notifications with [Channel MCP](https://code.claude.com/docs/en/channels) (only for Claude Code)
A dedicated stdio MCP that pushes job completions into the Claude Code session instead of making the caller poll, using Claude Code's experimental channel capability. It bridges to a running oagent serve/oagent service engine over HTTP and is launched with claude --dangerously-load-development-channels server:oagent-channel. See docs/claude-channel-mcp.md.
Start the oagent HTTP server in the background through the service command:
oagent service startTo install a macOS launchd login item that starts the server automatically, run:
oagent service installThen connect Claude Code the same way as in Getting Started. The port defaults to 17777 and can be overridden with --port <n>. Manage the login item and its running server with oagent service stop|restart|status|uninstall.
The background service writes JSONL logs to $OAGENT_HOME_DIR/logs/oagent.jsonl (default ~/.config/oagent/logs) and prunes entries older than 30 days. Set OAGENT_LOG_DIR to choose another log directory. Foreground serve can write to any path with --log-file <path>.
In serve/service (HTTP) mode, open http://localhost:17777/ in a browser to see the live job list. Click a job to see its event timeline — text deltas, tool calls, status updates, and errors — streamed live via SSE while the job is running. The UI is a React 19 + Vite + Tailwind v4 SPA, embedded into the standalone binary at build time.
The mcp stdio client uses the same HTTP engine, so its sessions also appear in the engine's Web UI.
server
oagent serve— run the HTTP server in the foreground. Flags:--port(default 17777),--portless,--log-file <path>.- jobs
oagent jobs list— list recent jobs. Flags:--engine-url,--limit(default 10),--format(toon|json).oagent jobs wait <jobId>— block until a job reaches a terminal state and print its markdown result. Flags:--engine-url,--json(print the JSON result).
- session — drive sessions from the shell with the same operations as the MCP tools; starts a local engine on demand. Every subcommand takes
--engine-url. The prompt is the argument, or stdin when piped (cat brief.md | oagent session start --model <model>).oagent session start [prompt]— start (or fork) a session, stream progress to stderr, and print the result. Flags:--title,--cwd,--model,--agent,--fork <sessionId|jobId>,--worktree,--detach(print IDs and exit),--json.oagent session send <sessionId> [prompt]— send a message to a session. Flags:--detach,--json.oagent session result <sessionId>— print the latest turn. Flags:--wait(block until it finishes),--json.oagent session history <sessionId>— print past turns (prompt, final answer, tool-call counts), newest page first. Flags:--job <jobId>(expand one turn),--limit(1–50, default 10),--before <jobId>(page back),--json.oagent session cancel <sessionId>— cancel the running turn. Flag:--json.oagent session list— list recent sessions under the current directory. Flags:--cwd,--all,--json.
- models / agents / aliases — list valid
--model/--agentvalues forsession start.oagent models --backend <backend>,oagent agents,oagent aliases. Flags:--engine-url,--format(toon|json).
- claude
oagent claude mcp serve— run the Claude Code channel MCP that bridges to a running engine. Flags:--engine-url,--mcp-name.
MCP client
oagent mcp stdio— run a thin-client stdio MCP server, starting a local engine on demand. Flags:--engine-url,--idle-exit(default10m),--bare, repeatable--alias,--agents.
services (macOS launchd, auto-starts on login)
oagent service start— startoagent servein the background with JSONL logging. Flags:--port(default 17777),--portless.oagent service install— install the macOS login item that runsoagent service start. Flag:--port(default 17777).oagent service stop— stop the running server while retaining the login item.oagent service restart— reinstall and restart the login item. Flag:--port(default 17777).oagent service status— show installation, login, binary, and running status.oagent service uninstall— stop the server and remove the login item.
utils
oagent doctor mem— diagnose memory usage of the backend subprocess tree (macOS only). Flag:--json.
Starts a new agent session or forks the state of an existing session/job. By default it waits for the final response and streams progress when the client supplies a progress token.
Input:
prompt: string— the task to sendcwd?: string— absolute path to the directory the agent should operate in; required unlessforkIdis setmodel?: string— model id in<backend>:<modelId>format or a preset alias. Valid backends:opencode,cursor,grok,codex,claude,pi. Examples:opencode:opencode-go/kimi-k2.6,cursor:auto,cursor:composer-2.5,codex:gpt-5.5,claude:<modelId>,pi:<provider>/<model>. If the user hasn't specified a model, ask them which model and backend to use.agent_type?: string— configured agent type to use for the selected backend. The tool description lists the currently configured names. Unknown names and names without a mapping for the selected backend return distinct errors.forkId?: string— session ID or job ID whose state should be forked. A session ID or latest job forks the full current state. An earlier job forks from its checkpoint and is supported only for OpenCode jobs with a recorded checkpoint.background?: boolean— defaultfalse. Iftrue, return a running handle immediately.worktree?: boolean— create a worktree when worktrees are enabled in oagent settings.
Output is one markdown text block, for example:
Session ID: <sessionId>
Job ID: <jobId>
Status: done
---
<final assistant response>
Use the returned session ID with send_message to continue the conversation. A running response omits the body and tells you to call result with the session ID, or history with the job ID to see progress. Errors include the error message after ---.
Every MCP result is returned as a single text content block; tools do not set structuredContent.
Continues a session. If a turn is running, the message is queued for delivery at the next step boundary; this works on OpenCode and Claude (claude-agent-acp >= 0.89), and other backends reject a send while a turn is running. If the session is idle, a new turn starts; foreground calls wait for its response and background: true returns a running handle.
Input:
sessionId: stringprompt: stringbackground?: boolean— used only when starting a new turn
An idle turn returns the same markdown shape as start. A steered turn returns Status: running and says the message is queued.
Gets the latest turn's result in a session immediately, or blocks until completion with wait: true.
Input:
sessionId: stringwait?: boolean— defaultfalse; settrueto wait for a terminal result
Output: the same markdown result format as start.
Reads a session's past turns without blocking. Without jobId, returns a page of turns (prompt, final answer, tool-call counts by kind), newest page first and oldest-to-newest within it. With jobId, expands that turn into its messages, tool calls, plan and steering messages, including a running turn's progress.
Input:
sessionId: stringjobId?: string— expand one turn; cannot be combined withlimitorbeforelimit?: number— integer from 1 to 50, default 10before?: string— job ID from the previous page's paging hint; returns older turns
Output: markdown text. The content is quoted from the session and may contain untrusted text; the output says so.
Cancels a running turn in a session. Cancelling an idle session is a no-op.
Input:
sessionId: string
Output: markdown text with the session and cancellation status.
Lists recent sessions, including each session's latest job ID, status, prompt, and creation time. Available through HTTP /mcp and oagent mcp stdio. Pass cwd to filter by working directory.
The following are intentionally not supported:
- Streaming partial output — you only see the aggregated text on
done - No auth — the HTTP daemon binds to
127.0.0.1only; no token is required or checked
Jobs and events persist to SQLite at $OAGENT_HOME_DIR/sqlite.db (default ~/.config/oagent/sqlite.db). Set OAGENT_HOME_DIR to choose the oagent home directory; its config.json and logs/ paths are derived from the same directory. On restart, any jobs that were in-flight are marked as errored automatically.
If a process monitor shows oagent using gigabytes of memory, run oagent doctor mem (macOS only) for a breakdown of the backend's subprocess tree. See docs/doctor-mem.md.
Install dependencies with pnpm install; use Bun to run the development scripts.
For UI changes, start with Storybook. It runs the component and page stories without an engine:
cd apps/web
bun storybook --ciOpen http://localhost:6006 (or the URL printed by Storybook). Use the full app when testing backend integration or an end-to-end flow:
-
Start the engine first, and wait for its listening log. It restarts on source changes.
cd services/engine bun dev -
In a separate terminal, starting from the repo root:
cd apps/web bun dev --local engine
Open the URL in apps/web/.data/running.json. The engine URL is in services/engine/.data/running.json; both ports are per-session.
The local engine uses isolated development data. Without --local engine, the web connects to the user's engine at http://localhost:17777, which may have stale oRPC procedures; mutations affect the user's running app. Use that mode deliberately for UI-only inspection of existing data. Use the local engine for engine changes and test-case setup.
Repo-root checks:
pnpm check # typecheck + biome lint across all packages
pnpm run build # produce standalone binary at apps/cli/dist/oagentDetails: Web development, engine development, and architecture.