| Field | Value |
|---|---|
| Link | https://github.com/qwibitai/nanoclaw |
| Title | NanoClaw — Lightweight Personal Claude Assistant |
| Source | GitHub (qwibitai/nanoclaw) |
| Tags | ai-agents, architecture, containers, security, claude-code, whatsapp, ipc, skills, agent-swarms |
| Date Downloaded | 2026-02-25 |
| Stars | 14,553 |
| Language | TypeScript |
| Created | 2026-01-31 |
NanoClaw is a lightweight alternative to OpenClaw that runs Claude Code agents inside isolated Linux containers (Docker or Apple Container). Single Node.js process, ~15 source files, SQLite for state, WhatsApp as the primary I/O channel. Each chat group gets its own sandboxed filesystem, memory (CLAUDE.md), and IPC namespace. The key innovation is "skills over features" — instead of bloating the codebase, contributors write SKILL.md files that teach Claude Code how to transform your fork. 14.5K stars in under a month. The architecture is directly relevant to what we're building with samir-bot.
groups/{name}/), isolated memory (CLAUDE.md), isolated IPC namespace, and isolated Claude sessions. Main channel has elevated privileges (can see all groups, register new ones).SKILL.md files (e.g., /add-telegram, /add-slack) that teach Claude Code how to transform an installation. Users run the skill on their fork and get clean, tailored code.GroupQueue class manages container lifecycle. Global concurrency limit, per-group message queuing, exponential backoff on failures, idle timeout for container reaping.better-sqlite3. No external database dependencies.Channel interface for WhatsApp (primary, via baileys), with extensibility for Telegram, Discord, Slack, Signal via skills.claude then /setup.~/.config/nanoclaw/mount-allowlist.json — stored outside the container, tamper-proof from agents. Validates all additional mounts against allowed roots and blocked patterns.``
WhatsApp (baileys) --> SQLite --> Polling loop --> Container (Claude Agent SDK) --> Response
`
NanoClaw is a single Node.js process that bridges messaging platforms to Claude Code agents running in containers. The data flow is:
Inbound: WhatsApp message arrives via baileys library
Storage: Message stored in SQLite with chat/group metadata
Polling: Main loop polls for new messages every few seconds
Routing: Messages grouped by chat JID, trigger word checked for non-main groups
Queuing: GroupQueue manages concurrency — max N containers at once
Container: Docker/Apple Container spawned with isolated mounts
Execution: Claude Agent SDK runs inside the container with the formatted prompt
Streaming: Output streamed back via sentinel markers in stdout
IPC: Container can send messages, schedule tasks, register groups via filesystem IPC
Response: Formatted output sent back to WhatsApp
Key Source Files
File Size Purpose src/index.ts 15.7K Orchestrator — state management, message loop, agent invocation src/container-runner.ts 20.5K Container lifecycle — mount building, spawning, output parsing src/db.ts 18.9K SQLite operations — messages, groups, sessions, tasks src/ipc.ts 12.2K IPC watcher — filesystem-based communication between containers and host src/group-queue.ts 10.2K Concurrency control — per-group queuing, retries, idle management src/mount-security.ts 10.6K Mount validation — allowlist enforcement, path traversal prevention src/task-scheduler.ts 7.2K Scheduled task execution — cron, interval, one-shot src/types.ts 3.1K Type definitions — RegisteredGroup, Channel, NewMessage, etc.
Security Model
The security architecture is container-first, not permission-first:
- OS-level isolation: Agents run in Linux containers, not behind application-level allowlists
- Mount minimalism: Non-main groups only see their own
groups/{name}/ directory. Main group gets project root as read-onlySecrets via stdin: API keys passed through container stdin, never mounted as files or env vars IPC authorization: Each group has its own IPC namespace. Non-main groups can only send messages to their own chat JID. Only main can register groups or refresh metadata Mount allowlist: External config at ~/.config/nanoclaw/ — outside any container mount, making it tamper-proofSession isolation: Each group gets its own .claude/ directory for sessions, preventing cross-group access
Skills System
The most architecturally interesting decision: no feature PRs. Instead:
Contributors create SKILL.md files in .claude/skills/
Each skill teaches Claude Code how to transform the codebase
Users run /add-telegram (for example) and Claude Code modifies their fork
Result: clean, tailored code — not a bloated system with every feature
The
skills-engine/ directory handles the lifecycle:
apply.ts — Execute a skill transformationbackup.ts — Snapshot before applyingmanifest.ts — Track what's installedlock.ts — Prevent concurrent skill modificationsuninstall.ts — Reverse a skillrebase.ts / replay.ts — Merge upstream changes while preserving customizations
Comparison to Our Architecture (samir-bot)
Aspect NanoClaw samir-bot Runtime Single Node.js process Single Express server Database SQLite MongoDB + PostgreSQL + Redis Agent execution Claude Code in containers Cursor CLI agents I/O Channel WhatsApp (primary) Slack + Dashboard UI Memory CLAUDE.md per group SOUL.md + MongoDB everything_log Skills SKILL.md (Claude Code transforms) Script-based skills in skills/ Task queue SQLite + GroupQueue class MongoDB + orchestrator scripts Security Container isolation Trust-based (same process) Concurrency Container pool with limits Sequential (planning for parallel)
Ideas Worth Stealing
Container isolation for agent execution — We could run sub-agents in containers instead of trusting them in-process
Skills-as-transformations — Instead of adding features, teach the agent how to modify itself
Per-group/context isolation — Each conversation context gets its own filesystem and memory
IPC via filesystem — Simple, debuggable, no socket complexity
Mount security allowlists — External config that agents can't tamper with
Idle timeout + container reaping — Containers stay alive for follow-up messages, then auto-cleanup
Skills engine with rollback — Backup before applying changes, ability to uninstall
Dependencies
Remarkably lean — only 8 runtime dependencies:
Package Purpose @whiskeysockets/baileys WhatsApp Web API better-sqlite3 SQLite driver cron-parser Cron expression parsing for scheduled tasks pino + pino-pretty Structured logging qrcode + qrcode-terminal WhatsApp QR auth yaml YAML parsing zod` Schema validation