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, Vertex AI, or Brave Search quotas fast. Set GCP budget alerts 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 your selected model provider (Gemini API, Vertex AI, Groq, etc.) and Brave Search when web search is enabled. 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, Vertex-capable 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 dedicated service account with only Vertex AI access, a free-tier e2-micro VM, and automatically configures a 2 GB swap file on first boot — all in one step. This lets you switch to Vertex AI later without recreating the VM.
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 # ── Step 0: Identify the Google Cloud project ────────────────── # Cloud Shell already knows the active project selected in GCP. # Auto-detecting it avoids copy/paste mistakes with project IDs. PROJECT_ID="$(gcloud config get-value project 2>/dev/null)" ZONE="us-central1-a" # Always Free e2-micro is region-limited; keep this zone. # ───────────────────────────────────────────────────── set -uo pipefail # Keep undefined variables/pipeline errors visible, but continue for readable diagnostics. VM_NAME="nanobot-vm" ; SA_NAME="nanobot-sa" FAILED=0 # ── Step 1: Save a Cloud Shell log ───────────────────────────── # Cloud Shell can disconnect or be closed. This log lives in your # Cloud Shell home directory, so you can reopen Cloud Shell later # and inspect what happened. LOG_DIR="${HOME}/nanobot-logs" mkdir -p "$LOG_DIR" LOG_FILE="${LOG_DIR}/gcp-vm-create-$(date +%Y%m%d-%H%M%S).log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "📍 Project ID: $PROJECT_ID" echo "📍 Zone: $ZONE" echo "🧾 Cloud Shell setup log: $LOG_FILE" echo " If Cloud Shell disconnects, reopen it and run:" echo " ls -lt ~/nanobot-logs && tail -n 160 ~/nanobot-logs/gcp-vm-create-*.log" echo "" # ── Step 2: Enable required GCP APIs ─────────────────────────── # Compute Engine API creates the VM. IAM API creates the service # account that the VM will run as. Vertex AI API lets the VM use # Application Default Credentials for Vertex models later. echo "🔌 Enabling APIs (Compute + IAM + Vertex AI)…" if ! gcloud services enable compute.googleapis.com iam.googleapis.com aiplatform.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 # ── Step 3: Create a least-privilege service account ─────────── # The VM uses this identity for Application Default Credentials. # It receives Vertex AI User only: enough to call Vertex models, # but not enough to administer Compute, IAM, Storage, or Secrets. echo "🔐 Creating dedicated service account…" if gcloud iam service-accounts create "$SA_NAME" \ --display-name="Nanobot SA — Vertex AI only" \ --project="$PROJECT_ID" 2>&1; then echo " ↳ Service account created." else echo " ↳ Service account may already exist; continuing." fi SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" if [ $FAILED -eq 0 ]; then echo "🎯 Granting Vertex AI User to $SA_EMAIL…" if ! gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/aiplatform.user" \ --condition=None >/dev/null 2>&1; then echo "❌ Failed to grant Vertex AI User role." >&2 FAILED=1 else echo " ↳ Vertex AI permission confirmed." fi fi if [ $FAILED -eq 0 ]; then # ── Step 4: Prepare first-boot startup script ──────────────── # The free-tier e2-micro has limited RAM. This script runs once # on first boot and adds a 2 GB swap file so installs and small # agent workloads are less likely to be killed by low memory. 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 # Persist startup diagnostics on the VM boot disk. This can be read # later with: sudo tail -n 160 /var/log/nanobot-startup.log exec > >(tee -a /var/log/nanobot-startup.log) 2>&1 echo "[$(date -Is)] Nanobot VM startup script started" if [ ! -f /swapfile ]; then echo "Creating 2 GB swap file..." 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 else echo "Swap file already exists; leaving it unchanged." fi free -h || true echo "[$(date -Is)] Nanobot VM startup script finished" STARTUP_EOF # ── Step 5: Create the VM ──────────────────────────────────── # e2-micro + Debian + standard 10 GB boot disk are chosen for # Google Cloud's free-tier constraints. cloud-platform scope lets # Google client libraries request tokens; IAM still restricts the # service account to Vertex AI User only. block-project-ssh-keys # keeps SSH access scoped to this instance rather than inheriting # every project-level SSH key. 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/cloud-platform \ --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" echo "" echo "▶ VM startup/swap log from Cloud Shell:" echo " gcloud compute instances get-serial-port-output $VM_NAME --zone=$ZONE --project=$PROJECT_ID --port=1 | tail -n 200" 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 "" echo "▶ Cloud Shell setup log saved at: $LOG_FILE" echo ""
roles/aiplatform.user. That allows Vertex AI model calls through Application Default Credentials, but does not grant Compute, IAM, Storage, Secret Manager, or project-admin access. The VM startup script configures 2 GB swap automatically on first boot, before you even connect.nanobot-sa.If Cloud Shell disconnects, reopen Cloud Shell and inspect the persisted setup log in your Cloud Shell home directory. VM startup output is also available through serial-port output, which does not require SSH into the VM.
ls -lt ~/nanobot-logs tail -n 160 ~/nanobot-logs/gcp-vm-create-*.log
gcloud compute instances get-serial-port-output nanobot-vm --zone=us-central1-a --port=1 | tail -n 200
sudo tail -n 160 /var/log/nanobot-startup.log
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. The service account receives only Vertex AI User so the VM can call Vertex AI later without storing a JSON key.
PROJECT_ID="$(gcloud config get-value project 2>/dev/null)"
gcloud services enable compute.googleapis.com iam.googleapis.com aiplatform.googleapis.com --project="$PROJECT_ID"
gcloud iam service-accounts create nanobot-sa \
--display-name="Nanobot SA — Vertex AI only" \
--project="$PROJECT_ID" || true
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:nanobot-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/aiplatform.user" \
--condition=None
Or via the Console: IAM & Admin → Service Accounts → + Create Service Account — fill name nanobot-sa, grant Vertex AI User, 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; under Access scopes, choose Allow full access to all Cloud APIs. IAM still limits this service account to Vertex AI only.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 '
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... or AQ.| Gemma 4 26B free tier | What to check |
|---|---|
| Default model in this guide | gemma-4-26b-a4b-it |
| Where the free limit is shown | Google AI Studio → Usage & billing → Rate limits for your project/model |
| How limits are enforced | Per project, across RPM, input TPM, and RPD; hitting any one limit can return a 429 rate-limit error. |
| Daily reset | Requests/day quotas reset at midnight Pacific time. |
| GCP billing impact | AI Studio usage remains separate from the VM free tier; enabling a paid tier is optional and changes API quotas. |
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.gemini/. For Groq GPT-OSS, use a Groq model ID such as openai/gpt-oss-20b or openai/gpt-oss-120b while keeping provider groq. Examples: gemma-4-26b-a4b-it, claude-sonnet-4-6, openrouter/auto, openai/gpt-oss-20b.
apt-get upgrade can restart services on the tiny free-tier VM and cut off your SSH session before Nanobot, config.json, or the systemd service are created.Loading…
~/.nanobot, reinstalls missing Python packages, rewrites config.json, and recreates the systemd unit.ls -lt ~/.nanobot/install-logs tail -n 200 ~/.nanobot/install-logs/nanobot-install-*.log ls -l ~/.nanobot/venv/bin/nanobot ~/.nanobot/config.json /etc/systemd/system/nanobot.service ls -l ~/.litellm-vertex/config.yaml /etc/systemd/system/litellm-vertex.service 2>/dev/null || true
sudo apt-get update sudo apt-get install -y python3-venv python3-pip curl openssl
mkdir -p ~/.nanobot/workspace python3 -m venv ~/.nanobot/venv
~/.nanobot/venv/bin/python -m pip install --upgrade pip ~/.nanobot/venv/bin/python -m pip install nanobot-ai
test -x ~/.nanobot/venv/bin/nanobot ~/.nanobot/venv/bin/nanobot --version
nano ~/.nanobot/config.json
Loading…
chmod 600 ~/.nanobot/config.json
Choose how to run Nanobot from your VM terminal.
Method 1 — Foreground (recommended for first run)
Watch all output in real time. Press Ctrl+C to stop.
~/.nanobot/venv/bin/nanobot gateway
Method 2 — Background with nohup (survives SSH disconnect)
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" |
The auto-install script runs Nanobot as a system service so it starts after reboot and restarts after crashes.
sudo systemctl status nanobot --no-pager sudo journalctl -u nanobot -f sudo systemctl restart nanobot
sudo systemctl stop nanobot ~/.nanobot/venv/bin/nanobot gateway
| 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.provider | Set to brave; Nanobot's web search tool uses Brave Search. |
| tools.web.search.apiKey | Brave Search API key. 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. |
| providers.custom.apiBase | When Vertex AI is selected, points Nanobot to local LiteLLM at http://127.0.0.1:4000/v1; LiteLLM then calls Vertex AI using the VM service account. |
| agents.defaults.model | For Vertex AI mode this stays vertexaimodel. The real Vertex model ID is configured in LiteLLM, so changing Vertex models does not require changing Nanobot's alias. |
| maxToolIterations: 40 | Caps tool calls per response — prevents runaway loops from exhausting API quotas. |
/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 ✅ |
| Gemma 4 26B (AI Studio) | Check live AI Studio rate limits | Low ✅ |
| Vertex AI models | Uses GCP billing/trial credits; not part of the AI Studio free tier | Keep budget alerts on ✅ |
| 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.