NanoClaw Setup (Codex)
Run commands directly. Pause only when user action is required (QR scan, runtime install, auth choice).
1. Install Dependencies
npm install
2. Confirm Container Runtime
echo "Platform: $(uname -s)" which container && echo "Apple Container: installed" || echo "Apple Container: not installed" which docker && docker info >/dev/null 2>&1 && echo "Docker: installed and running" || echo "Docker: not installed or not running"
- •On macOS: prefer Apple Container unless user explicitly wants Docker.
- •On Linux: use Docker (run
/convert-to-dockerworkflow before continuing).
If Apple Container is missing, ask user to install from:
Then verify:
container system start container --version
3. Configure Codex Authentication
Ask user which path they want:
- •Codex login/subscription (recommended)
- •API key in
.env
Option A: Codex login/subscription
Tell user to run in another terminal:
codex login
Then proceed. NanoClaw will copy host ~/.codex/auth.json into each isolated group session directory automatically.
Option B: API key
Create .env with one of:
echo 'OPENAI_API_KEY=' > .env # or echo 'CODEX_API_KEY=' > .env
Optional overrides (only if needed):
cat >> .env << 'EOF_ENV' OPENAI_BASE_URL= OPENAI_ORG_ID= OPENAI_PROJECT_ID= EOF_ENV
Validate:
grep -E '^(OPENAI_API_KEY|CODEX_API_KEY)=' .env || echo "No key configured"
4. Build Container Image
./container/build.sh
Smoke test:
if which docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "Container OK"
else
echo '{}' | container run -i --entrypoint /bin/echo nanoclaw-agent:latest "Container OK"
fi
5. WhatsApp Authentication
User action required:
npm run auth
Wait for successful auth output.
6. Configure Assistant Name and Main Channel
Ask user for trigger word (default Andy).
- •Main channel (self chat or solo chat) should be admin/control channel.
- •For personal chat channels, set
requiresTrigger: false.
Build once and briefly run app so WhatsApp groups are synced:
npm run build npm run dev
If user uses group main channel, query recent groups:
sqlite3 store/messages.db "SELECT jid, name FROM chats WHERE jid LIKE '%@g.us' AND jid != '__group_sync__' ORDER BY last_message_time DESC LIMIT 40"
Write/update data/registered_groups.json with the selected main chat JID and trigger.
Use this shape for personal chat (no trigger required):
{
"JID_HERE": {
"name": "main",
"folder": "main",
"trigger": "@ASSISTANT_NAME",
"added_at": "CURRENT_ISO_TIMESTAMP",
"requiresTrigger": false
}
}
Ensure folders exist:
mkdir -p groups/main/logs
If assistant name changed, update both files:
- •
groups/global/AGENTS.md - •
groups/main/AGENTS.md
(Keep legacy CLAUDE.md files aligned if they exist.)
7. Configure Mount Allowlist (Optional)
If user wants external folder access, create/update:
~/.config/nanoclaw/mount-allowlist.json
Default safe template:
mkdir -p ~/.config/nanoclaw
cat > ~/.config/nanoclaw/mount-allowlist.json << 'EOF_ALLOW'
{
"allowedRoots": [],
"blockedPatterns": [],
"nonMainReadOnly": true
}
EOF_ALLOW
8. Configure launchd Service (macOS)
NODE_PATH=$(which node)
PROJECT_PATH=$(pwd)
HOME_PATH=$HOME
cat > ~/Library/LaunchAgents/com.nanoclaw.plist << EOF_PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nanoclaw</string>
<key>ProgramArguments</key>
<array>
<string>${NODE_PATH}</string>
<string>${PROJECT_PATH}/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>${PROJECT_PATH}</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:${HOME_PATH}/.local/bin</string>
<key>HOME</key>
<string>${HOME_PATH}</string>
</dict>
<key>StandardOutPath</key>
<string>${PROJECT_PATH}/logs/nanoclaw.log</string>
<key>StandardErrorPath</key>
<string>${PROJECT_PATH}/logs/nanoclaw.error.log</string>
</dict>
</plist>
EOF_PLIST
npm run build
mkdir -p logs
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
launchctl list | grep nanoclaw
9. Test
Tell user to send:
- •Main channel:
hello - •Other groups:
@ASSISTANT_NAME hello
Watch logs:
tail -f logs/nanoclaw.log
Troubleshooting
- •Service not starting:
logs/nanoclaw.error.log - •Runtime failures:
groups/main/logs/container-*.log - •Auth problems: run
codex loginor addOPENAI_API_KEY/CODEX_API_KEYin.env - •WhatsApp disconnected: run
npm run auth, then restart service:
launchctl kickstart -k gui/$(id -u)/com.nanoclaw