Skip to content

icojerrel/zeroclaw

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ZeroClaw

ZeroClaw πŸ¦€

Zero overhead. Zero compromise. 100% Rust. 100% Agnostic.

License: MIT

The fastest, smallest, fully autonomous AI assistant β€” deploy anywhere, swap anything.

~3.4MB binary Β· <10ms startup Β· 1,017 tests Β· 22+ providers Β· 8 traits Β· Pluggable everything

Quick Start

git clone https://github.com/theonlyhennygod/zeroclaw.git
cd zeroclaw
cargo build --release

# Initialize config + workspace
cargo run --release -- onboard

# Set your API key
export OPENROUTER_API_KEY="sk-..."

# Chat
cargo run --release -- agent -m "Hello, ZeroClaw!"

# Interactive mode
cargo run --release -- agent

# Start the gateway (webhook server)
cargo run --release -- gateway                # default: 127.0.0.1:8080
cargo run --release -- gateway --port 0       # random port (security hardened)

# Check status
cargo run --release -- status --verbose

# List tools (includes memory tools)
cargo run --release -- tools list

# Test a tool directly
cargo run --release -- tools test memory_store '{"key": "lang", "content": "User prefers Rust"}'
cargo run --release -- tools test memory_recall '{"query": "Rust"}'

# List integrations
cargo run --release -- integrations list

Tip: Run cargo install --path . to install zeroclaw globally, then use zeroclaw instead of cargo run --release --.

Architecture

Every subsystem is a trait β€” swap implementations with a config change, zero code changes.

ZeroClaw Architecture

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, Webhook Any messaging API
Memory Memory SQLite with hybrid search (FTS5 + vector cosine similarity), Markdown Any persistence backend
Tools Tool shell, file_read, file_write, memory_store, memory_recall, memory_forget, composio (optional) Any capability
Observability Observer Noop, Log, Multi Prometheus, OTel
Runtime RuntimeAdapter Native (Mac/Linux/Pi) Docker, WASM
Security SecurityPolicy Gateway pairing, sandbox, allowlists, rate limits, filesystem scoping, encrypted secrets β€”
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

Memory System

ZeroClaw has a built-in brain. The agent automatically:

  1. Recalls relevant memories before each prompt (hybrid FTS5 + vector search with context injection)
  2. Saves conversation turns to memory (auto-save with embeddings)
  3. Manages its own memory via tools (store/recall/forget)

The default SQLite backend includes:

  • FTS5 full-text search with BM25 ranking for keyword queries
  • Vector embeddings (OpenAI or pluggable) with cosine similarity for semantic search
  • Hybrid merge β€” weighted combination of keyword + vector results (configurable: 0.3/0.7 default)
  • Embedding cache with LRU eviction (default: 10,000 entries)
  • Markdown-aware chunking β€” splits documents by headings, respects token limits
  • LIKE fallback when FTS5 and vector return no results
  • Upsert, delete, reindex β€” full CRUD with automatic embedding refresh

Markdown backend available for human-readable, append-only, git-friendly storage.

Switch with one config line:

[memory]
backend = "sqlite"          # "sqlite", "markdown", "none"
auto_save = true
embedding_provider = "openai"
vector_weight = 0.7
keyword_weight = 0.3

Security

ZeroClaw 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.
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> β€” ZeroClaw binds to localhost only, so nothing is exposed unless you explicitly configure a tunnel.

Layer 1: Gateway Hardening

# Default β€” localhost only, pairing required
zeroclaw gateway

# Random port β€” OS assigns ephemeral port (49152-65535)
zeroclaw gateway --port 0

# With tunnel β€” public access via secure tunnel only
zeroclaw gateway  # with [tunnel] configured

On startup, the gateway prints a 6-digit pairing code:

πŸ” PAIRING REQUIRED β€” use this one-time code:
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  482917  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   Send: POST /pair with header X-Pairing-Code: 482917

After pairing, all subsequent requests use Authorization: Bearer zc_<token>.

[gateway]
require_pairing = true      # default: true
allow_public_bind = false   # default: false β€” NEVER set true without tunnel

Layer 2: Channel Authentication

Every channel validates the sender before the message reaches the agent loop:

Channel Auth Method Config
Telegram allowed_users list (username match) [channels.telegram] allowed_users
Discord allowed_users list (user ID match) [channels.discord] allowed_users
Slack allowed_users list (user ID match) [channels.slack] allowed_users
Matrix allowed_users list (MXID match) [channels.matrix] allowed_users
iMessage allowed_contacts list [channels.imessage] allowed_contacts
Webhook X-Webhook-Secret header (shared secret) [channels.webhook] secret
CLI Local-only (inherently trusted) β€”

