Agents & Actions
Actions
An action is a project-defined command. When you run one, Spruce opens a terminal session in the artifact's worktree and executes the command — no context switching, no copy-pasting paths, no remembering which venv to source.
The most common use of actions is launching an agent (Claude Code, Codex, OpenCode, Kiro, or Gemini pre-configured with Spruce's MCP server, the artifact's context, and a prompt), but actions also work fine for dev servers, test suites, or any other command.
Actions are defined per project as markdown files in the Spruce project's actions/ folder, so they're versioned with the rest of the project and shared with your team.
How actions appear in the UI
Every artifact has a terminal panel. Click the + dropdown in the panel header and you'll see the list of actions defined for the project. Pick one and Spruce opens a new terminal session, drops into the artifact's worktree (if one exists), and runs the action's command.
Terminal panel with the + dropdown showing available actions
Anatomy of an action
An action is a markdown file with two parts:
- YAML frontmatter: a
modes:map (one entry per supported agent or shell), plus optionaldisplay:(icon / color) andforward:events. - Markdown body: the system prompt, substituted into a mode's
argsvia{{action_content}}.
The action's display name comes from the filename: actions/plan.md shows up as Plan, actions/run-tests.md as Run Tests.
Modes
Every action carries one or more modes. Each mode is either an argv invocation (a binary: plus a list of args:) or a shell command (a single command: string). When you run the action, Spruce picks the mode that matches the project's default agent — or falls back to whichever mode is listed first. You can also flip between modes at run time from the action picker.
This is how a single action — say, Plan — can run through Claude Code, Codex, Kiro, OpenCode, or Gemini without you maintaining five separate files. The body (the system prompt) is shared; only the invocation differs.
A real example, abridged from the plan.md action that ships in the base bundle:
markdown
---
display:
icon: list-tree
modes:
claude:
binary: claude
args:
- --mcp-config
- '{"mcpServers":{"spruce":{"command":"{{sidecar_path}}","args":["mcp","serve"]}}}'
- --system-prompt
- "{{action_content}}"
- --allowedTools
- "Read,Glob,Grep,Edit,Write,Bash,mcp__spruce__*"
- --
- "Your session ID is {{session_id}}. Get artifact {{artifact_id}} and begin."
codex:
binary: codex
args:
- -c
- 'mcp_servers.spruce.command="{{sidecar_path}}"'
- -c
- 'mcp_servers.spruce.args=["mcp","serve"]'
- --sandbox
- workspace-write
- "{{action_content}} Get artifact {{artifact_id}} and begin."
shell:
command: 'echo "fallback: no agent configured"'
forward:
- comment-added
---
You are a collaborative product thinker and software architect. Your job is to help a human go from idea to actionable plan, through conversation, not by charging ahead alone.
The current date and time is: {{current_time}}
{{context:artifact-system}}
{{context:comment-system}}
## How to Work
Get the artifact using `mcp__spruce__artifact_get`, read its linked artifacts, check for comments using `mcp__spruce__artifact_comment_list`, and explore relevant code. Then follow the phases below…Things to notice:
- Each mode is a key under
modes:. The key (claude,codex,shell) is the mode name. Spruce ships modes named after each supported agent, but the names are free-form — you can add agpt-4-turbomode if you wire one up. - Argv vs. shell modes are structurally distinct. A mode block with
binary:+args:is argv-direct: the binary is exec'd with each arg as a literal slot, no shell parsing. A mode block withcommand:is written into the user's shell PTY. Mixbinary:andcommand:in the same block and parsing fails. {{action_content}}puts the prompt into an arg. Everything below the closing---is the markdown body. It's substituted into any arg (or env value) that contains{{action_content}}— typically--system-prompt, or whatever flag your agent uses for its system message.forward: [comment-added]lets the running session absorb new user comments mid-flight without spawning a new session, useful for review-loop actions.
For the full set of substitutable variables (including {{sidecar_path}} and {{session_file:<name>}} used by per-session MCP setups), see Action Template Variables.
What an action has access to
When an action runs, Spruce sets the working directory to the artifact's worktree (if the artifact is being worked on) or to a sensible default (if not). Two things make actions powerful for agents specifically:
Spruce's MCP server
Whenever an action launches an agent, Spruce wires up its MCP server so the agent can call back into Spruce: read and update artifacts, post and resolve comments, run git operations, search the project. There are two delivery paths depending on what the agent supports:
- Per-session, inline. Agents whose CLI accepts inline MCP config (Claude Code, Codex, OpenCode, Gemini) get the Spruce MCP server passed at launch time — through
--mcp-config,-c mcp_servers.*,OPENCODE_CONFIG_CONTENT, or a per-session settings file. The{{sidecar_path}}template variable resolves to the bundledspruce-clibinary so the config can point at it without a hard-coded path. - Global config file. Agents that only read MCP servers from a fixed config file (Kiro reads
~/.kiro/settings/mcp.json) are configured once via Settings → Agents — Spruce writes thespruceentry into the agent's global file and shows the entry's status alongside the other agents.
Either way, the agent ends up with access to Spruce's tools surfaced via --allowedTools (Claude Code) or the equivalent flag for whichever agent the action launches. See MCP Tools for the full surface area.
Defining a new action
Save a markdown file in the project's actions/ folder with the frontmatter + body shape above. Spruce picks up the new action with no restart needed. You can also add or edit actions — including managing modes per agent — through Settings → Actions in the app.
Where actions come from
You can populate your project's actions/ folder two ways:
Use the base bundle on project creation. New projects start with multi-mode actions for Claude Code, Codex, OpenCode, Kiro, and Gemini:
- General: generic do-anything agent for ad-hoc work.
- Plan: read the artifact, propose an implementation plan.
- Implement: write code against the agreed plan.
- Review: self-review the diff, surface issues.
- Author by hand. Drop a markdown file in
actions/with the frontmatter shape described above. Spruce picks it up live, no restart. Use this for non-agent recipes (dev server, tests, lint), agent launchers for tools the packs don't ship, or to tweak the agent prompts that did ship from a pack.
You can also import a pack into an existing project from Settings → Import / Export → Import bundle, useful if you skipped the pack at creation or want to layer in a second one. See Importing and Exporting Bundles.
For ready-to-copy launchers and non-agent recipes, see Action Recipes.
The Spruce project directory is a git repo, so pushing it shares the
actions/folder along with everything else. New teammates get the same actions the moment they pull the project.
Platform notes for agent launchers
- macOS / Linux: agent binaries such as
claude,codex,opencode,kiro-cli, andgeminineed to be on yourPATH; install per the upstream docs. Settings → Agents shows which agents Spruce can detect, links to install pages for the ones it can't, and handles MCP setup for the agents that need it (Kiro). - Windows: Spruce ships a Windows-compatible launcher; see Platform Notes if you hit issues.
Related
- Settings → Agents — pick your default agent and wire up MCP config per agent.
- Action Recipes — common recipes for dev servers, builds, tests, agent launchers.
- Action Template Variables — what's available inside a mode's args / env or the prompt body.
- MCP Tools — what Spruce exposes to the agent.
- Sessions — how sessions are scoped and persisted.
