AI agent integration
Calyx ships with an MCP server that integrates with CLI AI agents (Claude Code, Codex CLI, OpenCode, Hermes, Grok, pi). It exposes peer-to-peer messaging between agents across tabs/panes, LSP-backed symbol lookup tools, cockpit tools for driving Calyx itself, a terminal command log, and a report of Claude Code’s token usage. The same server also republishes the MCP servers you add in Settings and hosts their views; that part is described on MCP Apps.
AI Agent IPC
Section titled “AI Agent IPC”Agents running in different tabs or panes can exchange messages with each other.
Enable
Section titled “Enable”- Open Settings (
Cmd+,), select the Agents pane, and turn on Enable AI Agent IPC in the AI Agent IPC section at the top. - Start agents (Claude Code / Codex / OpenCode / Hermes / Grok / pi) in two or more terminal panes.
- Each instance registers itself as a peer and can send/receive messages.
Turning the switch on starts the MCP server and writes config files based on which agents are installed.
| Agent | Config file |
|---|---|
| Claude Code | ~/.claude.json |
| Codex CLI | ~/.codex/config.toml |
| OpenCode | ~/.config/opencode/opencode.json, AGENTS.md |
| Hermes | ~/.hermes/config.yaml |
| Grok | ~/.grok/config.toml, ~/.grok/hooks/calyx.json |
| pi | ~/.pi/agent/extensions/calyx.ts |
Each agent gets two entries: calyx-ipc for the tools on this page, and calyx-mcp for the servers configured in the MCP Apps pane (see MCP Apps).
Restart any already-running agent instances so they pick up the new MCP server.
After you flip the switch, a status line under it reports the result: Running on port <port> · all agents configured, or Running on port <port> · <n> of <total> configured (Running on port <port> · no agents configured when none succeeded) followed by one line per config or hook that failed (✗) or was skipped because its agent is not installed (–).
If the server cannot start, the line reads Could not start: with the reason, and the Agents sidebar shows the same failure.
If you install another supported agent later, click Refresh below the switch. It writes that agent’s config and hooks against the server that is already running, so agents already connected keep working.
pi is the one supported agent with no MCP client configuration of its own, so Calyx reaches it through a TypeScript extension that pi loads on startup.
That single file carries the whole integration: the sidebar row, the approval gate, a calyx tool that dispatches to the MCP tools below (call it with {"tool": "list"} to enumerate them), and a calyx_mcp tool that does the same for MCP Apps servers.
A pi started outside Calyx, or inside a herdr pane, registers only calyx_mcp.
At launch and after updating Calyx
Section titled “At launch and after updating Calyx”Calyx remembers the switch. While it is on, every launch starts the server and rewrites the config entries and hooks above, so an update that changes what belongs in them needs no step from you. Calyx reuses the previous run’s port and token when it can, so an agent in a persistent session that outlives a Calyx restart keeps connecting. A new token is issued only when another process holds the previous port at restart. The Agents pane then says that the token was renewed: agent sessions started before that launch keep the old port and must be restarted, while new sessions need no change.
Calyx 0.41.0 and earlier did not remember the setting, so after updating from one of them the switch starts off. If you used AI Agent IPC before, turn it on once in Settings.
Rewriting at launch leaves config you maintain yourself intact.
Calyx edits only its own entry and keeps the rest of each file byte for byte, including key order, indentation, and line endings.
The Codex hooks block in ~/.codex/config.toml and the Calyx block in ~/.hermes/config.yaml are rewritten where they already sit, and anything inside one of them that Calyx does not own is moved out to just above the block instead of being replaced.
A file is not written at all when nothing needs to change.
How agents get the token
Section titled “How agents get the token”Calyx writes the server’s port and bearer token to ~/Library/Application Support/Calyx/agent-endpoint.json, readable by your user only, together with the process ID and start time of the Calyx that wrote it.
The hook scripts, the shell integration, the OpenCode plugin, and the pi extension read this file each time and send the token only when that Calyx is still running.
Claude Code and Codex do not keep the token in their config files.
Their entries name a helper script, calyx-mcp-headers, which prints the token only while the Calyx that wrote the endpoint file is running on the port the entry was written for.
Grok 1.0.52 or later reads the token on every request from calyx-bearer-token-<port>, a file next to the endpoint file that holds only the token.
Older Grok, OpenCode, and Hermes still carry the token in their config files.
The approval hook and the wake hook act only on answers that the running Calyx has signed with a key it creates at each start, so another process listening on the port cannot approve a tool call or wake a pane.
Available MCP tools
Section titled “Available MCP tools”register_peerlist_peerssend_messagebroadcastreceive_messages— deletes each returned message from the inbox, so any message is delivered exactly onceget_peer_status
See the demo video.
Waking Claude Code on messages
Section titled “Waking Claude Code on messages”Wake Claude Code on IPC messages, under AI Agent IPC in the Agents pane of Settings, is off by default.
With it on, a message that arrives for a Claude Code pane idle at its prompt wakes that pane, and the agent starts a turn on its own.
It applies to Claude Code only and needs a Claude Code version that supports asyncRewake hooks.
No other setup is needed: the wake hook is installed with Calyx’s other Claude Code hooks while AI Agent IPC is on, and the pane is bound to its peer when Claude Code connects to calyx-ipc from it or calls register_peer.
The wake hands the agent a short note saying how many messages are waiting and which peer id to read them with.
The agent reads them itself with receive_messages; Calyx never reads a message for it, and the note contains nothing written by another agent.
A message wakes a pane at most once.
A pane can be woken only while its wake hook is waiting. The hook starts waiting when a turn ends or a session starts (including a resumed, cleared, or compacted one), and waits for about 10 minutes. A turn interrupted with Esc starts no new wait, though a wait left from the previous turn can still wake the pane. A wake that arrives during a turn is absorbed into that turn after the running tool finishes. So a pane is not woken:
- about 10 minutes after its last wait began, that is, after its last completed turn or session start
- after Calyx or its IPC server restarted, until the next wait begins
- right after the switch was turned on, until the next wait begins
- after a persistent session was reattached to another pane
- while a
claudestarted inside the same pane has taken the hook over (the wake goes to that one)
Turning the switch off stops waking at once.
As before, send_message to an expired peer fails; a peer expires only when 10 minutes have passed since its last IPC call and it is neither the sender nor the recipient of an undelivered message.
Disable
Section titled “Disable”Turn off Enable AI Agent IPC in the Agents pane of Settings.
Calyx stops the server and removes its own entries and hooks.
Files that belong to Calyx alone (~/.grok/hooks/calyx.json and ~/.pi/agent/extensions/calyx.ts) are deleted.
A shared file that ends up empty stays on disk as an empty file, and a file that did not exist is never created.
The hook and helper scripts under ~/Library/Application Support/Calyx/bin/ stay in place.
Agents Sidebar
Section titled “Agents Sidebar”The sidebar includes an Agents tab that shows every connected AI agent in the current window along with its live status.
Each agent row is named after the pane it runs in, on three lines:
- The pane’s title.
- Its working directory, shown as the last path component.
- The agent, for example “Claude Code” or “Grok”.
Anything Calyx cannot resolve reads N/A.
Rows are named after the pane rather than the repository so that several agents working in one checkout stay distinguishable.
Alongside the name, a row shows:
- A state dot: red (waiting on the user), yellow (working), green (idle), blue (done).
- An unread message badge, if the agent has queued output the user has not yet seen.
- A last-seen timestamp.
Click a row to focus the pane running that agent.
The view supports Claude Code, Codex CLI, OpenCode, Hermes, Grok, and pi. Once Enable AI Agent IPC is on and you start an agent in a pane, that agent appears in the sidebar automatically. While the switch is off, the sidebar reads AI Agent IPC is disabled and points to Settings → Agents.
To see every pane of the window at once, along with the messages agents send each other, open Mission Map.
Subagent rows
Section titled “Subagent rows”An agent that runs subagents shows them as child rows under its own. A pane row with children gains a count badge at its right edge and a disclosure chevron next to it. A pane whose agent reports no subagents looks exactly as it did before.
Children start collapsed. Click the chevron to expand them. The chevron is a separate target from the row body, so expanding never moves focus to the pane. The expansion is remembered only while the sidebar stays open, and resets when you hide it or relaunch Calyx.
Each child row is indented under its parent and carries a state dot in the same four colors, the subagent’s type, the tool it is currently running, and how long ago it last reported. A CLI that reports only a subagent’s lifecycle leaves the type and tool lines out rather than filling them with placeholders, so those rows are a dot and a timestamp. Clicking a child focuses the parent’s pane, because a subagent has no pane of its own.
The tool line names the tool and what that call is working on, as Bash: git status --short.
Calyx reads the arguments the CLI reported: the command for a shell tool, the path for a read or a write, the URL for a fetch, and everything else as key: value pairs.
A run of whitespace collapses to a single space, so a heredoc still reads on one line, and a long line is cut at 500 characters.
Narrow the sidebar and the line is trimmed from its end, keeping the tool name and the start of the command in view, while the elapsed time on the right keeps its width.
Hover the row to read the whole line in a tooltip.
A tool with nothing to summarize shows its name alone.
| Agent | Subagent rows | Current tool |
|---|---|---|
| Claude Code | yes | yes |
| Grok | yes | yes |
| Codex | yes | no |
| OpenCode | yes | no |
| Hermes, pi, herdr panes | no | no |
A child row exists only while its CLI reports the subagent. It disappears when that subagent stops, when the parent session ends, and when the pane closes. Calyx keeps no history of its own, so nothing lingers once the CLI stops reporting it.
An agent CLI reads its hook configuration once, at session start. Subagent rows therefore appear in sessions you start after Calyx has installed the hooks, not in one that was already running.
When a row settles
Section titled “When a row settles”A row turns blue (done) when the agent’s session ends. Most supported CLIs report their own session end. For the ones that do not, and for an agent that was killed or crashed, Calyx settles the row when the pane’s shell returns to its prompt.
That fallback has two routes. Ghostty’s own end-of-command report covers every shell, including bash, elvish, and nushell, and needs no setup. Calyx’s shell integration covers zsh and fish while Track shell commands is on, and additionally expires any approval requests still pending for that pane, so an approval request never outlives the process that raised it.
A command you suspend with Ctrl-Z does not settle the row.
herdr-hosted agents
Section titled “herdr-hosted agents”Agents running inside herdr’s own panes show up here too, labeled “via herdr” in the subtitle. They need none of the setup native rows do: no Enable AI Agent IPC switch, no config file to write. Calyx reads them straight from herdr’s own status stream, so they appear automatically whenever herdr is installed and running.
Calyx watches for herdr rather than asking on a timer, so the order you start things in does not matter.
Start herdr while Calyx is already running and the rows fill in on their own, even with Calyx frontmost and the sidebar already open.
Install herdr, or put it on PATH, after Calyx launched and it is picked up without a relaunch.
A herdr server that restarts at the same socket path is recognized as a new session and reconnected to.
Calyx retries the connection a few times over the first seconds after herdr’s socket appears, because the file existing does not prove the server is listening yet. A server slower than that to start listening stays unreported until something else changes in its directory.
A herdr row you have already opened as a Calyx tab is clickable like any other: it focuses that pane. A row for a herdr pane you have not opened in Calyx has nothing to focus, so it is drawn as plain text with no hover highlight. Open that workspace from the Session Browser first.
When an agent CLI exits while herdr keeps its shell pane alive, the row turns blue (done) instead of holding whatever state it had last.
If AI Agent IPC is off, herdr rows keep showing, with a note underneath that Calyx’s own agents aren’t being monitored until you turn it on.
Resuming agents in persistent sessions
Section titled “Resuming agents in persistent sessions”With persistent sessions enabled, reattaching a session can offer to resume the agent CLI conversation that was running in it. See Persistent sessions for the toggles.
Cockpit tools
Section titled “Cockpit tools”Agents can drive Calyx itself through the same MCP server.
Four tools run immediately, without confirmation:
pane_list— list the terminal panes in the current windowpane_split— split a pane to the right or downtab_create— open a new tab, optionally in a given group and working directoryagent_status— report, for every pane or for onesurface_id, the agent’s state and current tool, its subagents, unread IPC messages, pending approvals, and its Git branch, changed-file count, and worktree task (all skipped withinclude_git: false), and, with Usage Tracking on, token usage; it does not change unread counts
Three tools type into your terminal or execute app commands, so each call is gated behind your approval:
pane_run— run a command in a panepane_send_keys— send keystrokes to a panepalette_execute— execute a command palette action
When a gated tool is called, the approval panel shows the tool name and the tab that owns its target pane (for palette_execute, which has no target pane, the current window’s active tab).
Allow runs that one call; the decision is not remembered.
The Options menu holds Deny and Always Allow.
Always Allow turns on auto-approval for future calls and approves every cockpit request already pending; agent tool prompts waiting in the same queue are left for you to decide.
A denied call returns {"status": "denied"} to the agent, a dismissed one returns {"status": "dismissed"}, and a request left unanswered for 55 seconds returns {"status": "approval_timeout"}.
Each is a normal result, not an error, and the tool does not run.
Auto-approval is the same setting as Auto-approve agent commands in the Agents pane of Settings. It is off by default, so every gated call asks first.
Approving agent tool calls
Section titled “Approving agent tool calls”When several agents run in parallel, their permission prompts are scattered across panes. With approval routing on, a supported agent sends each tool call’s permission request to Calyx before running the tool, and Calyx shows it in the same approval panel used by cockpit tools.
Which calls reach the panel depends on the agent:
- Claude Code and Codex: only the calls the CLI would have prompted you about itself. Anything its own permission system settles, such as a read in Plan mode or a tool you have already allowlisted, runs without reaching the panel.
- Grok: only in always-approve mode (
bypassPermissions). In its other modes Grok keeps prompting in its own pane, so the same question is never asked twice. - pi: every tool call. pi ships no permission prompt of its own, so the panel is the only gate. With approval routing off, pi’s tool calls run unreviewed.
- OpenCode and Hermes: none. They keep prompting in their own pane.
Enable
Section titled “Enable”- Turn on Enable AI Agent IPC in the Agents pane of Settings (while it is on, Calyx reinstalls the approval hook at every launch, so updates need no extra step).
- Turn on Show agent tool prompts in the approval banner in the Agents pane of Settings (off by default).
- Restart running agent CLI instances.
Using the approval panel
Section titled “Using the approval panel”Requests appear in a floating panel styled like a macOS notification, at the top-right of the screen that holds the Calyx window you are using. The panel shows on every Space, including full-screen ones, and stays above other apps’ windows even while Calyx is in the background. Clicking its buttons and menus never takes focus, so deciding a request does not pull you out of what you are typing. Only typing an Other… answer or a note into a question takes focus, and focus returns to the pane afterwards. The panel hides itself once nothing is pending.
The title names the agent and tool (for example “Claude Code · Bash”) and the tab that owns the target pane. Below it, two lines summarize what the tool will do. Hover the summary to read the full text in a tooltip, or click it to expand the full text inside the panel.
Yes approves that single request. The Options menu holds every other choice:
- The CLI’s own always-allow suggestions, such as “Yes, and don’t ask again for Bash: npm test for this session”. Each lasts for the scope the CLI names (session, project, or user).
- Always Allow <tool> in This Pane, shown only when the CLI offered no suggestions of its own. It auto-approves that tool for that pane until the pane closes or the server stops.
- No, which denies the request.
Hover the panel to reveal a dismiss button on its top-left corner. Dismissing hands the request back to the agent without an answer from Calyx: Claude Code and Codex show their own prompt in the pane, and you answer there. Grok and pi have no prompt to hand back to, so the button is disabled for them and the decision stays in the panel.
A Claude Code question (AskUserQuestion) appears in the same panel. Pick an answer from Options, or from an inline list when the question allows several answers or carries previews. Other… takes a free-text answer, Add notes attaches a note, Back returns to the previous question when there are several, and Chat about this hands the conversation back to the CLI.
When more than one request is pending, previous/next chevrons and an “N / M” position label appear at the right end of the title.
Browse the queue and decide any request in any order; deciding the displayed request advances to the nearest remaining one.
Click the position label to see the whole queue at once: every pending request across all windows, oldest first, each row reading 3. Claude Code · Bash: npm test with a ▸ marking the one on screen.
Picking a row jumps straight to that request, which saves paging through a backlog to reach the one you care about.
Cockpit tool requests share the same queue, and so do the consent prompts an MCP App raises when it wants to open a link or send a message to the agent.
With a single pending request the navigator disappears.
A macOS notification is posted for each new request. Secrets in the notification summary are masked, while the panel itself shows the exact text so you can judge what you are approving.
Fallback behavior
Section titled “Fallback behavior”Nothing is ever auto-approved on failure. If Calyx is unreachable, or you do not respond within about 10 minutes, the request expires, and what happens next depends on the agent. Claude Code and Codex fall back to their own in-pane prompt, so the decision comes back to you there. Grok in always-approve mode and pi have no prompt of their own to fall back to, so an expired request is denied. Cancelling the tool call on the agent side removes it from the panel immediately, and so does answering the same prompt in the agent’s own pane. A request still pending when the agent finishes its turn is removed then as well.
Terminal command log
Section titled “Terminal command log”Calyx can keep a structured log of the commands run in each terminal — the command line, exit status, and captured output — and expose it to agents. This lets an agent read a build’s output or wait for a long-running command without scraping the screen.
terminal_list_commands— list the recorded commands for a pane, oldest firstterminal_read_output— fetch the captured output of one commandterminal_await_command— wait until a running command finishes (default timeout 30 seconds, maximum 55; on timeout it returns{"status": "timeout"}and can simply be called again)
Requirements
Section titled “Requirements”The log is fed by shell integration, currently for zsh and fish only. Calyx installs the integration automatically while Track shell commands (Settings, Agents pane) is on; the toggle is on by default and applies to newly opened terminals only.
What is stored
Section titled “What is stored”Records are kept in memory only: up to 200 commands per pane, with captured output capped at 256 KB per pane.
Nothing is written to disk, and the log is discarded when Calyx quits.
Commands that run full-screen TUIs (the alternate screen) or whose output cannot be captured are reported with output_unavailable: true.
Command lines and captured output are checked for known secret patterns (API tokens, passwords, Authorization headers, cloud provider keys, JWTs) before they are stored, and any match is replaced with [redacted].
This runs automatically and cannot be turned off.
Redacting a large capture happens in the background so the terminal is never blocked waiting for it.
While that is in progress, the command still reports as running: terminal_read_output returns {"output_pending": true} instead of the output (call it again shortly), and terminal_list_commands withholds the exit code and duration until redaction finishes.
Token usage report
Section titled “Token usage report”With Usage tracking on, agents can call usage_report to read Claude Code’s token usage, grouped by model, effort, thread, agent type, day, project, or session.
The tool is always listed, and returns an error that says to turn on Usage Tracking when it is off.
Asking from an agent lists its arguments.
LSP Proxy MCP
Section titled “LSP Proxy MCP”LSP features are exposed via the same MCP server used by AI Agent IPC.
Agents can get symbol-aware results instead of relying on grep.
lsp_hover— hover info for a symbollsp_definition— jump to definitionlsp_references— list referenceslsp_rename— rename a symbollsp_diagnostics— fetch diagnostics (errors and warnings)
Additional tools are also provided.
- Turn on Enable AI Agent IPC in the Agents pane of Settings (the LSP proxy shares this server).
- Restart or reconnect your agent so it picks up the
calyx-ipcMCP server. - (Optional) In Settings, open the LSP pane and enable auto-install for missing language servers.
Calyx keeps language servers running in the background, syncs file changes from disk, and starts the right server on the first lsp_* call for a workspace.
Supported languages
Section titled “Supported languages”TypeScript, Python, Rust, Go, Swift, and others. Per-language auto-install support is shown in Settings under the LSP pane.
