omp-rpc-cli
v0.2.2
Published
Long-running Oh My Pi (omp) RPC session as a daemon, with a thin CLI to send tasks to it. Lets a driving agent (e.g. Claude Code) delegate work to a persistent omp session over omp's native RPC protocol.
Maintainers
Readme
omp-rpc
A long-running Oh My Pi (omp) session you can send
tasks to from the shell — a persistent second coding agent that a driver (you, or
Claude Code) can delegate work to and check back on.
omp --mode rpc speaks omp's native RPC protocol
(newline-delimited JSON over stdio). omp-rpc is the client: a small daemon
keeps one RPC session open, and a thin send command forwards tasks over a
Unix socket and streams the reply back. Because it's one session, context
accumulates across tasks — you can build on earlier work.
Previously
pi-acp, built on the generic Agent Client Protocol. It moved to omp's native RPC because RPC is a superset for driving omp — most importantly it allows switching models live, which ACP could not. Seedocs/LEARNINGS.md.
Using with Claude Code
First make sure omp is installed and authenticated (its
docs cover setup). Then:
Install the CLI — puts
omp-rpcon your PATH (needs Node ≥ 20):npm install -g omp-rpc-cli # or: pnpm add -g omp-rpc-cliAdd the skills to Claude Code — teaches it how to drive
omp-rpc:npx skills add kylebrodeur/omp-rpc-cli -gdelegating-to-omp-rpc— when and how to hand work off to it.using-omp-rpc— the daemon mechanics (commands, models, safety).
Now just ask Claude Code in plain language, e.g.:
"Start an omp-rpc session on this repo and delegate writing the migration script to it, then review what it produced."
Claude handles the start / send / stop lifecycle via the skills. You can
also drive it yourself with the CLI:
Use
omp-rpc start # boot the daemon (default model: glm, 1M ctx)
omp-rpc start --model kimi # coding-tuned kimi-k2.7-code
omp-rpc start --cwd ~/repo
omp-rpc send "Summarize what this repo does"
omp-rpc send "Now add a health check to server.js" # remembers the last turn
echo "review the diff" | omp-rpc send # reads stdin
omp-rpc send --quiet "..." # reply only (no thoughts/tools on stderr)
omp-rpc send --json "..." # raw {stopReason, usage}
omp-rpc model kimi # switch the model live — no restart
omp-rpc steer "skip the tests dir" # inject into the turn currently running
omp-rpc abort # interrupt the running turn
omp-rpc status # pid, model, session id, turn count, busy?
omp-rpc logs -n 60 # daemon log
omp-rpc stop # close session + clean up (see Safety)
omp-rpc stop --force # stop even mid-task; -y skips the prompt
omp-rpc models # built-in aliasesModel aliases
| alias | omp selector | context |
|-------|--------------|---------|
| glm (default) | ollama/glm-5.2:cloud | 1,000,000 |
| kimi | ollama/kimi-k2.7-code:cloud | 262,144 |
| deepseek | ollama/deepseek-v4-pro:cloud | 524,288 |
| gemma | ollama/gemma4:31b-cloud | 262,144 |
Any raw omp selector also works: --model anthropic/claude-opus-4-8, or live via
omp-rpc model anthropic/claude-opus-4-8. Confirm exact ids with
omp models list --json (the selector field). omp also exposes the same models
under an ollama-cloud/<id> provider; either works if authenticated.
How it works
omp-rpc send ──unix socket──▶ daemon ──stdio (omp RPC, JSON lines)──▶ omp --mode rpc-ui
(streams chunks back) (holds one session open) (the agent)- Model is live —
omp-rpc model <x>issues RPCset_modelon the open session, keeping the accumulated context. - Turns are steerable —
steerinjects into a running turn,abortcancels it, without tearing down the session. - Permissions auto-approve so the session runs unattended (headless) —
except commands the danger guard flags (see Safety). The daemon runs omp as
--mode rpc-ui --approval-mode writeprecisely so the guard has a veto point. - Runtime state lives in
~/.omp-rpc/(daemon.sock,daemon.pid,daemon.json,daemon.log); override withOMP_RPC_DIR(keep it short — see the socket-path note in the architecture reference).
Safety
Because the daemon approves tool use unattended, two guardrails apply:
- Dangerous-command guard (
src/danger.js). Each mutating tool surfaces an approvalselectunderrpc-ui; before answering "Approve", the command is matched against destructive patterns — recursive force-rmof root/home/cwd,mkfs,ddto a raw disk,shred/wipe, fork bombs,curl|wget … | sh, recursivechmod/chownon/,shutdown/reboot, destructivegit clean/reset. A match is answered "Deny" (logged asBLOCKED …) and the agent is told no; everything else is approved. It's a blast-radius net, not a sandbox — tune the patterns to taste. - Safe stop / cleanup.
omp-rpc stoprefuses to tear down a session that's mid-task (use--forceto override), lists exactly which runtime files it will remove, and never touches the session's working directory or anything the agent created there. It only deletesdaemon.sock/daemon.pid/daemon.json; the log is kept. In a terminal it asks to confirm; when scripted (no TTY) or with-yit proceeds without prompting.
Files
src/client.js— reusableRpcClient(importable omp-RPC-over-stdio client).src/daemon.js— holds the session, serves tasks over the socket.bin/omp-rpc.js— the CLI.src/danger.js— dangerous-command guard patterns.
Skills & docs
The two agent skills that drive this tool
(using-omp-rpc, delegating-to-omp-rpc) install via npx skills add
kylebrodeur/omp-rpc-cli — see Using with Claude Code.
Their source lives in skills/.
Design/protocol findings from building it: docs/LEARNINGS.md.
