Buttons for permission requests, question options and plans. Reply to a “finished” message to send that agent a follow-up. Messages are edited when a request is answered anywhere else.
Steer your coding agents
from one place.
Pilothouse is one inbox for Claude Code, Codex, OpenCode and Grok Build. It checks your rules before every tool call and brings what needs you — approvals, questions, plans and replies — to the terminal or your phone. Your rules live outside any one agent, so they work the same whichever vendor you use. Stay in control without staying at the desk.
pilothouse demo30 seconds, no agents touched: the real web app with pretend agents asking for things, in a temp folder that’s deleted when you quit. How the demo works
curl -fsSL https://pilothouse.dev/install.sh | shbrew install sabr-software/tap/pilothousethen run pilothouse setup
Animation: Claude Code is working in a terminal. You step away from your desk, so when the agent asks to run git push origin main, Pilothouse checks your rules, holds the request and sends it to your paired phone. You press and hold Allow, the phone signs the decision, and the agent continues in the terminal.
- Claude Code
- Codex
- OpenCode
- Grok Build
- tmux
- herdr
- Ghostty
- iTerm2
- VS Code
- SSH sessions
- macOS
- Linux
Know when the next agent lands.
Occasional updates when new agents, the relay or team features ship. No product spam.
Three commands. Then keep working the way you do.
Pilothouse runs a small daemon per machine. Agents report to it through their hooks; you answer from wherever you are. There is nothing to sign up for.
- 01
Install and set up
Installs the Claude Code, Codex and Grok Build hooks plus the OpenCode plugin (merged, backed up) and starts the user service.
$ pilothouse setup ✓ hooks installed: claude, codex, grok, opencode ✓ service running (launchd) - 02
Pair your phone
Expose the web app on your tailnet over HTTPS, then scan a QR code. The phone gets its own signing key.
$ pilothouse remote tailscale ✓ https://mac.tailnet.ts.net $ pilothouse pair # shows a QR - 03
Work, or walk away
Start agents through Pilothouse so you can reply from your phone. At the desk, nothing changes. Step away and requests come to you. Your rules run either way.
$ pilothouse run claude # or codex / opencode $ pilothouse # the inbox ● 1 needs you · 3 working
Your policy runs first. Every single time.
Most tools only see a request once the agent decides to ask. Pilothouse checks every tool call atPreToolUse, so “never force-push” holds even when the agent’s own settings would have allowed it. Write rules in YAML, add a CEL condition when a glob isn’t enough.
version: 1
rules:
- name: no-force-push
match: { kind: shell, command: "git push*" }
when: 'command.matches("(--force|-f)\\b")'
action: deny
message: Force-push is blocked. Open a PR.
- name: ask-before-push-main
match: { kind: shell, command: "git push*main*" }
action: ask
- name: no-env-files
match: { path: "**/.env*" }
action: deny
message: Secrets stay out of the context.
- name: tests-are-fine
match: { kind: shell, command: "{npm,pnpm} test*" }
action: allow- Bashnpm testallowtests-are-fineruns, no prompt
- Read.env.productiondenyno-env-filesagent gets your message
- Bashgit push --force origin featdenyno-force-pushblocked before it runs
- Bashgit push origin mainaskask-before-push-mainrouted to you
- Editsrc/routes/login.tsno opinionno rule matchedagent’s own settings decide
Any deny wins, then ask, then allow.
- Two checkpoints. Rules decide before the tool runs; people are asked only when the agent would ask.
- Repo rules need your trust. A repo’s
.pilothouse/policy.yamlcan only add stricter rules until you trust it. - Test before you ship.
pilothouse policy replay --since 7dshows what your new rules would have changed.
Skip the prompts. Keep the guardrails.
When you want an agent to keep moving, turn on guarded autopilot: routine reads, in-repo edits and tests run without a prompt; pushes, deploys, secrets and sudo ask; destructive commands are blocked. It is a preset, not a blank cheque.
| The agent wants to… | --dangerously-skip-permissions | Guarded autopilot |
|---|---|---|
npm test | runs | runs, no prompt |
Edit src/billing/invoice.ts | runs | runs, no prompt |
git status && git diff | runs | runs, no prompt |
sudo npm i -g some-cli | runs | asks you |
git push origin main | runs | asks you |
cat .env.production | runs | asks you |
vercel --prod | runs | asks you |
git push --force origin main | runs | blocked |
git reset --hard | runs | blocked |
rm -rf ~ | runs | blocked |
psql -c "DROP TABLE users" | runs | blocked |
On Codex, only deny rules take effect as written. Its pre-tool hook can block a call but cannot skip Codex’s own prompt, so guarded autopilot means “never destructive; pushes, deploys, secrets and sudo only by you.”Presets and one-tap rules →
It knows when you’re at the keyboard.
A tool that grabs every prompt and sends it to your phone makes the terminal worse. Pilothouse looks at whether you’re actually at the machine. At your desk, it gets out of the way. Away, it holds the request and finds you.
How presence worksAt your desk: Pilothouse steps aside and the agent shows its own permission dialog, exactly as it would without Pilothouse. Nothing freezes. If you leave it unanswered for a while, you get a desktop notification.
Away (idle): the request is held and pushed to your paired devices. The first answer wins. Come back to the keyboard and it's handed back to the terminal; if nobody answers before the hold limit, the agent's own dialog takes over.
Answer, reply and steer from anywhere.
Permission requests, question options, plans and finished turns all find you. Telegram works without Tailscale; ntfy and Web Push keep the buttons. Decisions from the paired web app are signed by the device.
First-class in setup. Allow / Deny on permission requests with remote access; questions and plans open the web app. Cleared from the phone once answered (ntfy 2.16+).
Allow / Deny right on the notification on Android and desktop, signed by the device. Answered somewhere else? The notification is replaced, not left with stale buttons.
Watch. Decide. Keep going.
Pilothouse sits between your agents and you. Your agents' sessions land in one inbox, your rules run before every tool call, and only what needs a person reaches your terminal or phone — then the agent keeps working.
Every session, in one inbox.
Run pilothouse for a live list of Claude Code, Codex, OpenCode and Grok Build sessions: who is working, who is waiting, and who needs you. No hunting for the right tab.
- A report for each Claude Code, Codex and OpenCode session: what you asked, what it says, and the proof: tests, lint and build it ran, files changed, the commit.
- Token use and estimated cost for Claude Code and Codex, per session, day and repo.
- Several computers? Link them and see every machine's sessions in one app.
Your rules first. You only when it matters.
Rules run before every tool call: block git push --force, ask before pushing tomain, keep agents out of .env. When an agent needs a person, the request finds you with the command, the diff and the rule that fired.
- Allow once, allow for the session, or deny with a message — from the terminal, phone or Telegram.
- Claude Code, Codex and OpenCode approvals can reach your phone when you're away; Grok Build's ask stays at the desk.
- Questions and plans follow the same routing where the agent exposes them.
Close the terminal. Keep the work.
pilothouse run keeps an agent in a holder process, so you can close the terminal and re-attach later. Start a task in its own worktree and branch, then review and ship it from the phone.
task newcreates a branch, worktree and agent;task done --propens the PR.- Reply to Claude Code, OpenCode and wrapped sessions instead of restarting them.
- Ask why
pilothouse explainshows the evidence and the rule behind a blocked session. - Test a rule
policy testtries a hypothetical call;replay --since 7dshows what your rules would have done. - One binary
macOS and Linux, amd64 and arm64. Runs as a launchd or systemd user service, headless included.
- No telemetry
Sessions, prompts and paths stay on your machine. The only call home is an update check you can disable.
- Try it first
pilothouse demoruns the real app with pretend agents in a temp directory.
Real screens, not mockups.
Captured from pilothouse demo, the same web app you pair. Dark and light follow your device, or switch them in the top bar; the phone layout is the installable PWA.






pilothouse demoApprovals you can trust from a phone.
A remote “Allow” is powerful, so it is treated that way: signed by a device key, checked by your own daemon, and never routed through someone else’s server.
Web app approvals are signed
Pairing creates a P-256 key inside the phone’s browser that can’t be exported. Each decision from the paired app is signed with it, time-stamped and single-use.
Agents can’t approve themselves
Local decisions only come through a Unix socket, and callers descended from an agent process are refused. A built-in rule asks you before an agent touches Pilothouse itself.
No open ports, no account
The web app listens on 127.0.0.1. Your phone reaches it through Tailscale Serve over HTTPS. There is no Pilothouse server in the middle.
Honest framing: Pilothouse runs as you. These protections are defense in depth that make accidental and casual self-approval hard; they are not a sandbox. Read the full security model →
Neutral, local, and opinionated about rules.
There are good tools here. herdr is a great multiplexer; Happy has native apps; Claude Code ships its own remote control. Pilothouse is the vendor-neutral layer that adds policy and works alongside all of them.
| Feature | Pilothouse | herdr | Happy | Claude Remote Control |
|---|---|---|---|---|
| License | Yes: Apache-2.0 | Yes: Apache-2.0 | Yes: MIT | No: Proprietary |
| Agents | Claude Code, Codex, OpenCode, Grok Build | 22 agent CLIs detected | Claude, Codex, Grok; harnesses for OpenCode and ACP agents | Claude Code only |
| Keep your terminal and how you launch agents | Yes: Yes — official hooks (OpenCode: a plugin; Grok Build: personal hooks); any terminal, even inside tmux or herdr | Partly: Agents run inside herdr panes | Partly: Agents start in Happy Desktop, or via happy claude / happy codex | Yes: Yes — /rc in a running session, or --rc |
| Your rules before every tool call | Yes: YAML + CEL, one-tap rules from approval cards, presets; any deny wins | No: No documented policy engine | Partly: Permission modes, a sandbox file and an AI reviewer; no per-call rules you write | Partly: Claude Code’s own allow/ask/deny rules and permission modes |
| Approve from your phone | Yes: Yes — each device signs its decisions | Partly: No app: answer in the pane over SSH, or with community apps | Yes: Yes — native apps | Yes: Yes — prompts stay open until you answer |
| Presence-aware (no phone buzz while you’re at the desk) | Yes: Yes — OS idle time; manual override | Partly: Desktop popups skip the active tab; no phone push | No: Not documented | Yes: Skips push while you type in or focus the terminal |
| Works without an account | Yes: No account | Yes: No account | Partly: Key-based account (your phone holds the key) | No: Needs a paid claude.ai plan; not API keys or Bedrock |
Claude Code, Codex, OpenCode and Grok Build. Same rules.
Official hooks for Claude Code, Codex and Grok Build; a small plugin for OpenCode. The differences that matter are in the table — including what each agent can answer from your phone.
| Feature | Claude Code | Codex | OpenCode | Grok Build |
|---|---|---|---|---|
| Connects through | Official hooks | Official hooks | A small plugin | Official hooks |
| Sessions in the inbox | ||||
| Deny rules before every tool call | ||||
| Ask rules | Its own prompt | Denied with a note: Codex can’t prompt from a hook | Held for you in Pilothouse, at the desk too | Its own prompt, at the desk only |
| Approvals from your phone | No permission-request hook | |||
| Questions from anywhere | Questions and plans | Shown; answered in its terminal | Questions (no plan mode) | Answer in its terminal |
| Replies from your phone | Claude Code sessions, or under pilothouse run | Under pilothouse run | Through the plugin | Under pilothouse run |
| Activity feed, usage and cost | Activity and session cost; global usage not yet | Activity read; usage not yet |
Do I have to switch terminals or start my agents differently?
No. Pilothouse installs hooks into Claude Code, Codex and Grok Build and a small plugin into OpenCode, so a claude, codex, opencode or grok started from any terminal or IDE shows up in your inbox — Ghostty, iTerm2, VS Code, tmux, even inside herdr. Grok only loads personal hooks in trusted folders, so trust each project once with /hooks-trust. Starting agents with pilothouse run claude is recommended if you reply from your phone: replies are typed into the agent’s terminal, so Claude Code doesn’t hold them. It also adds interrupt, a live terminal and detach/re-attach.
Why not just use my agent’s built-in remote control?
Built-in remote access, like Claude Code’s Remote Control, covers one vendor’s agent. Pilothouse is one inbox for Claude Code, Codex, OpenCode and Grok Build, and your rules sit outside all of them, so the same policy applies whichever agent your team runs. It is open source, needs no account, sends nothing about your work, and every answer from your phone is signed by that device’s key. What each agent supports differs; the support table has the details, and the comparison goes further.
Which agents are supported?
Claude Code, Codex, OpenCode and Grok Build in 0.2. Claude Code gets the full set: rules before every tool call, questions and plans, and remote approvals. Codex follows what its own hooks expose (trust new hooks once with /hooks). OpenCode runs through a small plugin. Grok Build connects through its personal hooks and keeps approvals and questions in its own terminal. The support table lists exactly what works; GitHub Copilot CLI is next.
How does my phone reach my laptop? Do I open a port?
No ports. Pilothouse serves its web app on 127.0.0.1 only. pilothouse remote tailscale uses Tailscale Serve to give it an HTTPS address that only devices on your tailnet can reach. You pair a phone by scanning a QR code.
What if I don’t use Tailscale?
You still get the terminal inbox, two-way Telegram (no Tailscale needed) and notifications through ntfy, Slack, Discord or your desktop. Answering in the paired web app needs a route to your machine; Telegram does not. An end-to-end encrypted relay for the web app is on the roadmap.
Will my phone buzz while I’m sitting at my desk?
No. Pilothouse checks whether you’re active at the machine. At the desk, it steps aside and the agent shows its own dialog right away. Only when you’re idle does it hold the request and send it to your devices. You can force either mode with pilothouse here, pilothouse away or pilothouse auto.
What happens if the Pilothouse daemon is down?
Agents carry on as if Pilothouse weren’t installed. The hook shim gives up within two seconds and returns “no opinion”. If you’d rather block tool calls when Pilothouse isn’t running, set approvals.fail_closed: true.
Can an agent approve its own request?
Pilothouse makes that hard on purpose. Local decisions are only accepted on a Unix socket and are refused if any ancestor of the calling process is an agent. Answers from the paired web app must be signed by that device’s key; Telegram answers are bound to your private chat instead. A built-in rule asks a person before an agent runs Pilothouse admin commands or edits Pilothouse’s files. It is defense in depth, not a sandbox: anything running as your user can ultimately change your files. The security page spells out the limits.
Does Pilothouse collect telemetry?
Nothing about your work. The only network call Pilothouse makes on its own is an anonymous daily update check (version, OS, architecture and a random ID that changes every month). We use it to count active installs, keeping only the date, a hash of that ID, the version, OS and architecture, and no IP address (details). Turn it off with update_check: false or PILOTHOUSE_NO_UPDATE_CHECK=1. Nothing about your sessions, prompts, commands or paths leaves your machine except through notification channels you set up.
Is it free? What about Windows?
Pilothouse is free and open source under Apache-2.0. It runs on macOS and Linux (amd64 and arm64); Windows is on the roadmap. A hosted relay and team policies may become a paid Pilothouse Cloud later — the open-source product stays complete for individuals.
Let your agents keep working
while you’re away from the keyboard.
Try the real app in 30 seconds, or install in a minute. Pair your phone in two. No account, ever.
pilothouse demo30 seconds, no agents touched: the real web app with pretend agents asking for things, in a temp folder that’s deleted when you quit. How the demo works
or install it
curl -fsSL https://pilothouse.dev/install.sh | shbrew install sabr-software/tap/pilothousethen run pilothouse setup