Note: An empty allowed_users list or ["*"] allows all users (open mode). Set specific IDs for production.

Layer 3: Rate Limiting

  • Sliding-window tracker β€” counts actions within a 1-hour rolling window
  • max_actions_per_hour β€” hard cap on tool executions (default: 20)
  • max_cost_per_day_cents β€” daily cost ceiling (default: $5.00)

Layer 4: Filesystem Sandbox

  • Workspace-only mode (default) β€” all paths must be relative to workspace
  • 14 system directories blocked β€” /etc, /root, /home, /usr, /bin, /sbin, /lib, /opt, /boot, /dev, /proc, /sys, /var, /tmp
  • 4 sensitive dotfiles blocked β€” ~/.ssh, ~/.gnupg, ~/.aws, ~/.config
  • Null byte injection β€” blocked at the path validation layer
  • Path traversal β€” .. in any position is rejected
  • Symlink escape detection β€” is_resolved_path_allowed() verifies canonicalized paths stay inside workspace
  • Command allowlisting β€” only approved shell commands (git, cargo, ls, etc.)
  • Autonomy levels β€” ReadOnly, Supervised (default), Full

Layer 5: Secure Tunnels

Expose your gateway securely β€” bring your own tunnel provider:

Provider Binary Use Case
none β€” Local-only (default)
cloudflare cloudflared Cloudflare Zero Trust tunnel
tailscale tailscale Tailnet-only (serve) or public (funnel)
ngrok ngrok Quick public URLs, custom domains
custom Any Bring your own: bore, frp, ssh, WireGuard, etc.
[tunnel]
provider = "tailscale"   # "none", "cloudflare", "tailscale", "ngrok", "custom"

[tunnel.tailscale]
funnel = true            # true = public internet, false = tailnet only

# Or use Cloudflare:
# [tunnel]
# provider = "cloudflare"
# [tunnel.cloudflare]
# token = "your-tunnel-token"

# Or ngrok:
# [tunnel]
# provider = "ngrok"
# [tunnel.ngrok]
# auth_token = "your-ngrok-token"
# domain = "my-zeroclaw.ngrok.io"  # optional

# Or bring your own:
# [tunnel]
# provider = "custom"
# [tunnel.custom]
# start_command = "bore local {port} --to bore.pub"
# url_pattern = "https://"         # regex to extract URL from stdout
# health_url = "http://localhost:4040/api/tunnels"  # optional

The tunnel starts automatically with zeroclaw gateway and prints the public URL.

Composio Integration (Optional)

ZeroClaw can optionally connect to 1000+ apps via Composio managed OAuth β€” Gmail, Notion, GitHub, Slack, Google Calendar, and more. Your core agent stays local; Composio handles OAuth tokens.

[composio]
enabled = true
api_key = "enc:a1b2c3..."   # encrypted with local key
entity_id = "default"

The setup wizard asks: Sovereign (local only) vs Composio (managed OAuth).

Mode Pros Cons
Sovereign Full privacy, no external deps You manage every API key
Composio 1000+ OAuth apps, revocable tokens Composio API key required

Use the composio tool from the agent:

> List my Gmail actions
> Execute GMAIL_FETCH_EMAILS
> Connect my Notion account

Encrypted Secrets

API keys in config.toml are encrypted by default using a local key file (~/.zeroclaw/.secret_key, mode 0600).

  • Encrypted values are prefixed with enc: followed by hex-encoded ciphertext
  • Plaintext values (backward compatible) are used as-is β€” no prefix
  • Disable with secrets.encrypt = false if you prefer plaintext
[secrets]
encrypt = true   # default: true β€” API keys stored encrypted

This prevents:

  • Plaintext API key exposure in config files
  • Accidental git commit of raw keys
  • Casual grep / log scraping attacks

Configuration

Config: ~/.zeroclaw/config.toml (created by onboard)

api_key = "sk-..."
default_provider = "openrouter"
default_model = "anthropic/claude-sonnet-4-20250514"
default_temperature = 0.7

[memory]
backend = "sqlite"              # "sqlite", "markdown", "none"
auto_save = true
embedding_provider = "openai"   # "openai", "noop"
vector_weight = 0.7
keyword_weight = 0.3

[gateway]
require_pairing = true          # require pairing code on first connect
allow_public_bind = false       # refuse 0.0.0.0 without tunnel

[autonomy]
level = "supervised"            # "readonly", "supervised", "full"
workspace_only = true
allowed_commands = ["git", "npm", "cargo", "ls", "cat", "grep"]
forbidden_paths = ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]

[heartbeat]
enabled = false
interval_minutes = 30

[tunnel]
provider = "none"               # "none", "cloudflare", "tailscale", "ngrok", "custom"

