Menu

AGENT RUNTIME — SELF-HOSTED  ·  beta

An always-on AI agent in one static binary

One static Zig binary that connects roughly 60 model providers (OpenRouter, Anthropic, OpenAI, Ollama, Groq and more) to 26 channels — Telegram, Discord, Slack, Signal, WhatsApp, iMessage and Nostr among them — with 39 built-in tools, hybrid memory, cron scheduling and sandboxing compiled in. No Node, no Python: release binaries are 4.4–6.5 MB and ship for 15 platforms, from x86 servers to Android phones and RISC-V boards.

Continue reading

built-in tools, hybrid memory, cron scheduling and sandboxing compiled in. No Node, no Python: release binaries are 4.4–6.5 MB and ship for 15 platforms, from x86 servers to Android phones and RISC-V boards.

brew install nullclaw
nullclaw --help

Overview

The useful part, at a glance.

In plain words

What it is
NullClaw is an AI agent runtime: one static binary, written in Zig, that runs an always-on LLM agent you can message from Telegram, Discord, Slack, Signal, iMessage and some twenty other channels. The same binary is the agent loop, the webhook gateway, the cron scheduler, the memory store and the OS service — there is no separate database server or plugin runtime to install. It talks to roughly 60 model providers, from Anthropic and OpenAI to a local Ollama.
Where it fits
The full-power runtime for deployments that need every channel, tool and provider in one always-on binary.
Why it exists — and when you need it
Why it exists
Comparable agent stacks run on Node.js or Python and pull in hundreds of dependencies; NullClaw compiles to one 4.4-6.5 MB native binary whose only bundled dependencies are a vendored SQLite and two pinned libraries — the build even fails if the vendored SQLite's checksum doesn't match. That means an always-on assistant fits on a Raspberry Pi, an Android phone or a RISC-V board, and the defaults are cautious: sandboxed shell, workspace-confined file access, encrypted secrets, and a gateway that only listens on localhost until you pair with it.
When you need it
Reach for it when you want your own always-on AI bot — say, a Telegram or Discord assistant with persistent memory and scheduled jobs — running 24/7 on a Raspberry Pi, a VPS or an edge device, without maintaining a heavy runtime. It also fits when you need an agent other software can call: editors over ACP, other agents over A2A, tool servers over MCP. Coming from OpenClaw, the TypeScript agent runtime it is config-compatible with, `nullclaw migrate openclaw` imports your config and memory in one command.

How it works

From zero to running.

Everything below is one binary and one config file (~/.nullclaw/config.json). The path from download to an always-on agent is: onboard once, test in the terminal, open the gateway, install it as a service.

  1. Install the binary

    Homebrew is the shortest path on macOS and Linux; Docker and a Zig 0.16.0 source build also work. There is no npm install and no virtualenv — the release asset is a 4.4-6.5 MB static executable, shipped for 15 platforms including Android and RISC-V.

    brew install nullclaw
  2. Onboard with a provider key

    One command writes ~/.nullclaw/config.json with your provider, model and memory backend. OpenRouter is the default provider; around 45 provider key environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY, GROQ_API_KEY and friends) are auto-detected, so if a key is already exported, onboarding picks it up.

    nullclaw onboard --api-key sk-... --provider openrouter
  3. Say something to it

    The agent loop runs in your terminal first — one-shot with -m or as a REPL without it. This is where you confirm the provider answers before wiring up any chat app. The agent already has its 39 tools here: shell, files, browser, web search, memory, cron.

    nullclaw agent -m "Hello, nullclaw!"
  4. Connect a channel and start the gateway

    channel add walks you through one channel's credentials (Telegram's bot token is the fastest first channel), then the gateway starts a long-running HTTP/WebSocket server on 127.0.0.1:3000 that receives webhooks and routes messages into provider-backed sessions. Pairing is required by default and public binding is off, so a random port scan finds nothing usable.

    nullclaw channel add telegram
    nullclaw gateway
  5. Make it survive reboots

    service install registers the gateway with your OS service manager (launchd, systemd and friends), and status plus doctor close the loop — doctor pre-checks the usual first failures like a missing key or an unreachable provider before you go hunting through logs.

    nullclaw service install
    nullclaw status && nullclaw doctor

Release binaries

One binary, ready to run.

Cross-compiled by nullbuilder for supported platforms — no language runtime or system-wide installer required.

Exact digests come from the repository manifest. If a future release also publishes a checksum file or detached signature, that upstream evidence appears beside the asset.

Capabilities

What NullClaw does.

26 channels, allowlists everywhere

Telegram, Discord, Slack, Signal, WhatsApp, iMessage, Matrix, Teams, WeChat, IRC, email, Nostr and more — 26 channel integrations in the catalog, 23 of them selectable at build time. Every channel sits behind its own allowlist, and the Nostr channel speaks NIP-17 gift-wrapped DMs.

