Install
$ agentstack add mcp-romanemreis-ferrus Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Pipes remote content directly into a shell (remote code execution).
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
ferrus
[](https://crates.io/crates/ferrus) [](https://releases.rs/docs/1.95.0/) [](https://github.com/RomanEmreis/ferrus/blob/main/LICENSE) [](https://github.com/RomanEmreis/ferrus/actions/workflows/rust.yml) [](https://github.com/RomanEmreis/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
- 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) withgoose 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 exportingGOOSE_MAX_TURNSbefore launching Ferrus. Tool-calling reliability depends heavily on the local model. - opencode (experimental) — convenient for running local models. ⚠️ 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.
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:
cargo install ferrus
# or on Linux/macOS:
curl -fsSL https://github.com/RomanEmreis/ferrus/releases/latest/download/install.sh | sh
# or on Windows:
iwr https://github.com/RomanEmreis/ferrus/releases/latest/download/install.ps1 -useb | iex
Run:
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 | | /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 ← /wait_for_task claim
├─► addressing ← /reject → work loop
├─► consultation ← /consult
│ └─► (restore paused status) ← /wait_for_consult
├─► awaiting_human ← /ask_human
│ └─► (restore paused status) ← /wait_for_answer
├─► reviewing ← /submit final gate pass
│ ├─► addressing ← /reject
│ └─► complete ← /approve
└─► failed ← retry or review-cycle limit
Any active Executor work state (Executing, Addressing) can pause to Consultation via /consult. HQ spawns the configured Supervisor in consultation mode, and the executor immediately calls /wait_for_consult to block until the Supervisor answers via /respond_consult.
Any active state, including Consultation, can pause to AwaitingHuman via /ask_human. The agent immediately calls /wait_for_answer to block until the human responds. The human types their answer in the HQ terminal (raw text, no slash prefix). /wait_for_answer restores the previous state and returns the answer.
- Each task advances independently;
max_parallel_taskscontrols concurrent executors. - HQ
/resetforce-resets resettable tasks and clears their scoped artifacts. MCP/resetis only valid for a failed task.
CLI reference
ferrus init [--agents-path ]
Scaffolds ferrus in the current project (default --agents-path .agents):
- Creates
ferrus.tomlwith default limits and an empty check command list - Creates
.ferrus/templates, task/run artifact directories,agents.json, andlogs/ - Registers the project in
~/.ferrus/projects// - Writes
.ferrus/project.tomlwith the project id and local data directory - Creates
~/.ferrus/projects//project.tomlwith project metadata - Creates
~/.ferrus/projects//ferrus.dbwithtasks,runs, andeventstables - 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; 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 |
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 projects list
Lists projects registered under ~/.ferrus/projects, including project id, name, database presence, last opened timestamp, workspace path, and data directory.
ferrus recover
Runs the same runtime recovery that HQ performs on startup: dead running rows are marked interrupted, expired task leases without a live run are released, and recorded human answers are reconciled.
Use ferrus recover --dry-run to print the pending recovery counters without changing runtime state. Use ferrus recover --worktrees to also remove orphaned managed task worktrees that no active task or active run still owns. Combine it with --dry-run to preview the orphan count without removing anything.
ferrus tasks list
Prints task runtime rows from ferrus.db, including task status, active claim owner, lease expiry, and artifact path.
ferrus runs list [--limit N]
Prints recent run attempts from ferrus.db, including role, agent, status, PID, timestamps, and workspace path.
ferrus events list [--limit N] [--run ]
Prints recent runtime events from ferrus.db. Use --run or --run-id to filter to one run attempt.
ferrus migrate / ferrus upgrade
Registers an existing pre-registry project in ~/.ferrus/projects//, initializes the SQLite database, creates .ferrus/tasks/ and .ferrus/runs/, and imports non-empty legacy task, review, submission, human-question, and consultation artifacts into the scoped layout.
ferrus.toml
[checks]
commands = [
"cargo clippy -- -D warnings",
"cargo fmt --check",
"cargo test",
]
[limits]
max_check_retries = 20 # consecutive check failures before state → Failed
max_review_cycles = 3 # reject→fix cycles before state → Failed
max_feedback_lines = 30 # trailing lines per failing command shown in /check and /submit output
wait_timeout_secs = 60 # max duration of one wait_* tool call before it returns timeout so the agent can poll again
max_parallel_tasks = 1 # maximum number of concurrent executor sessions
[lease]
ttl_secs = 90 # how long a claimed lease is valid without renewal
heartbeat_interval_secs = 30 # how often agents should call heartbeat
[spec]
directory = "docs/specs" # where /create_spec writes approved specs
[hq.supervisor]
agent = "claude-code" # agent for supervisor/reviewer role: claude-code | codex | qwen-code | goose | opencode
model = "" # optional override; empty = agent default
[hq.executor]
agent = "codex" # agent for executor role: claude-code | codex | qwen-code | goose (experimental); opencode executor is experimental/unstable — see Supported agents
model = "" # optional override; empty = agent default
Check commands run in the active task workspace. Full output is written to .ferrus/logs/check___.txt, where the task/run scope prevents parallel checks from overwriting each other. /check and /submit return a short failure summary inline.
Runtime files
Ferrus now separates human-readable project artifacts from machine-local runtime state:
| Path | Contents | |---|---| | .ferrus/ | Project-local templates, task/run artifacts, agent registry, and logs | | ~/.ferrus/projects// | Machine-local project metadata, SQLite runtime database, and global logs |
SQLite is the runtime source of truth. ferrus.db stores task status, claims and leases, run ownership, lifecycle events, retry counters, paused interaction metadata, and selected-spec state. Markdown files are scoped task intent and run artifacts, not a mirrored state machine. On HQ startup Ferrus marks dead active runs as interrupted, preserves leases backed by live runs, releases other expired leases, and resumes recoverable task flows.
.ferrus/
| File | Contents | |---|---| | project.toml | Local pointer to ~/.ferrus/projects// | | agents.json | Runtime registry for agent sessions, statuses, PIDs, and log ownership | | TASK.md | Task drafting template | | CONSULT_TEMPLATE.md | Read-only consultation request template |
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: RomanEmreis
- Source: RomanEmreis/ferrus
- License: Apache-2.0
- Homepage: https://ferrus.dev
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.