Dangerous command approval: run_command skill now checks commands
against 9 regex patterns (rm -rf /, dd, mkfs, fork bombs, shutdown,
device writes, etc.) and blocks execution with a clear message.
Defense-in-depth layer on top of VM isolation.
Cron agents: templates support schedule (5-field cron) and
schedule_timeout (seconds, default 300) fields. Overseer checks
every 60s, spawns {name}-cron agents on match, auto-destroys after
timeout. Inline cron parser supports *, ranges, lists, and steps.
No npm dependencies added.
Fireclaw
Multi-agent system powered by Firecracker microVMs. Each AI agent runs in its own hardware-isolated VM, connects to IRC, and responds via local LLMs.
What it does
Command runner: Execute arbitrary commands in ephemeral microVMs with KVM isolation.
$ fireclaw run "uname -a"
Linux 172.16.0.200 5.10.225 #1 SMP x86_64 Linux
Multi-agent system: Spawn AI agents as long-running VMs. Each agent connects to IRC, responds via Ollama, has tool access, and remembers across restarts.
# In IRC (#control):
<human> !invoke worker
<overseer> Agent "worker" started: worker [qwen2.5:7b] (172.16.0.2)
# In IRC (#agents):
<human> worker: what's your uptime?
<worker> System has been up for 3 minutes with load average 0.00.
# Private message:
/msg worker hello
<worker> Hey! How can I help?
# Hot-reload model:
<human> !model worker phi4-mini
<worker> [reloaded: model=phi4-mini]
Architecture
grogbox host
├── fireclaw overseer systemd service, IRC bot in #control
├── Ollama 0.0.0.0:11434, 5 models available
└── nyx.fireclaw.local ngircd IRC server (FireclawNet)
Firecracker VMs (fcbr0 bridge, 172.16.0.0/24)
├── worker (172.16.0.2) general assistant in #agents
├── coder (172.16.0.3) code-focused agent in #agents
└── research (172.16.0.4) research agent in #agents
Each agent VM:
- Runs a Python IRC bot (stdlib only, zero deps)
- Connects to nyx.fireclaw.local at 172.16.0.1:6667
- Calls Ollama at 172.16.0.1:11434 for LLM responses
- Has tool access — shell commands + podman containers
- Has persistent workspace at
/workspace(survives restarts) - Has persistent memory — saves/loads facts across restarts
- Accepts
/inviteto join any channel - Responds to DMs without mention
- Runs as unprivileged
agentuser - Is fully isolated from the host and other agents
Requirements
- Linux with KVM (
/dev/kvm) - Firecracker v1.15+ at
/usr/local/bin/firecracker sudoaccess (for tap devices, rootfs mounting)- Node.js 20+
- Ollama (for LLM responses)
- ngircd (for IRC)
Quick start
cd ~/projects/fireclaw
npm install
npm run build
sudo npm link
# One-time setup
fireclaw setup
fireclaw snapshot create
# Start the overseer (or use systemd)
sudo systemctl start fireclaw-overseer
# Connect to IRC and start spawning agents
# irssi -c localhost -n human
# /join #control
# !invoke worker
# /join #agents
# worker: hello!
IRC Channel Layout
| Channel | Purpose |
|---|---|
#control |
Overseer commands only (!invoke, !destroy, !list, etc.) |
#agents |
Common room — all agents join here |
/msg <nick> |
Private DM with an agent (no mention needed) |
/invite <nick> #room |
Pull an agent into any channel |
CLI Reference
fireclaw run [options] "<command>" Run a command in an ephemeral microVM
-t, --timeout <seconds> Command timeout (default: 60)
-v, --verbose Show boot/cleanup progress
--no-snapshot Force cold boot
fireclaw overseer [options] Start the overseer daemon
--server <host> IRC server (default: localhost)
--port <port> IRC port (default: 6667)
--nick <nick> Bot nickname (default: overseer)
--channel <chan> Control channel (default: #control)
fireclaw agent start <template> Start an agent VM
--name <name> Override agent name
--model <model> Override LLM model
fireclaw agent stop <name> Stop an agent VM
fireclaw agent list List running agents
fireclaw snapshot create Create VM snapshot for fast restores
fireclaw setup One-time setup
IRC Commands (via overseer in #control)
| Command | Description |
|---|---|
!invoke <template> [name] |
Spawn an agent VM |
!destroy <name> |
Kill an agent VM (graceful IRC QUIT) |
!list |
Show running agents |
!model <name> <model> |
Hot-reload agent's LLM model |
!templates |
List available agent templates |
!help |
Show commands |
Agent Templates
Templates live in ~/.fireclaw/templates/:
| Template | Nick | Model | Tools | Role |
|---|---|---|---|---|
| worker | worker | qwen2.5:7b | yes | General purpose |
| coder | coder | qwen2.5-coder:7b | yes | Code-focused |
| researcher | research | llama3.1:8b | yes | Thorough research |
| quick | quick | phi4-mini | no | Fast one-liners (~5s) |
| creative | muse | gemma3:4b | no | Writing, brainstorming |
Available Models
| Model | Size | Speed (CPU) | Tools | Best for |
|---|---|---|---|---|
| qwen2.5-coder:7b | 4.7 GB | ~15s | yes | Code tasks |
| qwen2.5:7b | 4.7 GB | ~15s | partial | General chat |
| llama3.1:8b | 4.9 GB | ~15s | partial | Instruction following |
| gemma3:4b | 3.3 GB | ~8s | no | Creative, balanced |
| phi4-mini | 2.5 GB | ~5s | no | Fast, simple answers |
Performance
| Mode | Time |
|---|---|
| Snapshot restore (ephemeral run) | ~1.1s |
| Cold boot (ephemeral run) | ~2.9s |
| Agent VM boot to IRC connect | ~5s |
Security Model
- Agent processes run as unprivileged
agentuser inside VMs - Root SSH retained for overseer management only
- Each VM gets hardware-level KVM isolation
- Persistent workspace is per-agent — no cross-agent access
- Overseer runs on host (trusted), agents in VMs (untrusted)
- Agent-to-agent cooldown (10s) prevents infinite loops
- Graceful shutdown — agents send IRC QUIT before VM kill
Source Files
src/
index.ts Entry point
cli.ts CLI commands (commander)
vm.ts Ephemeral VM lifecycle (cold boot + snapshot)
firecracker-api.ts Firecracker REST client
snapshot.ts Snapshot creation workflow
overseer.ts Overseer daemon (IRC + agent lifecycle)
agent-manager.ts Start/stop/list/reload agent VMs
network.ts Bridge, tap devices, IP allocation
rootfs.ts Image copy, SSH key injection
ssh.ts SSH execution (ssh2)
cleanup.ts Signal handlers
config.ts Constants, paths
types.ts Interfaces
setup.ts One-time setup
agent/
agent.py Python IRC bot (stdlib only, baked into rootfs)
scripts/
setup-bridge.sh Create fcbr0 bridge + NAT rules
teardown-bridge.sh Remove bridge + NAT rules
tests/
test-suite.sh Regression tests (20 tests)
Data Directory
~/.fireclaw/
vmlinux Firecracker kernel (5.10)
base-rootfs.ext4 Alpine base (ephemeral runs)
agent-rootfs.ext4 Agent image (1 GiB sparse, Alpine + Python + podman)
snapshot-rootfs.ext4 Snapshot rootfs
snapshot.{state,mem} VM snapshot
id_ed25519[.pub] SSH keypair
agents.json Running agent state
templates/ Agent persona templates
workspaces/ Persistent agent storage (64 MiB ext4 each)
runs/ Per-agent rootfs copies
ip-pool.json IP allocation
Agent Workspace (inside VM at /workspace)
/workspace/
MEMORY.md Memory index — loaded into system prompt
memory/
user_prefs.md Learned facts about users
project_x.md Ongoing project context
Testing
# Requires overseer running via systemd
./tests/test-suite.sh
20 tests covering: overseer commands, agent lifecycle, IRC interaction, tool access, error handling, CLI operations, crash recovery, graceful shutdown.
Known Limitations
- Snapshot mode doesn't support concurrent ephemeral runs (single fixed IP/tap)
sudorequired for tap device and rootfs mount operations- CPU inference: 5-30s per response depending on model
- No thin provisioning — full rootfs copy per agent (~146 MiB)
License
Apache-2.0
Description
Languages
TypeScript
46.9%
Shell
26.9%
Python
25.7%
JavaScript
0.5%