Memory with a real retrieval pipeline

Conversations and facts land in SQLite, found again with FTS5 keyword search plus embedding similarity — fused with reciprocal-rank fusion, diversified with MMR, decayed by age and reranked by an LLM. Twelve engines total, from plain Markdown files to Redis, Postgres, ClickHouse and LanceDB, when SQLite isn't the right fit.

~60 providers, one config

Eleven core implementations (Anthropic, OpenAI, Azure, Gemini, Vertex, OpenRouter, Ollama and CLI bridges) plus an OpenAI-compatible table covering 49 more services — Groq, Mistral, DeepSeek, xAI, Bedrock, Moonshot, LM Studio, llama.cpp — under 98 accepted names. Any other endpoint works via a custom base URL.

Sandboxed and encrypted by default

Commands the agent runs are isolated in a sandbox auto-picked from what your system has: Landlock, Firejail, Bubblewrap or Docker. File access stays inside the agent's workspace, secrets are encrypted at rest with ChaCha20-Poly1305 with time-based key rotation, and the gateway binds to 127.0.0.1 with pairing tokens and per-minute rate limits.

Speaks A2A, MCP and ACP

Other agents can discover and call it over Google's A2A protocol (v0.3.0, JSON-RPC with SSE streaming and a public agent card). It can use tools from any MCP (Model Context Protocol) server over stdio or SSE, and an ACP v1 stdio adapter lets code editors drive it directly.

Runs where Node.js can't

The v2026.5.29 release ships 15 static builds: Linux on x86_64, aarch64, arm32 and RISC-V, macOS, Windows and Android. A wasm3 WebAssembly runtime is compiled in by default, and early hardware tooling — board scan, I2C and SPI tools, a MaixCam camera-board channel — points the same binary at embedded boards.

Use it for

Where it earns its place.

A Telegram assistant on a Raspberry Pi

You want a bot that remembers you, runs 24/7, and does not need Node or Python babysitting on a small board. Install the aarch64 (or arm32) binary, onboard with an OpenRouter key, add the Telegram channel with a bot token, and register it as a service. You get an always-on assistant with hybrid SQLite memory, sandboxed shell access, and a per-channel allowlist so only your account can talk to it.

nullclaw onboard --api-key sk-... --provider openrouter
nullclaw channel add telegram
nullclaw service install
A morning briefing that posts itself

The cron subsystem schedules full agent runs, not just shell commands. One line registers a 7 a.m. job whose prompt the agent executes with its normal tools — web search across any of the 8 providers, web fetch, memory — and --announce delivers the result to a channel. Jobs are inspectable and pausable from the CLI or from the gateway's bearer-token cron API.

nullclaw cron add-agent "0 7 * * *" "Summarize overnight repo issues and top HN stories" --announce --channel telegram
One agent your editor and other agents can call

The same binary is a protocol citizen in three directions. nullclaw acp runs a stdio JSON-RPC server that ACP-capable code editors drive directly; the gateway publishes an agent card at /.well-known/agent.json so other agents can discover and call it over A2A 0.3.0 with SSE streaming; and any MCP server you configure contributes its tools to the agent's toolbox alongside the 39 built-ins.

nullclaw acp
nullclaw mcp list
Moving off OpenClaw without retyping config

If you already run OpenClaw — the TypeScript agent runtime NullClaw is config-compatible with — one command imports your existing config and memory. Run it with --dry-run first to see exactly what would be translated, then for real. Your channels and provider setup carry over; what changes underneath is the runtime: one static binary instead of a Node process tree.

nullclaw migrate openclaw --dry-run
nullclaw migrate openclaw
What's inside Counted in the source, not the brochure. 105 listed

26 chat channels

23 of these are build-time selectable (-Dchannels=all is the default), every channel sits behind its own allowlist, and Nostr speaks NIP-17 gift-wrapped DMs.

  • Telegram
  • Discord
  • Slack
  • Signal
  • WhatsApp
  • iMessage
  • Matrix
  • Mattermost
  • Microsoft Teams
  • IRC
  • Email
  • LINE
  • Lark
  • DingTalk
  • WeChat
  • WeCom
  • Weixin
  • QQ
  • Max
  • OneBot
  • Nostr
  • MaixCam
  • Web
  • Webhook
  • CLI
  • External (plugin protocol)

~60 model providers under 98 accepted names

11 core implementations plus a 98-alias OpenAI-compatible table covering 49 distinct services; anything else works via a custom: base URL prefix.

  • Anthropic
  • OpenAI
  • Azure OpenAI
  • OpenRouter
  • Ollama
  • Gemini
  • Vertex
  • Claude CLI
  • Codex CLI
  • Gemini CLI
  • OpenAI Codex
  • Groq
  • Mistral
  • DeepSeek
  • xAI
  • Bedrock
  • Copilot
  • Qwen
  • GLM
  • MiniMax
  • Moonshot
  • vLLM
  • LM Studio
  • llama.cpp