[composio]
enabled = false                 # opt-in: managed OAuth tools via Composio
# api_key = "enc:..."           # set via onboard wizard or manually

[secrets]
encrypt = true                  # encrypt API keys in config.toml

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"}

Random Port Mode

Use --port 0 for OS-assigned random ephemeral ports (security hardening against port scanning):

zeroclaw gateway --port 0
# Output: πŸ¦€ ZeroClaw Gateway listening on http://127.0.0.1:54321 (random port)

The actual port is printed on startup and passed to the tunnel system automatically.

Commands

Command Description
onboard Interactive setup wizard
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
status -v Show full system status
tools list List all 7 tools (6 core + composio if enabled)
tools test <name> <json> Test a tool directly
integrations list List all 50+ integrations

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt Use this file to discover all available pages before exploring further.

Token Use & Costs

ZeroClaw tracks tokens, not characters. Tokens are model-specific, but most OpenAI-style models average ~4 characters per token for English text.

How the system prompt is built

ZeroClaw assembles its own system prompt on every run. It includes:

  • Tool list + short descriptions
  • Skills list (only metadata; instructions are loaded on demand with read)
  • Safety guardrails
  • Workspace + bootstrap files (AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md when new, plus MEMORY.md). Large files are truncated at 20,000 characters. memory/*.md files are on-demand via memory tools and are not auto-injected.
  • Time (UTC + user timezone)
  • Runtime metadata (host/OS/model)

What counts in the context window

Everything the model receives counts toward the context limit:

  • System prompt (all sections listed above)
  • Conversation history (user + assistant messages)
  • Tool calls and tool results
  • Memory context (injected before each prompt via hybrid recall)
  • Provider wrappers or safety headers (not visible, but still counted)

Tips for reducing token pressure

  • Use smaller models for verbose, exploratory work
  • Trim large tool outputs in your workflows
  • Keep skill descriptions short (skill list is injected into the prompt)
  • Adjust auto_save to avoid excessive memory growth

Development

cargo build              # Dev build
cargo build --release    # Release build (~3.4MB)
cargo test               # 1,017 tests
cargo clippy             # Lint (0 warnings)
cargo fmt                # Format

# Run the SQLite vs Markdown benchmark
cargo test --test memory_comparison -- --nocapture

Test Coverage

Module Tests Covers
Memory (SQLite) 100+ FTS5, vector search, hybrid merge, embeddings, chunker, SQL injection, unicode
Security (Policy) 50+ Path traversal, null bytes, forbidden dirs, workspace scoping, symlink escapes
Security (Pairing) 20+ Code generation, token issuance, constant-time comparison, replay prevention
Gateway 20+ Port 0, random port allocation, header extraction, port conflicts
Config 30+ Serde roundtrip, backward compat, secure defaults, gateway config
Providers 30+ Factory, custom URLs, auth styles
Tools 20+ Schema validation, tool specs, serde
Integrations 15+ Registry completeness, status functions, categories
Tunnel 20+ Factory, constructors, async behavior

Project Structure

src/
β”œβ”€β”€ main.rs              # CLI (clap) β€” 10 subcommands
β”œβ”€β”€ lib.rs               # Library exports (8 modules)
β”œβ”€β”€ agent/               # Agent loop + memory context injection
β”‚   β”œβ”€β”€ mod.rs
β”‚   └── loop_.rs
β”œβ”€β”€ channels/            # Channel trait + 7 implementations
β”‚   β”œβ”€β”€ traits.rs        # Channel trait definition
β”‚   β”œβ”€β”€ cli.rs           # Local terminal
β”‚   β”œβ”€β”€ telegram.rs      # Telegram Bot API
β”‚   β”œβ”€β”€ discord.rs       # Discord bot
β”‚   β”œβ”€β”€ slack.rs         # Slack bot
β”‚   β”œβ”€β”€ matrix.rs        # Matrix protocol
β”‚   β”œβ”€β”€ imessage.rs      # macOS iMessage
β”‚   └── mod.rs           # System prompt builder
β”œβ”€β”€ config/              # TOML config schema
β”‚   β”œβ”€β”€ schema.rs        # All config structs + defaults
β”‚   └── mod.rs
β”œβ”€β”€ cron/                # Scheduled tasks
β”œβ”€β”€ gateway/             # HTTP gateway (raw TCP + tokio)
β”‚   └── mod.rs           # /health, /pair, /webhook endpoints
β”œβ”€β”€ heartbeat/           # Periodic task engine
β”‚   β”œβ”€β”€ engine.rs
β”‚   └── mod.rs
β”œβ”€β”€ integrations/        # 50+ integration registry
β”‚   β”œβ”€β”€ registry.rs      # All integrations across 9 categories
β”‚   └── mod.rs
β”œβ”€β”€ memory/              # Memory trait + hybrid search engine
β”‚   β”œβ”€β”€ traits.rs        # Memory trait definition
β”‚   β”œβ”€β”€ sqlite.rs        # SQLite + FTS5 + vector embeddings
β”‚   β”œβ”€β”€ markdown.rs      # Append-only markdown
β”‚   β”œβ”€β”€ embeddings.rs    # EmbeddingProvider trait + OpenAI + Noop
β”‚   β”œβ”€β”€ vector.rs        # Cosine similarity + serialization + hybrid merge
β”‚   β”œβ”€β”€ chunker.rs       # Markdown-aware document splitting
β”‚   └── mod.rs           # Factory
β”œβ”€β”€ observability/       # Observer trait + 3 backends
β”‚   β”œβ”€β”€ traits.rs
β”‚   β”œβ”€β”€ noop.rs
β”‚   β”œβ”€β”€ log.rs
β”‚   └── multi.rs
β”œβ”€β”€ onboard/             # Interactive setup wizard
β”‚   └── wizard.rs
β”œβ”€β”€ providers/           # Provider trait + 22+ providers
β”‚   β”œβ”€β”€ traits.rs        # Provider trait definition
β”‚   β”œβ”€β”€ openrouter.rs    # OpenRouter (default)
β”‚   β”œβ”€β”€ anthropic.rs     # Anthropic direct
β”‚   β”œβ”€β”€ openai.rs        # OpenAI direct
β”‚   β”œβ”€β”€ ollama.rs        # Local Ollama
β”‚   β”œβ”€β”€ compatible.rs    # OpenAI-compatible adapter (18+ providers)
β”‚   └── mod.rs           # Factory
β”œβ”€β”€ runtime/             # RuntimeAdapter trait + Native
β”‚   β”œβ”€β”€ traits.rs
β”‚   └── native.rs
β”œβ”€β”€ security/            # Security policy + gateway pairing + secrets
β”‚   β”œβ”€β”€ policy.rs        # SecurityPolicy, path validation, rate limiting
β”‚   β”œβ”€β”€ pairing.rs       # PairingGuard, OTP, bearer tokens
β”‚   β”œβ”€β”€ secrets.rs       # Encrypted secret store (XOR + local key file)
β”‚   └── mod.rs
β”œβ”€β”€ skills/              # Skill loader (TOML manifests)
β”‚   └── mod.rs
β”œβ”€β”€ tools/               # Tool trait + 7 tools
β”‚   β”œβ”€β”€ traits.rs        # Tool trait definition
β”‚   β”œβ”€β”€ shell.rs         # Shell command execution
β”‚   β”œβ”€β”€ file_read.rs     # Sandboxed file reading
β”‚   β”œβ”€β”€ file_write.rs    # Sandboxed file writing
β”‚   β”œβ”€β”€ memory_store.rs  # Store to memory
β”‚   β”œβ”€β”€ memory_recall.rs # Search memory
β”‚   β”œβ”€β”€ memory_forget.rs # Delete from memory
β”‚   β”œβ”€β”€ composio.rs      # Composio managed OAuth tools (optional)
β”‚   └── mod.rs           # Registry
└── tunnel/              # Tunnel trait + 5 implementations
    β”œβ”€β”€ none.rs          # Local-only (default)
    β”œβ”€β”€ cloudflare.rs    # Cloudflare Zero Trust
    β”œβ”€β”€ tailscale.rs     # Tailscale serve/funnel
    β”œβ”€β”€ ngrok.rs         # ngrok
    β”œβ”€β”€ custom.rs        # Bring your own
    └── mod.rs           # Factory

examples/
β”œβ”€β”€ custom_provider.rs
β”œβ”€β”€ custom_channel.rs
β”œβ”€β”€ custom_tool.rs
└── custom_memory.rs

tests/
└── memory_comparison.rs  # SQLite vs Markdown benchmark

64 source files Β· 17,500 lines of Rust Β· 1,017 tests Β· 0 clippy warnings

License

MIT β€” see LICENSE

Contributing

See CONTRIBUTING.md. Implement a trait, submit a PR:

  • New Provider β†’ src/providers/
  • New Channel β†’ src/channels/
  • New Observer β†’ src/observability/
  • New Tool β†’ src/tools/
  • New Memory β†’ src/memory/
  • New Tunnel β†’ src/tunnel/
  • New Skill β†’ ~/.zeroclaw/workspace/skills/<name>/

ZeroClaw β€” Zero overhead. Zero compromise. Deploy anywhere. Swap anything. πŸ¦€

About

claw done right 🦞

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages

  • Rust 99.9%
  • Dockerfile 0.1%