A personal 24x7 AI assistant that runs on your messaging platforms. Send a message on WhatsApp, Telegram, Signal, or iMessage and get responses from Claude with full tool access, persistent memory, scheduled reminders, and integrations with 500+ apps.
Get your free API key to get started →
- Requirements
- Installation
- Quick Start
- Deploying Remotely
- Providers
- Configuration
- Messaging Platforms
- Tool Approvals
- Memory System
- Scheduling and Reminders
- App Integrations
- Commands
- Troubleshooting
- Directory Structure
- Contributing
- Resources
- Community
- Node.js 18+
- macOS, Linux, or Windows
- Anthropic API key (
ANTHROPIC_API_KEY) - Composio API key (
COMPOSIO_API_KEY) - Claude Code — required if using the Claude provider
- Opencode — required if using the Opencode provider
Platform-specific:
- WhatsApp: a phone with WhatsApp installed
- Telegram: a bot token from @BotFather
- Signal: signal-cli installed and registered
- iMessage: macOS only, requires the
imsgCLI tool
git clone <repo-url> secure-openclaw
cd secure-openclaw
npm installYou need at least one AI provider installed on the machine.
Claude Code (for the Claude provider):
npm install -g @anthropic-ai/claude-codeOpencode (for the Opencode provider):
curl -fsSL https://opencode.ai/install | bashYou can install both. The CLI lets you switch between them.
After installing Claude Code, authenticate it locally:
claude
# Follow the OAuth prompts to log in with your Anthropic accountOn remote/Docker deployments, authentication is handled by the ANTHROPIC_API_KEY environment variable instead — no interactive login needed.
Anthropic — get your key from https://console.anthropic.com/
export ANTHROPIC_API_KEY=sk-ant-...Composio — provides 500+ app integrations (Gmail, Slack, GitHub, etc.)
curl -fsSL https://composio.dev/install | bash
composio login
composio whoami # shows your API key
export COMPOSIO_API_KEY=your-keyAdd all exports to your shell profile (~/.zshrc or ~/.bashrc) to make them permanent.
node cli.jsThis opens the interactive menu:
1) Terminal chat — talk to the assistant in your terminal
2) Start gateway — run the messaging gateway
3) Setup adapters — configure WhatsApp, Telegram, etc.
4) Show current config
5) Test connection
6) Change provider
7) Exit
Or run directly:
node cli.js chat # terminal chat
node cli.js start # start the gatewayThe gateway can run on a remote server. Terminal chat is local only.
A $6/month DigitalOcean droplet. No ID verification, just sign up and go.
- Sign up at digitalocean.com
- Create > Droplets
- Pick a region, select Ubuntu 24.04, choose the $6/mo plan (1 GB RAM)
- Set a root password
- Click Create Droplet and copy the public IP from the dashboard
# SSH in
ssh root@YOUR_DROPLET_IP
# Add swap (the build needs more than 1 GB)
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
# Install Docker
curl -fsSL https://get.docker.com | sh
# Clone the repo (use a GitHub PAT if private)
git clone https://github.com/YOUR_USERNAME/secure-openclaw.git
cd secure-openclawcp .env.example .env
nano .envFill in ANTHROPIC_API_KEY, COMPOSIO_API_KEY, and whichever platforms you want. Save with Ctrl+O, exit with Ctrl+X.
docker compose up -d --build
ufw allow 4096That's it. Docker Compose reads your .env, builds the image (installs Claude Code + Opencode inside), and starts the gateway. WhatsApp auth and memory are persisted in Docker volumes automatically.
Open http://YOUR_DROPLET_IP:4096/qr in your browser and scan with WhatsApp > Linked Devices.
docker compose logs -f # live logs
docker compose down && docker compose up -d # restart
docker compose exec openclaw sh # shell into container
git pull && docker compose up -d --build # update- Health check:
http://YOUR_DROPLET_IP:4096/ - Telegram: works immediately if you set
TELEGRAM_BOT_TOKENin.env
Build gets killed (exit code 137): Out of memory. Make sure you added swap (step 2).
Can't access http://YOUR_IP:4096: Run ufw allow 4096. Also make sure you're using the public IP from the DigitalOcean dashboard, not the internal/private one (starts with 10.).
WhatsApp QR page says "Waiting...": The gateway is still starting. Check logs with docker compose logs -f and wait for [Gateway] Ready.
Claude exits with code 1: Your ANTHROPIC_API_KEY is missing or wrong. Check with docker compose exec openclaw env | grep ANTHROPIC.
Private repo clone fails: GitHub doesn't support password auth. Use a Personal Access Token: git clone https://YOUR_TOKEN@github.com/...
Checking logs:
docker compose logs -f # all logs, live
docker compose logs -f --tail 50 # last 50 lines, then follow
docker compose logs openclaw 2>&1 | grep ERROR # filter for errorsAny Linux VPS works (Hetzner, Vultr, AWS Lightsail). Same steps — SSH in, add swap if < 2 GB RAM, install Docker, clone, docker compose up.
| Feature | Local | Remote |
|---|---|---|
| Terminal chat | Yes | No |
| Gateway (WhatsApp, Telegram, etc.) | Yes | Yes |
| Memory | Yes | Yes (needs volume) |
| Cron/reminders | Yes | Yes |
| Composio integrations | Yes | Yes |
Secure OpenClaw supports two AI providers:
Claude Agent SDK — Anthropic's SDK. Uses your ANTHROPIC_API_KEY. Requires Claude Code installed. Models: Opus 4.6, Sonnet 4.5, Haiku 4.5.
Opencode — open-source alternative. Requires Opencode installed. Runs a local server or connects to an existing one. Models: GPT-5 Nano, Big Pickle, GLM-4.7, Grok Code, MiniMax M2.1.
Switch providers from the CLI menu (option 7) or in config.js:
agent: {
provider: 'claude', // or 'opencode'
}When using Opencode, the provider auto-detects whether a server is already running on the configured port. If one exists, it connects. If not, it starts one.
Use /model during terminal chat to switch models within the active provider.
All settings live in config.js. Edit directly or use the setup wizard.
{
agentId: 'secure-openclaw',
whatsapp: { enabled: true, allowedDMs: [...], allowedGroups: [...] },
telegram: { enabled: false, token: '', ... },
signal: { enabled: false, phoneNumber: '', ... },
imessage: { enabled: false, ... },
agent: {
workspace: '~/secure-openclaw',
maxTurns: 100,
allowedTools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep'],
provider: 'claude',
opencode: {
model: 'opencode/gpt-5-nano',
hostname: '127.0.0.1',
port: 4096
}
},
}Each platform has an allowlist for DMs and groups. Set to ['*'] to allow all, or list specific IDs.
whatsapp: {
allowedDMs: ['+1234567890'], // only this number can DM
allowedGroups: ['*'], // all groups allowed
respondToMentionsOnly: true // in groups, only respond when @mentioned
}Messages from unrecognized senders are silently dropped.
Uses QR code authentication. No bot token needed.
- Enable in config or run the setup wizard
- Start the gateway
- Scan the QR code that appears in your terminal (WhatsApp > Settings > Linked Devices)
- Session saves to
auth_whatsapp/— you only scan once
- Message @BotFather on Telegram, send
/newbot, copy the token - Add the token to config:
telegram: {
enabled: true,
token: 'YOUR_BOT_TOKEN',
allowedDMs: ['*'],
}- Start the gateway, then message your bot
Requires signal-cli to be installed and registered.
signal-cli -u +1234567890 register
signal-cli -u +1234567890 verify CODEThen configure:
signal: {
enabled: true,
phoneNumber: '+1234567890',
signalCliPath: 'signal-cli',
}macOS only. Requires the imsg CLI tool.
brew install steipete/formulae/imsgEnable in config. Make sure Messages.app is open and signed in.
The gateway runs with permission mode default, which means the assistant asks for approval before using certain tools. When a tool needs approval:
In terminal chat: the spinner pauses, the tool name and details are printed, and you type y or n to approve or deny.
On messaging platforms: the assistant sends you a message like "Claude wants to use Bash. Reply Y to allow, N to deny." Your next reply resolves the approval.
If the assistant uses AskUserQuestion to ask clarifying questions, these are formatted as numbered options. Reply with a number or type your answer.
Approvals time out after 2 minutes with no response.
Persistent memory stored at ~/secure-openclaw/.
~/secure-openclaw/
MEMORY.md — long-term: preferences, people, decisions
memory/
YYYY-MM-DD.md — daily logs
[topic].md — topic-specific notes
Memory is loaded at the start of each conversation. The assistant writes to memory when you ask it to remember something. It does not proactively write memory on every message.
Use the /memory command in chat to view or search memories.
The assistant can schedule messages using cron tools.
- "Remind me in 30 minutes to check the oven" — one-time delay
- "Every day at 9am, send me a standup reminder" — cron expression
0 9 * * * - "Every weekday at 8am" — cron expression
0 8 * * 1-5
Jobs persist in ~/.secure-openclaw/cron-jobs.json and execute while the gateway is running.
Composio provides access to 500+ apps:
- Gmail, Google Calendar, Google Sheets, Google Drive
- Slack, Discord
- GitHub, GitLab, Jira, Linear
- Notion, Trello, Asana
- Salesforce, HubSpot
- Twitter/X, LinkedIn
- And many more
Just ask: "Send an email to john@example.com", "Create a GitHub issue for the login bug", "Add an event to my calendar for tomorrow at 3pm".
On first use of an app, Composio provides an auth link. Click it to authorize, then the assistant can use that app going forward.
node cli.js # interactive menu
node cli.js chat # terminal chat
node cli.js start # start gateway
node cli.js setup # setup wizard
node cli.js config # show config
node cli.js help # help| Command | Description |
|---|---|
/new, /reset |
Start a fresh conversation |
/status |
Show session info |
/memory |
Show memory summary |
/memory list |
List all memory files |
/memory search <query> |
Search memories |
/model |
Switch model (terminal only) |
/queue |
Message queue status |
/stop |
Stop current operation |
/help |
Show commands |
"ANTHROPIC_API_KEY not set" — export the key in your shell or .env file.
"claude: command not found" — Claude Code is not installed. Run curl -fsSL https://claude.ai/install.sh | bash.
"opencode: command not found" — Opencode is not installed. Run curl -fsSL https://opencode.ai/install | bash.
Composio not working — make sure COMPOSIO_API_KEY is set. Run composio login and composio whoami to get your key.
WhatsApp QR not appearing — delete auth_whatsapp/ and restart.
Telegram bot not responding — verify the token, make sure you sent /start to your bot, check enabled: true.
Signal not working — verify signal-cli is installed, phone number is registered and includes country code.
iMessage not working — macOS only. Check that Messages.app is open, imsg is installed (which imsg), and accessibility permissions are granted.
Opencode server failing — if port 4096 is already in use from a previous run, kill the old process: kill $(lsof -ti :4096). The provider auto-detects running servers, so usually this resolves itself.
Memory not persisting on remote — make sure you have a persistent volume mounted at /home/claw/secure-openclaw.
secure-openclaw/
config.js configuration
cli.js CLI entry point (menu, terminal chat)
gateway.js gateway process (messaging platforms)
Dockerfile container build for remote deployment
adapters/
base.js base adapter class
whatsapp.js WhatsApp via Baileys
telegram.js Telegram via node-telegram-bot-api
signal.js Signal via signal-cli
imessage.js iMessage via imsg (macOS)
agent/
claude-agent.js agent with memory, cron, system prompt
runner.js queue + run coordinator
providers/
base-provider.js provider interface
claude-provider.js Claude Agent SDK provider
opencode-provider.js Opencode provider
index.js provider registry
memory/
manager.js memory file management
tools/
cron.js scheduling tools
gateway.js gateway MCP tools (send_message, etc.)
commands/
handler.js slash command handlers
sessions/
manager.js session tracking
~/secure-openclaw/ workspace (created on first use)
MEMORY.md long-term memory
memory/ daily logs and topic files
We welcome contributions! Here's how to get started:
- Fork the repo
- Create a branch (
git checkout -b feat/my-feature) - Make your changes and commit (
git commit -m 'Add my feature') - Push to your branch (
git push origin feat/my-feature) - Open a Pull Request
Please keep PRs focused on a single change. If you're fixing a bug, include steps to reproduce. If you're adding a feature, explain the use case.
- Discord — ask questions, share what you've built
- X / Twitter — follow for updates
- GitHub Issues — bug reports and feature requests
- GitHub Discussions — ideas and Q&A
MIT