# Ferrus

> Deterministic multi-agent orchestration for real software execution.

- **Type:** MCP server
- **Install:** `agentstack add mcp-ferrus-dev-ferrus`
- **Verified:** Pending review
- **Seller:** [ferrus-dev](https://agentstack.voostack.com/s/ferrus-dev)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [ferrus-dev](https://github.com/ferrus-dev)
- **Source:** https://github.com/ferrus-dev/ferrus
- **Website:** https://ferrus.dev

## Install

```sh
agentstack add mcp-ferrus-dev-ferrus
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ferrus

[](https://crates.io/crates/ferrus)
[](https://releases.rs/docs/1.95.0/)
[](https://github.com/ferrus-dev/ferrus/blob/main/LICENSE)
[](https://github.com/ferrus-dev/ferrus/actions/workflows/rust.yml)
[](https://github.com/ferrus-dev/ferrus/actions/workflows/publish.yml)

**Deterministic orchestration of AI agents for real software work.**

Ferrus turns coding agents into controlled, repeatable workers.

It runs a Supervisor -> Executor -> Reviewer loop over your repository -- not as a chat, but as a **state machine**.
Tasks are planned, implemented, checked, and reviewed in a structured, restart-safe flow. Unlike chat-based agents, ferrus enforces structure and lifecycle.

Everything is explicit:
- Runtime state lives in SQLite; task context lives in scoped Markdown artifacts
- Optional repository graph facts live in a separate machine-local SQLite sidecar
- Agents are stateless between runs
- Crashes are recoverable
- No hidden context

## Supported agents

Ferrus works with existing coding agents:

- **Codex**
- **Claude Code**
- **Qwen Code** (experimental)
- **goose** (experimental) -- MCP-native and convenient for local models. Ferrus attaches its role-scoped MCP server at launch via goose's `--with-extension`, so no config file is written; set the model provider (e.g. a local LM Studio/Ollama provider) with `goose configure`. Honors the per-task worktree, so the executor role is usable. Headless runs are bounded by loop guards (`--max-turns`, `--max-tool-repetitions`) so a weak local model that thrashes on compile errors fails cleanly instead of looping forever -- raise the turn budget by exporting `GOOSE_MAX_TURNS` before launching Ferrus. Tool-calling reliability depends heavily on the local model.
- **opencode** (experimental) -- convenient for running local models. Warning: The executor layer is currently **unstable**: opencode identifies a project by its git root-commit and binds it to a single working directory in its own global store, so it does not stay confined to the isolated per-task worktree HQ provisions and may operate on the canonical checkout instead. Use opencode for the **supervisor/reviewer** role for now; treat the executor role as not yet supported.

Agents are treated as interchangeable workers -- ferrus provides the runtime, coordination, and state.

Internally, agent support is normalized through `src/agents/`: `mod.rs` defines the shared Supervisor/Executor contracts and MCP config entry shape, while `claude/`, `codex/`, `qwen/`, `opencode/`, and `goose/` adapt each CLI's launch flags, model overrides, headless prompt transport, and local permission/config conventions.

>  **Status**: ferrus is currently in alpha and not ready for production.

[Tutorial](https://ferrus.dev) | [Roadmap](https://github.com/ferrus-dev/ferrus/blob/main/docs/milestones.md)

---

## How it works

```
  you
   |
   +-> ferrus HQ
         |
         +-> Supervisor (Claude Code or Codex) -- plans tasks
         |         | exits after task created;
         |
         +-> Executor (Claude Code or Codex)   -- implements, checks, submits
         |         | runs headlessly
         |
         +-> Reviewer (Claude Code or Codex)   -- spawned automatically on submission
                   | exits after approve/reject; runs headlessly
```

HQ watches state transitions and spawns the right agent at the right time.

State is coordinated through `ferrus.db`, with human-readable task context under `.ferrus/tasks/` and `.ferrus/runs/`. If an agent crashes and restarts, Ferrus can recover its run and task lease without reconstructing state from Markdown files.

---

## Quick start

Install:

```sh
cargo install ferrus
# or on Linux/macOS:
curl -fsSL https://github.com/ferrus-dev/ferrus/releases/latest/download/install.sh | sh
```

```powershell
# or on Windows:
iwr https://github.com/ferrus-dev/ferrus/releases/latest/download/install.ps1 -useb | iex
```

Run:

```sh
ferrus init                                                # scaffold ferrus.toml, .ferrus/, and ~/.ferrus project state
ferrus register --supervisor claude-code --executor codex  # write agent configs and tool permissions
ferrus                                                     # enter HQ
```

Then type `/task` -- a supervisor spawns, you describe what you want, and the full loop runs automatically.

On Linux and macOS for `x86_64` and `aarch64`/`arm64`, `install.sh` downloads the matching release binary into `~/.local/bin` by default. On Windows, `install.ps1` installs `ferrus.exe` into `%LOCALAPPDATA%\ferrus\bin` by default. Release archives are verified with published SHA-256 checksums before installation. Set `FERRUS_INSTALL_DIR` to override the destination, or `FERRUS_INSTALL_VERSION=vX.Y.Z` to install a specific release tag.

---

## HQ

`ferrus` with no arguments opens an interactive shell:

| Command | Description |
|---|---|
| `/plan` | Free-form planning session with the supervisor (no task created) |
| `/task` | Define a task from the selected milestone, then run the executor->review loop automatically |
| `/task --manual` | Define a free-form task without selected milestone context |
| `/spec` | Draft, approve, and save a feature specification; offers to archive a completed selected spec first |
| `/archive-spec` | Summarize completed selected spec work into `## Outcome` and archive linked task/run artifacts |
| `/milestones` | Select the current spec and milestone |
| `/reset-spec` | Clear the selected spec and milestone |
| `/check` | Run configured checks from HQ when the current workflow permits; does not mutate task state |
| `/check --force` | Run configured checks from HQ regardless of task status; does not mutate task state |
| `/supervisor` | Open an interactive supervisor session (no initial prompt) |
| `/executor` | Open an interactive executor session (no initial prompt) |
| `/resume` | Manually resume the executor headlessly; also recovers Consultation by relaunching both supervisor and executor |
| `/review` | Manually spawn supervisor in review mode (escape hatch when automatic spawning failed) |
| `/status` | Show task state, agent list, and session log paths |
| `/tasks` | List SQLite task runtime rows |
| `/runs [--limit N]` | List SQLite run attempts |
| `/events [--limit N] [--run ]` | List SQLite runtime events |
| `/attach ` | Show log path for a running headless agent |
| `/stop` | Stop all running agent sessions (prompts for confirmation) |
| `/reset` | Force-reset resettable tasks and clear their scoped artifacts (prompts for confirmation) |
| `/init [--agents-path]` | Initialize ferrus in the current directory |
| `/register [--supervisor ] [--executor ]` | Register Claude Code or Codex configs from HQ |
| `/model  ` | Update the supervisor or executor model override |
| `/model  --clear` | Clear the supervisor or executor model override |
| `/help` | List all HQ commands |
| `/quit` | Exit HQ |

> **Quit HQ:** Press **Ctrl+C** twice within 2 seconds to exit. The first press shows a yellow "Press Ctrl+C again to exit" prompt in the status line; the second confirms and exits. The prompt clears automatically after 2 seconds if you change your mind.

> **TUI features:** Type `/` to see autocomplete suggestions; press **Tab** / **Shift+Tab** to navigate and **Enter** to accept. A status line at the bottom of the terminal shows the current task state and retry/cycle counters in real time.

### How the loop works

```
ferrus> /task
  +- supervisor spawns -> you describe the task -> supervisor calls enqueue_task
       +- executor spawns (headless) -> implements -> check -> submit
            +- reviewer spawns (headless) -> reads submission -> approve or reject
                 +- approved -> Complete
                 +- rejected -> executor re-spawns with feedback
```

Agents are **stateless between runs**. Ferrus resolves each run to a SQLite task row and scoped artifacts under `.ferrus/tasks/` and `.ferrus/runs/`; each spawn exits when its job is done.

---

## State machine

```
pending
 +-> executing       addressing  work loop
       +-> consultation  (restore paused status)  awaiting_human  (restore paused status)  reviewing  addressing  complete  failed ]`

Scaffolds ferrus in the current project (default `--agents-path .agents`):

- Creates `ferrus.toml` with default limits and an empty check command list
- Creates `.ferrus/` templates, task/run artifact directories, `agents.json`, and `logs/`
- Registers the project in `~/.ferrus/projects//`
- Writes `.ferrus/project.toml` with the project id and local data directory
- Creates `~/.ferrus/projects//project.toml` with project metadata
- Creates `~/.ferrus/projects//ferrus.db` with `tasks`, `runs`, and `events` tables
- Creates `docs/specs/` for approved feature specifications
- Creates skill files agents load to understand their role:
  - `/skills/ferrus/SKILL.md` -- general overview
  - `/skills/ferrus-supervisor/SKILL.md` + `ROLE.md`
  - `/skills/ferrus-executor/SKILL.md` + `ROLE.md`
- Adds `.ferrus/` to `.gitignore`

### `ferrus serve [--role supervisor|executor] [--agent-name ] [--agent-index ]`

Starts the agent coordination server on stdio. Agents load this as an MCP server. `--agent-name` and `--agent-index` are embedded in the `claimed_by` field (e.g. `"executor:codex:1"`). Pass `--role` to expose only the tools for that role:

| `--role` | Tools exposed |
|---|---|
| `supervisor` | Definition sessions: `enqueue_task`, `create_spec`, `archive_spec`; task sessions: `wait_for_review`, `review_pending`, `approve`, `reject`, `wait_for_consultation`, `respond_consult`, `ask_human`, `wait_for_answer`, `heartbeat` |
| `executor` | `wait_for_task`, `check`, `consult`, `submit`, `wait_for_consult`, `ask_human`, `wait_for_answer`, `status`, `reset`, `heartbeat` |
| *(omitted)* | All tools |

All three server modes also expose the optional read-only repository retrieval tools
`repository_graph_status`, `repository_search`, and `repository_context`. They do not require a task lease and never
build an index or mutate task/run state.

The unfiltered server additionally exposes compatibility tools such as `create_task` and `answer`. The `status` tool includes scoped SQLite task context when called by a running agent with a resolved runtime identity.

### `ferrus register [--supervisor ] [--supervisor-model ] [--executor ] [--executor-model ]`

Writes agent config files so they automatically load `ferrus serve` as a tool server, and adds only the selected agents' local files to `.gitignore`. At least one of `--supervisor` or `--executor` is required; each model flag requires the matching role flag. Supported agents:

| Agent | Config written |
|---|---|
| `claude-code` | `.claude/mcp-supervisor.json` or `.claude/mcp-executor.json` + `.claude/settings.local.json` permissions |
| `codex` | `.codex/config.toml` |
| `qwen-code` | `.qwen/settings.json` |
| `opencode` | `opencode.json` |
| `goose` | none -- the Ferrus MCP server is attached at launch via `--with-extension` |

### `ferrus doctor`

Checks that `.ferrus/project.toml`, global project metadata, task/run artifacts, and the `ferrus.db` schema agree with the current workspace. It also reports interrupted runs and expired leases that can be fixed with `ferrus recover`.

### `ferrus graph`

The optional local repository graph indexes generic files/documents, Cargo metadata, and Rust syntax without
running repository code. Enable it explicitly in `ferrus.toml`:

```toml
[repository_graph]
enabled = true
```

Indexing is never part of `ferrus init`; run it when wanted:

```sh
ferrus graph index [--full] [--json]
ferrus graph status [--json]
ferrus graph search RuntimeTaskContext --kind struct --path src [--limit 20] [--json]
ferrus graph show --node  [--json]
ferrus graph show --symbol  [--json]
ferrus graph show --path src/project.rs [--json]
ferrus graph context (--node  | --symbol  | --path ) [--depth 2] [--max-results 50] [--json]
ferrus graph neighbors  --direction both --depth 2 --limit 50 [--kind contains] [--json]
```

`index` reuses unchanged per-file fragments by default; `--full` bypasses that cache. Completed snapshots are
immutable and published atomically, so a failed or stale build leaves the previous graph queryable. `status` is
read-only and reports absent or incompatible storage without creating it.

Every query reports the snapshot ID, freshness against the current source manifest, diagnostic counts,
repository-relative evidence spans, provenance, and any truncation. CLI limits are requests: configured
`[repository_graph.query_limits]` remain hard service caps. The derived sidecar is machine-local beside
`ferrus.db`; it stores structural facts and content identities, not source bodies.

Managed Executor worktrees use a task-owned graph view pinned to the dispatch baseline. `/check` and the final
submit gate refresh its changed-file overlay best-effort: unchanged fragments are reused, changed and added files
replace or extend the view, and deleted paths hide baseline facts. Task-view responses include both the baseline
snapshot, overlay revision, and mutable/frozen lifecycle; a graph refresh failure never changes task lifecycle
state. Submit freezes the successfully materialized view with an immutable Git tree in the same runtime
transaction as the Reviewing handoff. Reviewers and recovery sessions therefore reopen the exact submitted graph
and hash-verified snippets after the Executor worktree disappears; rejection preserves that run history while the
task resumes a mutable successor view.

Runtime identity selects the view explicitly: taskless/manual sessions use canonical, Executors use their mutable
task overlay, Consultants use the attached task view and Executor workspace, and Reviewers use the frozen view on
their review run. An invalid task binding or unavailable submitted freeze is reported instead of silently falling
back to canonical context.

Approval compares the actual canonical source manifest before and after patch application, integration checks,
spec updates, and any rollback. A changed post-operation manifest is durably marked stale with its source revision
and manifest identity. A clean rollback records no proposed integration; partial mutations remain stale and are
refreshed from the files actually left in canonical. Best-effort incremental indexing starts only after the
canonical approval lock is released, and its success or failure never changes the task approval outcome. A manual
`ferrus graph index` clears the same durable invalidation after publishing its verified snapshot.

Canonical and task refreshes are coordinated by expiring SQLite leases scoped to the exact published view, so
concurrent tasks cannot publish into one another's namespace and duplicate refreshes are suppressed across Ferrus
processes. Ordinary maintenance keeps every snapshot referenced by a non-terminal task/run (including frozen
review views) plus all published canonical snapshots. Completed-task publications and unreferenced snapshots age
out under `[repository_graph.retention]`; deleting a managed worktree never deletes a retained immutable baseline.
Interrupted builds never expose partial facts: `ferrus recover` marks only unfinished attempts failed, reclaims
expired graph refresh leases, and garbage-collects safe candidates without changing task lifecycle state.

Supervisor and Executor agents can inspect the same published graph through `repository_graph_status`, find exact
paths or symbols with `repository_search`, and assemble bounded deterministic evidence with `repository_context`.
Source snippets are opt-in and hash-verified against the indexed snapshot. Graph output is not automatically
injected into task or review prompts, and a missing relationship means only that the current index does not know it.

The normative retrieval behavior is documented in
[`docs/repository-graph-retrieval.md`](docs/repository-graph-retrieval.md). Local Criterion methodology and dogfood

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ferrus-dev](https://github.com/ferrus-dev)
- **Source:** [ferrus-dev/ferrus](https://github.com/ferrus-dev/ferrus)
- **License:** Apache-2.0
- **Homepage:** https://ferrus.dev

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-ferrus-dev-ferrus
- Seller: https://agentstack.voostack.com/s/ferrus-dev
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
