Skip to main content

AI Agents

Running Claude Code, Gemini CLI, Codex CLI, OpenCode, and Cursor side by side in Canopy.

Updated
Reviewed

Built-in Agents

Canopy supports five AI coding agents out of the box. Each one runs as a CLI process in a dedicated terminal panel with full PTY emulation.

AgentCommandShortcutColor
Claude CodeclaudeCmd/Ctrl+Alt+CTerracotta (#CC785C)
Gemini CLIgeminiCmd/Ctrl+Alt+GBlue (#4285F4)
Codex CLIcodexCmd/Ctrl+Alt+XGreen (#10a37f)
OpenCodeopencodeCmd/Ctrl+Alt+OEmerald (#10b981)
Cursorcursor-agentCmd/Ctrl+Alt+UCyan (#3ee6eb)

All keyboard shortcuts can be rebound in Keyboard Shortcuts.

Launching an Agent

There are a few ways to launch an agent:

  • Keyboard shortcut — press the agent's shortcut from the table above to launch it directly.
  • Toolbar button — click the agent icon in the toolbar.
  • Worktree card — use the agent launch buttons on any worktree card in the sidebar.
  • Panel palette — open with Cmd/Ctrl+N and select the agent type.

The agent launches in the active worktree's directory, so it picks up the right branch and working tree straight away.

Session Resume

When you close an agent panel or quit Canopy, the app captures the agent's session ID from its terminal output. This lets you pick up exactly where you left off instead of starting a fresh conversation.

To resume a session, open the Panel Palette (Cmd/Ctrl+N) and scroll to the Recent Sessions section at the bottom. Each entry shows the agent name, model, and how long ago the session ran (e.g. "Sonnet · 2h ago"). Selecting one re-launches the agent with the correct resume flag.

Canopy handles the resume syntax automatically. Under the hood, it passes the session ID using each agent's CLI flag:

AgentResume syntax
Claude Codeclaude --resume <session-id>
Gemini CLIgemini --resume <session-id>
Codex CLIcodex resume <session-id>
OpenCodeopencode -s <session-id>

Canopy stores up to 50 sessions per worktree and prunes anything older than 30 days. Sessions are scoped to the directory they were started in. Any launch flags you used originally (like --dangerously-skip-permissions for Claude) are preserved on resume.

Note
Canopy does not currently support session resume for Cursor. Each cursor-agent session starts fresh, so no session ID is captured on close.

Pre-Agent Snapshots

Every time an agent starts working, Canopy captures a snapshot of your working tree automatically. If you had uncommitted changes or untracked files before the agent ran, this gives you a one-click restore point to get back to that exact state. No setup, no configuration. It just happens in the background.

Under the hood, Canopy runs git stash push --include-untracked to capture all uncommitted changes and untracked files, then immediately re-applies the stash so the agent has the full working tree to operate on. The stash entry stays in place as your restore point while the agent works.

One snapshot is stored per worktree. If an agent finishes and you start a second agent on the same worktree without reverting, the original snapshot is preserved. Subsequent agent starts will not overwrite an existing restore point.

Reverting Agent Changes

To roll back to the pre-agent state, open the worktree card context menu (the ... button) and select Revert Agent Changes. This discards all uncommitted changes in the working tree, including any edits you made after the agent ran, and restores exactly the state that was captured at snapshot time. The whole operation takes a single click.

The menu item only appears on worktrees that have an active snapshot with uncommitted changes. Once you revert successfully, the menu item disappears and the snapshot is consumed. If your working tree was clean when the agent started (no uncommitted changes), there is nothing to restore, so the revert option will not appear.

For a more granular review of what an agent changed before deciding whether to revert, check the Review Hub. You can inspect individual file diffs and stage changes selectively rather than reverting everything.

Edge Cases

  • Conflicted files at agent start — if the working tree has unresolved merge conflicts when the agent launches, the snapshot is skipped. No menu item appears.
  • Conflicts after revert — if applying the snapshot produces merge conflicts, Canopy completes the revert but shows a warning that conflicts need manual resolution.
  • Stash deleted manually — if the underlying git stash entry was removed before reverting (via git stash drop or similar), the revert fails and Canopy shows an error notification.
  • Snapshot expiry — snapshots are automatically pruned after 48 hours. The stash entry is also dropped at that point.
Note
If a snapshot fails to create (for example, due to a git error), Canopy shows a warning notification but lets the agent continue without rollback capability. The agent's work is not blocked.

Help Agent

Canopy includes a built-in documentation assistant called the Help Agent. It spawns a real CLI agent session (Claude Code, Gemini CLI, or Codex CLI) inside a dedicated help/ workspace bundled with the app. The agent is locked to read-only, help-assistant mode and connects to Canopy's live documentation through the canopy-docs MCP server. Think of it as a knowledgeable guide that can search the docs, answer questions about features and settings, and even draft GitHub issues on your behalf.

Opening the Help Agent

There are four ways to open the Help Agent:

  • Keyboard shortcutCmd+Shift+H (macOS) or Ctrl+Shift+H (Windows/Linux)
  • Dock button — click the Canopy icon in the dock (the tab bar at the bottom of each panel)
  • App menu — Help > "Launch Help Agent"
  • Action palette — open with Cmd+Shift+P and search for "Launch Help Agent"

The Help Agent opens as a resizable overlay panel on the right side of the window, separate from the Portal. Click outside the panel or press the close button to dismiss it.

Agent Picker

The first time you open the Help Agent, a picker lists the available agents: Claude Code, Gemini CLI, and Codex CLI. Select one to start your session. Canopy remembers your choice, so subsequent opens skip the picker and launch your preferred agent automatically.

To switch agents, click the back arrow () in the panel header. This returns you to the picker and clears the current preference.

You can also set a persistent default in Settings > CLI Agents under the "Default agent" option. When a default is set, the Help Agent always launches with that agent without showing the picker. If no default is configured, Canopy uses the first installed agent it finds (Claude → Gemini → Codex).

Panel Layout and Resizing

The help panel defaults to 380 pixels wide, with a minimum of 320px and a maximum of 800px. Drag the left edge to resize it. Keyboard users can focus the resize handle and use ArrowLeft / ArrowRight to adjust in 10-pixel steps. Your width preference persists between sessions.

Each time you open the panel, it starts a fresh conversation. Closing the panel clears the session entirely, and help sessions don't appear as tabs in the dock.

What the Help Agent Can Do

The Help Agent searches Canopy's documentation in real time through the canopy-docs MCP server. It can:

  • Answer questions about Canopy features, settings, and workflows
  • Search the documentation and surface relevant pages
  • Share links to YouTube tutorial videos found in the docs
  • Search existing GitHub issues related to your question
  • Draft new GitHub issues on Canopy's repository for feature requests or bugs (with your approval)

The agent operates read-only. It cannot edit files, run shell commands, or help with your own project's codebase. It's strictly a Canopy documentation assistant.

Tip
If the agent picker shows no agents, go to Settings > CLI Agents and make sure at least one agent is installed and enabled.

Agent Availability

Canopy detects which agent CLIs are installed by checking your PATH (via which). Agent buttons stay visible in the toolbar — unavailable ones are shown as not installed.

Check which agents are detected in Settings > General under "System Status."

Tip
If an agent CLI isn't detected after installing it, make sure it's on your PATH. Open a new terminal and verify with which claude (macOS/Linux) or where claude (Windows), then restart Canopy.

Agent State Tracking

Canopy monitors each agent's terminal output in real time and tracks its state. States show up as badges on the worktree card and terminal panel:

StateMeaning
IdleAgent prompt is visible, ready for input.
WorkingLLM is streaming a response.
RunningExecuting a tool or shell command.
WaitingBlocked on user input. Two sub-states: prompt (permission or approval request) and question (the agent is asking a clarifying question).
DirectingYou are actively typing into the agent's terminal.
CompletedFinished the current task.

State detection works by pattern-matching terminal output. Each agent has its own set of patterns for identifying prompts, streaming indicators, tool execution, and approval requests. The patterns are tuned per agent, so detection stays accurate across different CLI output formats.

CPU-Based Idle Detection

Sometimes an agent launches a long-running process like a compiler or test suite that produces no terminal output for a while. Rather than flickering to "idle" prematurely, Canopy monitors the process tree's CPU usage. If any child process is still active, the agent stays in its current state until the work actually finishes. This is transparent to you as a user: builds and test runs just show the correct state without false idle transitions.

Activity Headlines

Beyond the state badge, each agent panel shows an activity headline, a short description of what the agent is doing right now (e.g. "Editing src/index.ts" or "Running tests"). These are generated from terminal output in real time.

State Chip Tooltip

Each agent panel header displays a small circular state chip, separate from the state badge shown on worktree cards in the sidebar. The chip's icon and color reflect the agent's current state:

StateIconColor
WorkingSpinning circleOrange/amber
RunningPlayBlue
WaitingHollow circle (prompt: amber circle, question: question circle)Grey (prompt: amber)
DirectingInteracting circleBlue
CompletedCheckmark circleGreen

The chip is hidden when the agent is idle. It also hides for the completed state if no session cost data is available.

If there are errors captured from agent terminal output, a small red dot appears at the top-right corner of the chip. The dot clears once the errors are dismissed from the panel.

When a session completes and cost data is available, the chip shows the session cost and token count as inline text next to the icon (e.g. $1.23 · 45k). This is the only case where session data appears outside the tooltip.

Tooltip Fields

Hovering the state chip opens a tooltip with live session metadata. All fields are conditional and only appear when their data is available:

FieldWhen ShownFormat
Headline + elapsedAlways (when chip is visible)The current activity headline (or "Agent working" as a fallback), followed by session elapsed time (e.g. · 14m). Elapsed time formats: 45s, 14m, 2h 14m, 1d 3h.
Exit codeAgent exited with a non-zero codeExit code: 1 in red.
State detailsAlwaysCurrent state label, optionally followed by duration in that state (e.g. · 2m), the change trigger (e.g. · Output), and a confidence percentage when below 100%.
SinceAlwaysRelative time of the last state change, e.g. Since: 2 minutes ago.
Cost + tokensSession cost availableSession cost in USD and token count, e.g. Cost: $0.14 · 12.3k tokens. Token counts format as integers below 1k, 45k at 1k+, and 1.2m at 1m+.
Error countOne or more errors from terminal output1 error or 3 errors in red.
Note
Session cost and token data is currently only available for Claude Code. Canopy parses the cost summary that Claude Code prints to the terminal at the end of each task. Other agents (Gemini CLI, Codex CLI, OpenCode, Cursor) do not expose cost in their terminal output, so the cost fields won't appear for those sessions. As a result, the completed chip is effectively only visible for Claude Code sessions in the current release.

The duration text within the State details field only appears for the working, waiting, and directing states, and only after the agent has been in that state for at least 10 seconds. This prevents a brief 0s flash when a state has barely started.

The change trigger tells you what caused the last state transition. Possible values are: Input, Output, Heuristic, AI classification, Timeout, Exit, Activity, and Title. High-confidence triggers like Input and Output always show 100% confidence (so no percentage is displayed). Lower-confidence triggers like Heuristic or AI classification show their confidence score explicitly.

Both the session elapsed time and the state duration update every 30 seconds, not in real time. A freshly opened tooltip may show a slightly stale value that catches up on the next refresh cycle.

Notifications

When agents enter the waiting state, Canopy notifies you via title bar and dock badges. For the full notification and sound system, see Notifications & Sound.

The two main notification channels:

  • Title bar badge — shows the count of agents needing attention, e.g. "(2) Canopy"
  • macOS dock badge — same count on the dock icon

Notifications clear automatically when you focus the Canopy window.

Quit Confirmation

When you quit Canopy while any agent panel is in the Working or Running state, Canopy intercepts the quit and shows a confirmation dialog automatically. The check runs on every quit attempt — via Cmd+Q on macOS, Alt+F4 on Windows, or File > Quit on any platform.

The dialog is titled "Agents are working" and reports how many agents are currently active. Two choices are presented: Cancel (the default, keyboard-highlighted) dismisses the dialog and leaves everything running; Quit Anyway proceeds with a graceful shutdown.

Panels that have already been closed are excluded from the count. If no agents are in Working or Running state, no dialog appears and Canopy quits silently. OS-level signals such as SIGTERM or a force-quit bypass the dialog entirely.

Note
If you choose Quit Anyway, Canopy still captures session IDs before shutting down. You can resume any interrupted session from the Panel Palette after restarting.

Preventing System Sleep

When any agent is in the Working or Running state, Canopy automatically prevents the system from sleeping. This keeps long-running agent tasks from being interrupted by macOS, Windows, or Linux power management. The protection stays active until every agent has left those states. There's nothing to configure and no indicator shown. It just works in the background.

Providing Codebase Context

Use CopyTree to give agents context about your codebase. Press Cmd+Shift+C to copy a structured snapshot to your clipboard, then paste it into any agent's terminal input. You can also right-click a worktree card and choose Copy Context to select between full context and modified files only.

Send Selection to Agent

Select text in any terminal or agent panel, then route it directly into another panel's input buffer without going through the system clipboard. This is the quickest way to share a snippet of agent output, an error message, or a shell result with another agent running in parallel.

There are three ways to trigger it:

  • Right-click context menu — select text, then right-click and choose Send to Agent. The menu item only appears when text is selected in a PTY-backed panel.
  • Keyboard shortcut — see the platform-specific shortcut below.
  • Action palette — open with Cmd/Ctrl+Shift+P and search for "Send to Agent" (the action is listed as "Send terminal selection to another agent or terminal panel").

Press Cmd+Shift+E to open the Send Selection palette. This shortcut is scoped to terminal and agent panels. In other contexts (such as the Unified Input bar), the same key combination performs a different action.

The palette shows a searchable list of all other PTY-backed panels (agent and terminal panels). Each item displays the panel title; agent panels also show the agent name and icon. The list caps at 20 results, so use the search field to find a specific target if you have many panels open. Panels in the trash or running in the background are excluded.

Panels whose input is currently locked (for example, while an agent is actively working) appear in the list but are greyed out with a lock icon. They cannot be selected as a target.

Canopy caches your selection as you highlight text, so the text does not need to remain highlighted when the palette opens. The last selection you made in that panel is used. After sending, the cached selection persists, so you can immediately route the same text to a second target without reselecting.

The selected text arrives in the target panel's input buffer as if you had typed it. It is not submitted automatically. Press Enter in the target panel to run it. Multi-line selections are handled safely through bracketed paste mode, so the content won't execute line-by-line on arrival.

Tip
The keyboard shortcut and context menu item silently do nothing if no text has been selected in the focused panel. If the shortcut does not seem to respond, click and drag in the terminal output to make a selection first.

To send the same input to multiple panels at once, see Bulk Operations.

Agent Updates

Canopy can check and update agent CLI versions. Updates work through:

  • npmnpm install -g <package>
  • Homebrewbrew upgrade <package>
  • Custom command — per-agent update command

Check current agent versions and manage updates in the agent settings.

Custom Agents

Beyond the five built-in agents, Canopy supports custom agents through the user registry. Custom agents merge with the built-in registry and show up alongside them in all launch surfaces.

For each custom agent, you can configure:

  • Name — display name in the UI
  • Command — the CLI command to execute
  • Color — brand color for panel borders and badges
  • Keyboard shortcut — quick-launch binding
  • Context injection — whether CopyTree injection is supported

MCP Server

The sections above cover agents that run inside Canopy terminals. The MCP server flips this around: Canopy becomes the server, and external tools connect to it from outside.

Canopy exposes its action system as a local MCP server (Model Context Protocol). Any MCP-compatible client running on the same machine can connect and call Canopy actions as tools. This means an external agent like Claude Code or Cursor can read terminal output, manage worktrees, stage git changes, and control panels without needing to go through the terminal.

The server is opt-in and disabled by default. It binds to 127.0.0.1 only, so nothing is exposed to the network.

Enabling the Server

Open Settings > MCP Server and toggle the server on. It starts immediately. Toggle it off to stop.

No separate installation is needed. The server runs inside Canopy's main process and is available as long as Canopy is open.

Connecting an Agent

The Settings panel has a "Copy MCP config" button that copies a ready-to-paste JSON snippet to your clipboard:

{
  "mcpServers": {
    "canopy": {
      "type": "sse",
      "url": "http://127.0.0.1:45454/sse"
    }
  }
}

For Claude Code, paste this into .mcp.json at your project root, or add it globally in ~/.claude.json. You can also use the CLI:

claude mcp add canopy --transport sse http://127.0.0.1:45454/sse

If you have authentication enabled, the CLI command above won't include the bearer token. Use the JSON snippet from the Settings panel instead, as it includes the Authorization header automatically.

For Cursor, see the Cursor MCP docs. For Windsurf, see the Windsurf MCP docs. For other MCP clients, paste the snippet into their server configuration file.

Note
Any MCP client that supports SSE transport can connect. Canopy does not require a specific client.

Auto-Discovery

While the server is running, Canopy writes a discovery file at ~/.canopy/mcp.json containing the connection details. When the server stops (or Canopy quits), the entry is removed. Other keys in the file are left untouched.

This file is reserved for future dedicated integrations. Most users can ignore it and use the manual config steps above.

Available Tools

Tools exposed through MCP mirror Canopy's internal action system. The exact set depends on what's registered at runtime, but here are the main categories:

CategoryExample tools
Terminalterminal.list, terminal.getOutput, terminal.sendCommand (confirm)
Worktreeworktree.list, worktree.getCurrent, worktree.create (confirm)
Gitgit.getStagingStatus, git.stageFile, git.getFileDiff
GitHubgithub.listIssues, github.listPullRequests, github.openPR
Panelpanel.list, panel.focus, panel.palette
Filesfiles.search, file.view, file.openInEditor
Notesnotes.list, notes.read, notes.create
Projectproject.getAll, project.getCurrent, project.switch
Portalportal.listTabs, portal.openUrl, portal.toggle
Introspectionactions.list, actions.getContext
Reciperecipe.list, recipe.run
Agentagent.launch

Tools marked (confirm) require explicit confirmation before they execute. Use actions.list to get the full manifest at runtime, including descriptions and input schemas for every tool.

Confirmation-Required Actions

Canopy groups actions into three danger levels:

  • Safe — callable freely, no extra steps needed.
  • Confirm — listed in the tool manifest, but the call must include _meta.confirmed: true in its arguments. Without it, the server returns a CONFIRMATION_REQUIRED error. The tool's description always notes this requirement.
  • Restricted — never listed and never callable through MCP.

This prevents autonomous agents from running destructive operations (like deleting a worktree or sending a terminal command) without an explicit signal. The tool arguments for a confirm call look like this:

{
  "_meta": { "confirmed": true },
  "terminalId": "abc123",
  "command": "npm run build"
}

Authentication

By default, no authentication is required. Any process on 127.0.0.1 can connect. If you want to restrict access, generate a bearer token in Settings > MCP Server > Authentication.

With a token set, all requests must include the Authorization: Bearer <token> header. The "Copy MCP config" button automatically includes the header when a token is active:

{
  "mcpServers": {
    "canopy": {
      "type": "sse",
      "url": "http://127.0.0.1:45454/sse",
      "headers": {
        "Authorization": "Bearer canopy_abc123..."
      }
    }
  }
}

You can generate, regenerate, or remove the token at any time from the same Settings panel.

Port Configuration

The default port is 45454. You can change it in Settings > MCP Server. If the configured port is already taken, Canopy tries the next port up, repeating up to 10 times (maximum 45464). The Settings panel shows which port the server actually bound to if it differs from your configured value.

If all 10 candidate ports are unavailable, the server fails to start and the Settings panel shows the error.

Bulk Operations

When you're running multiple agents across several worktrees, managing them one at a time gets tedious fast. Bulk Operations lets you send a single action to every selected agent terminal at once. Open the palette, pick which worktrees to target, choose what to send, and fire it off.

Opening Bulk Operations

There are three ways to open the Bulk Operations palette:

  • Keyboard shortcutCmd+Shift+B (macOS) or Ctrl+Shift+B (Windows/Linux)
  • Toolbar button — click the broadcast icon in the toolbar
  • Action palette — open with Cmd+Shift+P and search for "Bulk Operations"

See Keyboard Shortcuts for the full shortcut reference.

Selecting Worktrees

The palette lists every worktree in your current project. Each row shows the branch name, agent count, and the dominant agent state. Click a row to toggle its checkbox, or use Select All / Deselect All at the top to target everything at once.

Worktrees with no active agent terminals are greyed out and can't be selected. The footer displays a running count of selected worktrees and total agents that will receive the action.

State Filter Presets

Above the worktree list, four filter buttons let you quickly add worktrees by their current state:

  • Active — agents in the Working or Running state
  • Waiting — agents blocked on input or approval
  • Idle — agents at the prompt, ready for a command
  • Completed — agents that have finished their task

Each button shows a count of matching worktrees and adds them to your current selection (it won't deselect anything already chosen). Matching is based on the worktree's dominant agent state, so a worktree with one Idle and one Working agent would appear under Active (since Working is the dominant state). These states map directly to the Agent State Tracking definitions above.

Keyboard Navigation

The palette supports full keyboard navigation: / to move between worktrees, Space to toggle selection, Cmd+Enter to send, and Esc to go back or close.

Keystroke Mode

Keystroke mode sends a single key signal to every selected agent's terminal. Four presets are available:

KeystrokeUse Case
EscapeCancel the current prompt or dismiss a menu
EnterConfirm a pending approval across all agents
Ctrl+CInterrupt a running agent (destructive)
Double EscapeCancel the current task entirely (destructive)

Ctrl+C and Double Escape are considered destructive actions. When you select either one, an amber confirmation prompt appears before anything is sent. Double Escape sends two Escape keystrokes with a one-second delay between them.

Text Command Mode

Text Command mode types a message and submits it to every selected agent. This is useful for giving the same instruction to multiple agents at once, or for approving a batch of waiting prompts with a specific response.

Type your command in the input field, then press Enter to see a preview of the resolved text for each worktree. The preview step lets you verify everything looks right before confirming. Press Cmd+Enter to skip the preview and send immediately.

The input supports template variables that resolve differently for each worktree. Click the variable chips below the input to insert them at the cursor. See Template Variables below for the full list.

Command history is available with / arrow keys, storing up to 50 previous commands.

Tip
Use {{branch_name}} or {{issue_number}} to give each agent targeted context without typing separate commands. The preview step shows exactly what each worktree will receive.

Recipe Mode

Recipe mode broadcasts a saved recipe to all selected worktrees. Recipes from all three scopes (Global, Team, and Project) are available for broadcast.

Select a recipe from the list, then preview which worktrees will receive it. After confirmation, recipes are dispatched two at a time through a concurrency queue to avoid overwhelming the system.

Note
All recipes (Global, Team, and Project) appear in the Bulk Operations palette. See Recipes for details on recipe scopes.

Template Variables

Template variables resolve per-worktree at send time. They're available in Text Command mode and appear as clickable chips below the input field. Variable values are pulled from each worktree's Git branch and linked GitHub issue or PR.

VariableResolves To
{{issue_number}}GitHub issue number linked to the worktree
{{pr_number}}GitHub PR number linked to the worktree
{{number}}Issue number if available, otherwise PR number
{{worktree_path}}Absolute filesystem path to the worktree directory
{{branch_name}}Git branch name of the worktree

If a variable can't be resolved for a particular worktree (for example, no linked issue), it becomes an empty string. The preview step highlights any unresolved variables with an amber warning so you can catch them before sending.