39 built-in tools

Plus 6 cron tools, 4 memory tools and two hashed file-tool variants — that completes the 39 — with dynamic tools imported from any MCP server on top.

  • Shell
  • File read
  • File write
  • File edit
  • File append
  • File delete
  • Git operations
  • HTTP request
  • Web search
  • Web fetch
  • Browser
  • Browser open
  • Screenshot
  • Image info
  • Calculator
  • Message
  • Delegate
  • Spawn
  • Schedule
  • SQLite query
  • Composio
  • Pushover
  • Anonymize text
  • Hardware board info
  • Hardware memory
  • I2C
  • SPI

12 memory engines

Retrieval is a real pipeline — FTS5 plus embeddings fused with RRF, MMR diversification, temporal decay, query expansion and LLM reranking — not a single vector lookup.

  • Hybrid (SQLite + Markdown, the default)
  • SQLite
  • Markdown
  • In-memory
  • API
  • Lucid
  • Redis
  • LanceDB
  • Postgres
  • ClickHouse
  • Knowledge graph (kg)
  • None

3 agent protocols, 5 sandbox backends, 8 search providers

The sandbox is auto-detected from what the host has; tunnels (Cloudflare, Tailscale, ngrok) and OTel observability round out the ops surface.

  • MCP client (2024-11-05, stdio + SSE)
  • A2A 0.3.0 (JSON-RPC, SSE streaming, public agent card)
  • ACP v1 (stdio JSON-RPC for editors)
  • Landlock
  • Firejail
  • Bubblewrap
  • Docker
  • No sandbox (explicit)
  • Brave
  • DuckDuckGo
  • Exa
  • Firecrawl
  • Jina
  • Perplexity
  • SearXNG
  • Tavily

Quickstart

Up and running.

Full walkthrough in the docs — verified with v2026.5.29.

Onboard once, then talk to it.

# quick setup with a provider key
nullclaw onboard --api-key sk-... --provider openrouter

# send a single message
nullclaw agent -m "Hello, nullclaw!"

# start the long-running runtime on 127.0.0.1:3000
nullclaw gateway

# health checks
nullclaw status && nullclaw doctor

Common questions

Questions, answered.

Is this production-ready?

It is pre-1.0: config keys and CLI flags may change between releases, and releases are date-versioned (the current one is v2026.5.29). What is unusually solid for this stage is the test surface — 7,470 test blocks in-tree — and the dependency story: only a vendored SQLite and two pinned forks, with a build that fails hard if the vendored SQLite's SHA-256 doesn't match.

How big is the binary, really?

The shipped release binaries are 4.4-6.5 MB — that's the default build with all 23 selectable channels and the embedded wasm3 WebAssembly runtime compiled in. You can go much smaller with a stripped -Dchannels=none build, but what you actually download is single-digit megabytes, not hundreds of kilobytes.

Do all 26 channels work on every OS?

No. iMessage reads the macOS Messages database (IMESSAGE_CHAT_DB_PATH), so it is macOS-only; Signal talks to an external signal HTTP service you run separately (SIGNAL_HTTP_URL); and of the sandbox backends, Landlock, Firejail and Bubblewrap are Linux mechanisms — on other platforms auto-detection falls back to Docker or no sandbox. Telegram remains the least-friction first channel everywhere.

Can it run fully local, without a cloud model?

Yes, for the model side: Ollama, LM Studio, llama.cpp and vLLM are all supported providers, and memory (SQLite + FTS5) lives on disk. Some tools inherently reach out — web search needs one of the 8 search providers, and web fetch needs the internet — but nothing in the runtime itself phones home, and there is no telemetry beyond the OTel exporter you would have to configure yourself.

Is it safe to hand an LLM a shell tool?

The defaults are built around assuming the model will occasionally do something dumb: shell commands run in an auto-detected sandbox (on by default), file tools are confined to the workspace (workspace_only=true), actions are capped at 20 per hour, every channel has an allowlist, and the gateway binds to 127.0.0.1 with required pairing tokens and per-minute rate limits. You can loosen each of these, but you have to do it explicitly.

What is the relationship to OpenClaw?

NullClaw is an independent runtime written in Zig, not a fork — but it deliberately speaks the same config shape, and nullclaw migrate openclaw imports an existing OpenClaw config and memory. Think of it as the answer to "I like this agent's behavior, but I want it in one small static binary on hardware Node.js doesn't love."

Pre-1.0: config and CLI may change between releases. Binary sizes are taken from the v2026.5.29 release assets; channel, provider and test counts are counted from the source tree at that version.