Skip to main content

Synopsis

The feral CLI is the primary interface for managing the FERAL brain, dashboard, and development tools. Global connection options apply to all subcommands:

Commands

feral (no subcommand)

Launch the interactive REPL. Connects to the brain via WebSocket and presents a chat prompt.
REPL slash-commands: /status, /devices, /skills, /identity, /quit.

feral "message"

One-shot mode. Sends a single message to the brain, prints the response, and exits.

feral start

Start the brain, wait for health, optionally open the dashboard in a browser, then drop into the interactive REPL. If this is the first run, the setup wizard launches automatically.

feral serve

Start only the brain API server (headless, no REPL, no browser).
Useful for production deployments or when running the dashboard separately.

feral setup

Run the interactive setup wizard.
Walks through LLM provider selection, API key storage, USER.md creation, and autonomy mode configuration. Generates a session token on first run. Safe to re-run — only overwrites values you change.

feral status

Show the current state of the running brain (sessions, devices, skills, LLM, audio, sync, memory).

feral devices

List all connected hardware devices.

feral skills

List all loaded skills.

feral identity

Show the agent’s name, personality, rules, and communication style.

feral pair

Manage per-node device pairing tokens for session authentication.

feral access

Manage pairing access mode and remote tunnel state.

feral wake-test

Test wake word detection from your microphone for 10 seconds.
Requires openwakeword and pyaudio. Reports detection count and mode (ML or energy-based fallback).

feral marketplace

Skill marketplace commands.

feral sync

Federated memory sync commands.

feral doctor

Run comprehensive diagnostics and report what’s working, what’s missing, and suggested fixes.
Checks: Python version, FERAL package, config directory, LLM credentials (keys + Ollama), identity files, memory database, port availability, Playwright/chromium, Node.js, local audio backends (faster-whisper, piper), and core dependencies.

feral update

Upgrade feral-ai in the environment that is actually running the brain, then restart it.
The upgrade targets sys.executable, the interpreter running this command, not whatever pip your PATH resolves first. That distinction is the point: a machine with more than one Python environment will happily upgrade the one that is not serving, which reads as an upgrade that did nothing. It refuses rather than half-works. A source checkout (pip install -e) is sent to git pull instead of pip. A brain running under a different interpreter than the CLI is reported, with the command that would work, rather than silently skipped. Running it when you are already current does nothing and says so. The restart afterwards is not decoration: a Python process never reloads its source, so an upgrade without a restart leaves the old code serving. It reuses feral restart. Checking for releases on a schedule is separate and off by default (see FERAL_UPDATE_CHECK in the environment reference). feral update asks the index when you run it, because running it is the request.

feral key

Manage per-provider API keys in the encrypted vault. Multiple labeled keys per provider are supported, and add probes the key before the prompt closes so you see green/red immediately.
Actions: add, list, remove, reset-cooldowns, recover.

feral models

List, test, and pin the chat model per provider.

feral voice

Inspect and test the STT / TTS / realtime voice catalogue. providers shows the same probe status the setup wizard’s voice preflight renders.

feral integrations

Connect and disconnect third-party accounts. OAuth providers support --self-hosted to use your own OAuth app instead of a first-party client.
Supported ids: gmail, google, notion, spotify, microsoft, home-assistant.

feral grant

Grant or revoke folder access for the computer_use file tools. Paths outside an active grant are refused, and grants apply immediately without a restart.

feral twin

Manage the digital twin’s per-domain policies and its approval queue.

feral checkpoints

Inspect or undo the file writes FERAL made, grouped by the user message (the “turn”) that caused them.
TURN_ID defaults to the most recent checkpointed turn. show prints the revert plan without touching a file. A file whose current content no longer matches what FERAL left there is reported as drifted and the revert refuses outright. --force overrides that and discards the newer content.
Checkpoints cover coding_tools__write_file and coding_tools__edit_file only. Anything coding_tools__bash changed (shell redirects, sed -i, formatters, package installs, git commands) is not reverted and is not tracked. Every command here prints that caveat on every invocation.
This command reads $FERAL_HOME/checkpoints/index.db directly and never calls the brain’s REST API, because the moment you most need an undo is the moment the brain is wedged. See Coding Harness.

feral memory

Memory backend, decay, and query management.

feral app

Build, sign, and publish GenUI app bundles.
sign uses your publisher key at ~/.feral/publisher.key; there is no --private-key flag.

feral app install asks first

Installing an app is two steps, because an app’s skill_dependencies install skills and a skill executes Python inside the brain. install calls POST /api/apps/preview, prints what it found, asks, and only then calls POST /api/apps/install with the install_token the preview minted. The route answers 403 preview_required without one, so there is no unattended path. What it prints, all of it served by the brain so the terminal and the web install sheet cannot drift:
  • the bundle’s signature status, and the app’s own reach (where its sandboxed surfaces may send data),
  • skills it will install: new code, each verified against its publisher’s signature, with what each one can reach,
  • skills you already have: nothing new runs, listed so the app’s full reach is visible,
  • skills FERAL cannot install: the brain’s own reason, the actions that will not work without them, and what to do about it.
A dependency FERAL cannot verify does not end the install. The app installs without it and GET /api/apps recomputes missing_skill_dependencies on every call, so the Apps page keeps showing the shortfall until the skill is there.
Exit codes: 0 installed, 1 declined or refused, 2 bad invocation. A non-TTY stdin never prompts. Piped or scripted, without --yes, it prints the disclosure, installs nothing and exits 2 naming the command that would work; an answer read off a pipe is not consent.

feral bridge

Install the phone-bridge daemon on this host.

feral install

Install a published skill or daemon from the FERAL registry. The argument is the item’s name (the skill_id for a skill, and what the catalog lists); the registry’s UUID also resolves, but nothing you type should be one.
A name that matches items of more than one kind, or versions the registry cannot order, is refused with a message naming what it found rather than resolved to an arbitrary pick. See Marketplace → Naming an item.

feral publish

Publish a skill or daemon bundle to the registry. --skill and --daemon are mutually exclusive and one is required.
The directory is the bundle: manifest.json at its root (a SkillManifest or DaemonManifest, not a registry envelope), with impl.py or your entrypoint beside it. The registry metadata is derived from that manifest, and the item publishes under its identifier: skill_id for a skill, node_id for a daemon. Your brand.name is a display name and is not the key. A publish is a submission. It lands submitted / private and is not installable until a reviewer approves it; the command prints the status it got back and the endpoint to track it. See Marketplace → Publish flow.

feral publisher

Manage the publisher identity used by feral publish.

Exit Codes