Corvus ๐ฆโโฌ
Fast, small, and fully autonomous AI assistant infrastructure โ deploy anywhere, swap anything.
[!IMPORTANT]
~3.4MB binary ยท <10ms startup ยท 1,017 tests ยท 22+ providers ยท 8 traits ยท Pluggable everything
โจ Features
- ๐๏ธ Ultra-Lightweight: <5MB Memory footprint โ 99% smaller than OpenClaw core.
- ๐ฐ Minimal Cost: Efficient enough to run on $10 Hardware โ 98% cheaper than a Mac mini.
- โก Lightning Fast: 400X Faster startup time, boot in <10ms (under 1s even on 0.6GHz cores).
- ๐ True Portability: Single self-contained binary across ARM, x86, and RISC-V.
Why teams pick Corvus
- Lean by default: small Rust binary, fast startup, low memory footprint.
- Secure by design: pairing, strict sandboxing, explicit allowlists, workspace scoping.
- Fully swappable: core systems are traits (providers, channels, tools, memory, tunnels).
- No lock-in: OpenAI-compatible provider support + pluggable custom endpoints.
Benchmark Snapshot (Corvus vs OpenClaw)
Local machine quick benchmark (macOS arm64, Feb 2026) normalized for 0.8GHz edge hardware.
| OpenClaw | NanoBot | PicoClaw | Corvus ๐ฆ | |
|---|---|---|---|---|
| Language | TypeScript | Python | Go | Rust |
| RAM | > 1GB | > 100MB | < 10MB | < 5รMB |
| Startup (0.8GHz core) | > 500s | > 30s | < 1s | < 10ms |
| Binary Size | ~28MB (dist) | N/A (Scripts) | ~8MB | 3.4 MB |
| Cost | Mac Mini $599 | Linux SBC ~$50 | Linux Board $10 | Any hardware $10 |
Notes: Corvus results measured with
/usr/bin/time -lon release builds. OpenClaw requires Node.js runtime (~390MB overhead). PicoClaw and Corvus are static binaries.
Reproduce Corvus numbers locally:
Quick Start
Use Corvus without compiling Rust locally:
Or install globally via your package manager:
Docker Compose (local-first dashboard)
# From clients/agent-runtime
# Edit API_KEY (and optional provider/model) in your local compose/env
# Gateway only
# Gateway + dashboard
Open:
- Gateway:
http://localhost:3000 - Dashboard:
http://localhost:4324
Then pair in dashboard via /pair and use the returned bearer token for admin config actions.
Build from source (Rust toolchain):
# Enable SurrealDB memory backend support
# Quick setup (no prompts)
# Or interactive wizard
# Or quickly repair channels/allowlists only
# Chat
# Interactive mode
# Start the gateway (webhook server)
# Start full autonomous runtime
# Check status
# Run system diagnostics
# Check channel health
# Get integration setup details
# Manage background service
# Migrate memory from OpenClaw (safe preview first)
Corvus also checks for newer releases in agent, daemon, and status commands.
Set CORVUS_DISABLE_UPDATE_CHECK=1 to disable update notifications.
Dev fallback (no global install): prefix commands with
cargo run --release --(example:cargo run --release -- status).
Architecture
Every subsystem is a trait โ swap implementations with a config change, zero code changes.
| Subsystem | Trait | Ships with | Extend |
|---|---|---|---|
| AI Models | Provider |
22+ providers (OpenRouter, Anthropic, OpenAI, Ollama, Venice, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, etc.) | custom:https://your-api.com โ any OpenAI-compatible API |
| Channels | Channel |
CLI, Telegram, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook | Any messaging API |
| Memory | Memory |
SQLite (hybrid search), SurrealDB (feature: memory-surreal), Markdown |
Any persistence backend |
| Tools | Tool |
shell, file_read, file_write, memory_store, memory_recall, memory_forget, browser_open (Brave + allowlist), composio (optional) | Any capability |
| Observability | Observer |
Noop, Log, Multi | Prometheus, OTel |
| Runtime | RuntimeAdapter |
Native, Docker (sandboxed) | WASM (planned; unsupported kinds fail fast) |
| Security | SecurityPolicy |
Gateway pairing, sandbox, allowlists, rate limits, filesystem scoping, encrypted secrets | โ |
| Identity | IdentityConfig |
OpenClaw (markdown), AIEOS v1.1 (JSON) | Any identity format |
| Tunnel | Tunnel |
None, Cloudflare, Tailscale, ngrok, Custom | Any tunnel binary |
| Heartbeat | Engine | HEARTBEAT.md periodic tasks | โ |
| Skills | Loader | TOML manifests + SKILL.md instructions | Community skill packs |
| Integrations | Registry | 50+ integrations across 9 categories | Plugin system |
Runtime support (current)
- โ
Supported today:
runtime.kind = "native"orruntime.kind = "docker" - ๐ง Planned, not implemented yet: WASM / edge runtimes
When an unsupported runtime.kind is configured, Corvus now exits with a clear error instead of
silently falling back to native.
Memory System (Full-Stack Search Engine)
All custom, zero external dependencies โ no Pinecone, no Elasticsearch, no LangChain:
| Layer | Implementation |
|---|---|
| Vector DB | Embeddings stored as BLOB in SQLite, cosine similarity search |
| Keyword Search | FTS5 virtual tables with BM25 scoring |
| Hybrid Merge | Custom weighted merge function (vector.rs) |
| Embeddings | EmbeddingProvider trait โ OpenAI, custom URL, or noop |
| Chunking | Line-based markdown chunker with heading preservation |
| Caching | SQLite embedding_cache table with LRU eviction |
| Safe Reindex | Rebuild FTS5 + re-embed missing vectors atomically |
The agent automatically recalls, saves, and manages memory via tools.
[]
= "sqlite" # "sqlite", "lucid", "surreal", "markdown", "none"
= true
= "openai"
= 0.7
= 0.3
[]
= "http://127.0.0.1:8000"
= "corvus"
= "memory"
= true
Security
Corvus enforces security at every layer โ not just the sandbox. It passes all items from the community security checklist.
Security Checklist
| # | Item | Status | How |
|---|---|---|---|
| 1 | Gateway not publicly exposed | โ | Binds 127.0.0.1 by default. Refuses 0.0.0.0 without tunnel or explicit allow_public_bind = true. |
| 2 | Pairing required | โ | 6-digit one-time code on startup. Exchange via POST /pair for bearer token. All /webhook requests require Authorization: Bearer <token>. |
| 3 | Filesystem scoped (no /) | โ | workspace_only = true by default. 14 system dirs + 4 sensitive dotfiles blocked. Null byte injection blocked. Symlink escape detection via canonicalization + resolved-path workspace checks in file read/write tools. |
| 4 | Access via tunnel only | โ | Gateway refuses public bind without active tunnel. Supports Tailscale, Cloudflare, ngrok, or any custom tunnel. |
Run your own nmap:
nmap -p 1-65535 <your-host>โ Corvus binds to localhost only, so nothing is exposed unless you explicitly configure a tunnel.
Channel allowlists (Telegram / Discord / Slack)
Inbound sender policy is now consistent:
- Empty allowlist = deny all inbound messages
"*"= allow all (explicit opt-in)- Otherwise = exact-match allowlist
This keeps accidental exposure low by default.
Recommended low-friction setup (secure + fast):
- Telegram: allowlist your own
@username(without@) and/or your numeric Telegram user ID. - Discord: allowlist your own Discord user ID.
- Slack: allowlist your own Slack member ID (usually starts with
U). - Use
"*"only for temporary open testing.
If you're not sure which identity to use:
- Start channels and send one message to your bot.
- Read the warning log to see the exact sender identity.
- Add that value to the allowlist and rerun channels-only setup.
If you hit authorization warnings in logs (for example: ignoring message from unauthorized user),
rerun channel setup only:
WhatsApp Business Cloud API Setup
WhatsApp uses Meta's Cloud API with webhooks (push-based, not polling):
- Create a Meta Business App:
- Open the WhatsApp Business Platform page from Meta and create an app
- Create a new app โ Select "Business" type
- Add the "WhatsApp" product
- Get your credentials:
- Access Token: From WhatsApp โ API Setup โ Generate token (or create a System User for permanent tokens)
- Phone Number ID: From WhatsApp โ API Setup โ Phone number ID
- Verify Token: You define this (any random string) โ Meta will send it back during webhook verification
-
Configure Corvus:
[] = "EAABx..." = "123456789012345" = "my-secret-verify-token" = ["+1234567890"] # E.164 format, or ["*"] for all -
Start the gateway with a tunnel:
WhatsApp requires HTTPS, so use a tunnel (ngrok, Cloudflare, Tailscale Funnel).
-
Configure Meta webhook:
- In Meta Developer Console โ WhatsApp โ Configuration โ Webhook
- Callback URL:
https://your-tunnel-url/whatsapp - Verify Token: Same as your
verify_tokenin config - Subscribe to
messagesfield
- Test: Send a message to your WhatsApp Business number โ Corvus will respond via the LLM.
Configuration
Config: ~/.corvus/config.toml (created by onboard; wizard now includes SurrealDB prompts when
available)
= "sk-..."
= "openrouter"
= "anthropic/claude-sonnet-4-20250514"
= 0.7
[]
= "sqlite" # "sqlite", "lucid", "surreal", "markdown", "none"
= true
= "openai" # "openai", "noop"
= 0.7
= 0.3
[]
= "http://127.0.0.1:8000"
= "corvus"
= "memory"
# username = "corvus"
# password = "corvus-pass"
# token = "..." # preferred over username/password when set
= true
[]
= true # require pairing code on first connect
= false # refuse 0.0.0.0 without tunnel
[]
= "supervised" # "readonly", "supervised", "full" (default: supervised)
= true # default: true โ scoped to workspace
= ["git", "npm", "cargo", "ls", "cat", "grep"]
= ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]
[]
= "native" # "native" or "docker"
[]
= "alpine:3.20" # container image for shell execution
= "none" # docker network mode ("none", "bridge", etc.)
= 512 # optional memory limit in MB
= 1.0 # optional CPU limit
= true # mount root filesystem as read-only
= true # mount workspace into /workspace
= [] # optional allowlist for workspace mount validation
[]
= false
= 30
[]
= "none" # "none", "cloudflare", "tailscale", "ngrok", "custom"
[]
= true # API keys encrypted with local key file
[]
= false # opt-in browser_open tool
= ["docs.rs"] # required when browser is enabled
[]
= false # opt-in: 1000+ OAuth apps via composio.dev
[]
= "openclaw" # "openclaw" (default, markdown files) or "aieos" (JSON)
# aieos_path = "identity.json" # path to AIEOS JSON file (relative to workspace or absolute)
# aieos_inline = '{"identity":{"names":{"first":"Nova"}}}' # inline AIEOS JSON
SurrealDB environment overrides (env-first):
# optional:
Identity System (AIEOS Support)
Corvus supports identity-agnostic AI personas through two formats:
OpenClaw (Default)
Traditional markdown files in your workspace:
IDENTITY.mdโ Who the agent isSOUL.mdโ Core personality and valuesUSER.mdโ Who the agent is helpingAGENTS.mdโ Behavior guidelines
AIEOS (AI Entity Object Specification)
AIEOS is a standardization framework for portable AI identity. Corvus supports AIEOS v1.1 JSON payloads, allowing you to:
- Import identities from the AIEOS ecosystem
- Export identities to other AIEOS-compatible systems
- Maintain behavioral integrity across different AI models
Enable AIEOS
[]
= "aieos"
= "identity.json" # relative to workspace or absolute path
Or inline JSON:
[]
= "aieos"
= '''
{
"identity": {
"names": { "first": "Nova", "nickname": "N" }
},
"psychology": {
"neural_matrix": { "creativity": 0.9, "logic": 0.8 },
"traits": { "mbti": "ENTP" },
"moral_compass": { "alignment": "Chaotic Good" }
},
"linguistics": {
"text_style": { "formality_level": 0.2, "slang_usage": true }
},
"motivations": {
"core_drive": "Push boundaries and explore possibilities"
}
}
'''
AIEOS Schema Sections
| Section | Description |
|---|---|
identity |
Names, bio, origin, residence |
psychology |
Neural matrix (cognitive weights), MBTI, OCEAN, moral compass |
linguistics |
Text style, formality, catchphrases, forbidden words |
motivations |
Core drive, short/long-term goals, fears |
capabilities |
Skills and tools the agent can access |
physicality |
Visual descriptors for image generation |
history |
Origin story, education, occupation |
interests |
Hobbies, favorites, lifestyle |
See the AIEOS specification for the full schema and examples.
Gateway API
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/health |
GET | None | Health check (always public, no secrets leaked) |
/pair |
POST | X-Pairing-Code header |
Exchange one-time code for bearer token |
/webhook |
POST | Authorization: Bearer <token> |
Send message: {"message": "your prompt"} |
/whatsapp |
GET | Query params | Meta webhook verification (hub.mode, hub.verify_token, hub.challenge) |
/whatsapp |
POST | None (Meta signature) | WhatsApp incoming message webhook |
Commands
| Command | Description |
|---|---|
onboard |
Quick setup (default) |
onboard --interactive |
Full interactive 7-step wizard (includes memory backend + Surreal options) |
onboard --channels-only |
Reconfigure channels/allowlists only (fast repair flow) |
agent -m "..." |
Single message mode |
agent |
Interactive chat mode |
gateway |
Start webhook server (default: 127.0.0.1:8080) |
gateway --port 0 |
Random port mode |
daemon |
Start long-running autonomous runtime |
service install/start/restart/stop/status/uninstall |
Manage background service lifecycle |
doctor |
Diagnose daemon/scheduler/channel freshness |
status |
Show full system status |
channel doctor |
Run health checks for configured channels |
integrations info <name> |
Show setup/status details for one integration |
Development
# Run the SQLite vs Markdown benchmark
Pre-push hook
A git hook runs cargo fmt --check, cargo clippy -- -D warnings, and cargo test before every
push.
To skip the hook when you need a quick push during development: