Setup your private AI agent with your choice of messaging channels, AI models, and web search — at near-zero cost.
A 24/7 Linux server on Google's free tier — runs while you sleep, no electricity bill, no exposed home ports.
An ultra-lightweight AI agent (~4K lines) that searches the web, runs commands, manages files, and responds via your favourite messaging app.
Runs as a background service — message it from anywhere, get instant responses, even when your laptop is off.
Both are open-source autonomous AI agents capable of web search, shell execution, file management, and multi-channel messaging. The key difference is complexity: Nanobot is ~4,000 lines of Python while OpenClaw spans ~430,000 lines of JavaScript/TypeScript. This 100× difference in codebase size translates to a smaller attack surface and easier auditing for security-conscious users. Nanobot supports 11+ LLM providers (Gemini, Claude, GPT, DeepSeek, Groq, Zhipu, and local models via Ollama/vLLM) compared to OpenClaw's model-agnostic approach. For messaging, Nanobot covers 8+ platforms (Telegram, Discord, WhatsApp, Slack, Email, DingTalk, Feishu, QQ) while OpenClaw supports 20+. Choose Nanobot for simplicity and quick deployment; choose OpenClaw for maximum platform coverage and advanced automation workflows.
Nanobot is an autonomous AI agent — it takes real actions and makes real API calls. Understand these risks first:
Nanobot can misinterpret instructions and take unintended actions — looping searches, rewriting files, or sending unexpected messages. Always test in a supervised session before leaving it unattended.
A runaway tool loop or leaked API key can exhaust your Gemini or Brave Search quotas fast. Set GCP budget alerts (Section 8) before running Nanobot unattended. The maxToolIterations limit in config provides a safety cap.
If your Telegram bot token or API keys are leaked — from a public repo, shared screenshot, or log file — an attacker can control your agent and rack up API costs. Treat every key like a bank password.
Everything you send to the bot is transmitted to Google Gemini (for processing) and Brave Search (for web search). Do not share private data, passwords, or confidential business information with the bot.
This guide is an independent community resource created by Commune.AI. It is provided "as is" without warranty of any kind. Commune.AI, its affiliates, and contributors accept no liability for any damages, costs, or losses arising from the use of this guide, including but not limited to misconfiguration, API charges, data exposure, or service disruptions. By proceeding, you acknowledge that you use this guide entirely at your own risk. Not affiliated with Google LLC, HKUDS/nanobot, Telegram, Brave Software, or any third-party service mentioned herein.
Select your messaging channels, tools, and AI model. The guide adapts — only relevant sections and API key inputs appear. Your config.json is generated automatically.
ORANGE_VALUES in code blocks are placeholders you must replace. Fill in the input fields in each section — code snippets update automatically.
Create a free-tier VM, service account, and swap — ready for Nanobot
| Prerequisite | Where to get it | Cost |
|---|---|---|
| Google account | accounts.google.com | Free |
| GCP project + billing | console.cloud.google.com | Free |
Creates a zero-permission service account, a free-tier e2-micro VM, and automatically configures a 2 GB swap file on first boot — all in one step.
gcloud.The script auto-detects your Project ID from Cloud Shell. You can optionally customise the VM and service account names:
#!/usr/bin/env bash # ── Auto-detect Project ID from Cloud Shell ──────────────────── PROJECT_ID="$(gcloud config get-value project 2>/dev/null)" ZONE="us-central1-a" # keep for Always Free tier # ───────────────────────────────────────────────────── set -uo pipefail # removed -e so script continues on error VM_NAME="nanobot-vm" ; SA_NAME="nanobot-sa" FAILED=0 echo "🔌 Enabling APIs (Compute + IAM)…" if ! gcloud services enable compute.googleapis.com iam.googleapis.com --project="$PROJECT_ID" 2>&1; then echo "❌ Failed to enable APIs. Check your project ID and billing status." >&2 FAILED=1 else echo " ↳ APIs confirmed." fi echo "🔐 Creating restricted service account (no IAM roles)…" gcloud iam service-accounts create "$SA_NAME" \ --display-name="Nanobot SA — zero GCP permissions" \ --project="$PROJECT_ID" 2>&1 | grep -q "already exists" && echo " ↳ Service account already exists (OK)" || echo " ↳ Service account created." SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" if [ $FAILED -eq 0 ]; then echo "🖥️ Creating free-tier VM (with swap auto-configured on first boot)…" # Write startup script to temp file (configures 2GB swap on first boot) cat > /tmp/startup.sh << 'STARTUP_EOF' #!/bin/bash if [ ! -f /swapfile ]; then fallocate -l 2G /swapfile && chmod 600 /swapfile mkswap /swapfile && swapon /swapfile echo "/swapfile none swap sw 0 0" >> /etc/fstab sysctl -w vm.swappiness=10 echo "vm.swappiness=10" >> /etc/sysctl.conf fi STARTUP_EOF if ! gcloud compute instances create "$VM_NAME" \ --project="$PROJECT_ID" \ --zone="$ZONE" \ --machine-type=e2-micro \ --image-project=debian-cloud \ --image-family=debian-12 \ --boot-disk-size=10GB \ --boot-disk-type=pd-standard \ --boot-disk-auto-delete \ --service-account="$SA_EMAIL" \ --scopes=https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write \ --metadata=block-project-ssh-keys=true \ --metadata-from-file=startup-script=/tmp/startup.sh 2>&1; then echo "❌ VM creation failed. See error above." >&2 FAILED=1 fi rm -f /tmp/startup.sh fi echo "" echo "════════════════════════════════════════════" if [ $FAILED -eq 0 ]; then echo "✅ VM ready! 2 GB swap will be live by the time you SSH in." echo "════════════════════════════════════════════" echo "" echo "▶ SSH into your VM:" echo " gcloud compute ssh $VM_NAME --zone=$ZONE --project=$PROJECT_ID" else echo "❌ Setup incomplete — review errors above" echo "════════════════════════════════════════════" echo "" echo "Common fixes:" echo " • Wrong PROJECT_ID → verify in GCP Console" echo " • Billing not enabled → console.cloud.google.com/billing" echo " • VM already exists → delete it first or use a different name" echo "" echo "Cloud Shell will stay open so you can review the errors." fi echo ""
Wait ~60 seconds for the VM to boot, then open an SSH session. You can use the Cloud Shell command below, or click the SSH button next to the VM in the GCP Console.
gcloud compute ssh nanobot-vm --zone=us-central1-a
free -h — you should see ~2.0G in the Swap row. If it shows 0, the startup script is still running; wait 30 s and check again.The fastest way is a single Cloud Shell command. No roles are granted — this is intentional.
gcloud iam service-accounts create nanobot-sa \ --display-name="Nanobot SA — zero GCP permissions"
Or via the Console: IAM & Admin → Service Accounts → + Create Service Account — fill name nanobot-sa, skip the roles step, click Done. Do not create or download a JSON key.
us-central1 Zone: us-central1-a
us-central1 or us-west1. Any other region incurs compute charges.nanobot-sa.SSH in via the GCP Console → VM instances → SSH button next to nanobot-vm. Then run:
sudo bash -c ' fallocate -l 2G /swapfile && chmod 600 /swapfile mkswap /swapfile -q && swapon /swapfile echo "/swapfile none swap sw 0 0" >> /etc/fstab sysctl -w vm.swappiness=10 > /dev/null echo "vm.swappiness=10" >> /etc/sysctl.conf echo "✅ 2 GB swap active"; free -h '
With GCP done, proceed to Step 2 to obtain your API keys.
Set up the channels and model provider you selected above
/newbot.My Nanobot.bot, e.g. mynanobot_xyz_bot.7012345678:AAFxxxxxxxxxxxxxxx. Copy it.Id: 123456789 — that number is your User ID.allowFrom is silently ignored — strangers cannot command your bot. Numeric IDs are permanent; usernames can change.AIzaSy...| Free tier limit | Allowance |
|---|---|
| Requests/day (Gemini 2.0 Flash) | 1,500 |
| Tokens/minute | 1,000,000 |
| GCP billing impact | None — tracked separately via AI Studio |
Brave Search is the web search backend hardcoded in Nanobot. It gives your agent real-time access to current information. The Search plan includes US$5 of free API calls per month (~1,000 queries). Subscribing may incur a small one-time charge of approximately US$1 that's usually reversed; you can set a usage limit to stay within the free US$5 monthly credits.
nanobot.BSA.| Plan detail | Value |
|---|---|
| Plan name | Search |
| Free credits/month | US$5 (~1,000 queries) |
| One-time signup charge | ~US$1 (authorization hold) |
| Credit card required | Yes |
Deploy, configure, run, and verify your AI agent on the VM
whoami to detect your Linux username — no manual entry needed.provider/model-name. You must use the exact model name or Nanobot will not run. Examples: gemini/gemini-3.1-flash-lite-preview, anthropic/claude-sonnet-4-20250514, openrouter/auto, groq/llama-3.3-70b-versatile
Loading…
sudo apt-get update && sudo apt-get upgrade -y sudo apt-get install -y python3-venv python3-pip
mkdir -p ~/.nanobot/workspace python3 -m venv ~/.nanobot/venv
~/.nanobot/venv/bin/pip install --upgrade pip ~/.nanobot/venv/bin/pip install nanobot-ai
~/.nanobot/venv/bin/nanobot --version
nano ~/.nanobot/config.json
Loading…
chmod 600 ~/.nanobot/config.json
| Key | Purpose & security note |
|---|---|
| channels.telegram.allowFrom | Security control. Only this specific Telegram User ID (stored as a quoted string) can send commands. Add more entries if sharing access. |
| tools.web.search.apiKey | Brave Search API key — hardcoded search backend in Nanobot. The Search plan gives US$5/month in free credits. |
| tools.exec.timeout | Limits shell command execution to 60 seconds. Prevents runaway processes. |
| tools.restrictToWorkspace | When true, limits file access to the workspace directory only. Set to false if Nanobot needs broader file access. |
| maxToolIterations: 40 | Caps tool calls per response — prevents runaway loops from exhausting API quotas. |
Running as a system service (auto-start on boot, auto-restart on crash) is in Appendix A. For most learners, start here:
Watch all output in real time. Press Ctrl+C to stop.
~/.nanobot/venv/bin/nanobot gateway
nohup ~/.nanobot/venv/bin/nanobot gateway \ > ~/.nanobot/nanobot.log 2>&1 & echo "Started. PID: $!"
| Task | Command |
|---|---|
| Check running | pgrep -a nanobot |
| Watch live logs | tail -f ~/.nanobot/nanobot.log |
| Stop it | pkill -f "nanobot gateway" |
/start. Nanobot should reply.allowFrom value in config.json — ensure it is a number, not a quoted string.Nanobot Budget · Projects: your project · Type: Monthly · Amount: $5 (safety net — normal spend is $0).| % | At $5 budget triggers at | Suggested action |
|---|---|---|
| 50% | $2.50 | Investigate — something may be running outside the free tier. |
| 90% | $4.50 | Stop non-essential resources immediately. |
| 100% | $5.00 | Review all active GCP resources now. |
| Resource | Free allowance/month | This guide's usage |
|---|---|---|
| e2-micro VM (us-central1) | 1 instance | 1 ✅ |
| pd-standard disk | 30 GB | 10 GB ✅ |
| Network egress (Americas/EMEA) | 1 GB | Low ✅ |
| Gemini 2.0 Flash (AI Studio) | 1,500 req/day | Low ✅ |
| Brave Search (Search plan) | US$5 free credits/mo | Low ✅ |
| Ephemeral external IP (running VM) | Free | Free ✅ |
| Feature | nohup (Section 6) | systemd (this appendix) |
|---|---|---|
| Survives SSH disconnect | ✅ | ✅ |
| Auto-restarts on crash | ❌ | ✅ |
| Starts on VM reboot | ❌ | ✅ |
| OS-level filesystem sandbox | ❌ | ✅ |
pkill -f "nanobot gateway" 2>/dev/null || true
sudo nano /etc/systemd/system/nanobot.service
Paste — replace the four occurrences of YOUR_LINUX_USERNAME:
[Unit] Description=Nanobot AI Agent After=network-online.target Wants=network-online.target [Service] User=YOUR_LINUX_USERNAME WorkingDirectory=/home/YOUR_LINUX_USERNAME Environment=HOME=/home/YOUR_LINUX_USERNAME ExecStart=/home/YOUR_LINUX_USERNAME/.nanobot/venv/bin/nanobot gateway Restart=always RestartSec=10 NoNewPrivileges=true ProtectSystem=strict ProtectHome=read-only ReadWritePaths=/home/YOUR_LINUX_USERNAME/.nanobot PrivateTmp=true [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl enable nanobot sudo systemctl start nanobot sudo systemctl status nanobot --no-pager
| Command | When to use |
|---|---|
| sudo systemctl restart nanobot | After editing config.json. |
| sudo systemctl stop nanobot | To pause Nanobot. |
| sudo systemctl disable nanobot | Prevent auto-start on boot. |
| sudo systemctl daemon-reload | Required after editing the .service file. |
tail -f ~/.nanobot/nanobot.log
sudo journalctl -u nanobot -f
sudo journalctl -u nanobot -n 100 --no-pager
ERROR or Traceback. Common culprits: wrong API key, invalid bot token, JSON syntax error in config.python3 -m json.tool ~/.nanobot/config.json
Valid = formatted JSON prints. Error = line number where parsing failed.
@BotFather → /mybots → select bot → API Token → update config.json → restart Nanobot.
Visit aistudio.google.com, verify or regenerate the key, update config.json, restart.
allowFrom contains your Telegram User ID as a quoted string: ["123456789"]."apiKey" in the tools.web.search block matches your Brave key (starts with BSA).Nanobot's web search tool is hardcoded to use the Brave Search API. Alternative search providers (e.g. Tavily) are not supported at this time.
maxToolIterations: 40 setting in config.json also indirectly limits search calls per conversation — a runaway agent cannot issue unlimited queries.The WhatsApp bridge requires a persistent process to maintain the connection. This appendix shows how to run it as a systemd service that survives terminal close and system restarts.
nanobot channels login manually first.~/.nanobot/bridge/ — keep this directory intact.Create a systemd service file for the WhatsApp bridge:
sudo tee /etc/systemd/system/nanobot-whatsapp-bridge.service > /dev/null << 'EOF' [Unit] Description=Nanobot WhatsApp Bridge After=network-online.target Wants=network-online.target [Service] Type=simple User=YOUR_LINUX_USERNAME WorkingDirectory=/home/YOUR_LINUX_USERNAME ExecStart=/home/YOUR_LINUX_USERNAME/.nanobot/venv/bin/nanobot channels login Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF
sudo systemctl daemon-reload sudo systemctl enable nanobot-whatsapp-bridge.service sudo systemctl start nanobot-whatsapp-bridge.service
sudo systemctl status nanobot-whatsapp-bridge.service
You should see Active: active (running). To view logs:
sudo journalctl -u nanobot-whatsapp-bridge.service -f
If you're using the systemd service from Appendix A, ensure the gateway service starts after the bridge:
sudo sed -i '/^After=/s/$/\nAfter=nanobot-whatsapp-bridge.service/' /etc/systemd/system/nanobot.service sudo systemctl daemon-reload sudo systemctl restart nanobot.service
sudo systemctl stop nanobot-whatsapp-bridge · Restart: sudo systemctl restart nanobot-whatsapp-bridge · Disable auto-start: sudo systemctl disable nanobot-whatsapp-bridge~/.nanobot/bridge/. If you delete this directory, you'll need to re-scan the QR code. Back it up before major system changes.