Skip to content

Operator Setup

This guide walks you through self-hosting your own ique.bot instance with a Telegram bot.

Prerequisites

  • Node.js 20+ — check with node --version
  • pnpm — install with npm i -g pnpm
  • A Telegram bot token — create one via @BotFather in Telegram
  • An Anthropic API key — from console.anthropic.com

Step 1: Clone and Install

bash
git clone https://github.com/watthem/nanoclaw.git
cd nanoclaw
pnpm install

Step 2: Configure Environment

bash
cp .env.example .env

Edit .env and add your tokens:

bash
# Required
TELEGRAM_BOT_TOKEN=123456:ABC-DEF...   # From @BotFather
ANTHROPIC_API_KEY=sk-ant-...            # From Anthropic console

# Optional — only if you want the /radar boutique
RADAR_API_KEY=msr_...

TIP

ANTHROPIC_API_KEY is not in .env.example. You need to add the line yourself.

Step 3: Start

bash
./ique/start.sh

You should see output like:

[ique] DB: /path/to/nanoclaw/ique/ique.db
[ique] Starting ique.bot stack...

[ique server] Listening on port 3900
[radar] Starting worker loop
[track-triage] Starting worker loop
[telegram] Bot launched, listening for messages

[ique] All processes started:
  Server:       PID 12345 (port 3900)
  Radar:        PID 12346
  Track Triage: PID 12347
  Telegram:     PID 12348

The database is auto-created on first run from ique/setup.sql.

Press Ctrl+C to stop all processes.

Step 4: Test

Open your bot in Telegram and send a message. Try:

MessageWhat should happen
/radar AAPLFetches SEC insider filings for Apple, returns a briefing
track statsReturns counts from your music vault (if configured)
helloRoutes to butler (default) via keyword fallback

If the bot doesn't respond, check the terminal for errors. Most common issue: missing ANTHROPIC_API_KEY.

What Start.sh Launches

start.sh is a bash script that runs four processes in the background:

  1. ique server — HTTP API on port 3900. Routes messages and manages the queue.
  2. Radar worker — Polls queue for /radar tasks.
  3. Track Triage worker — Polls queue for /triage tasks.
  4. Telegram adapter — Bridges Telegram to the ique server via HTTP.

All processes share one SQLite database. If you don't need a specific worker, comment out its line in start.sh.

Choosing Which Boutiques to Run

Edit start.sh. Comment out or add worker lines:

bash
# Workers you want:
npx tsx groups/radar/worker.ts &
PIDS+=($!)

# Workers you don't want — comment out:
# npx tsx groups/track-triage/worker.ts &
# PIDS+=($!)

If a boutique is registered in the database but its worker isn't running, messages will route to it but sit in queued forever. No crash, no error — just no response.

Running a Public Bot

If you want other people to message your bot (not just you):

  1. Don't set the bot as private in @BotFather
  2. Run the stack on a server with a stable internet connection (VPS, home server, etc.)
  3. Consider which boutiques you want to expose — comment out any that touch private data

The users table has an allowed_boutiques field (JSON array) that controls which boutiques each user can access. By default, new users get access to all active boutiques. To restrict access, update the user record:

bash
node -e "
  const { DatabaseSync } = require('node:sqlite');
  const db = new DatabaseSync('ique/ique.db');
  db.prepare(
    \"UPDATE users SET allowed_boutiques = ? WHERE telegram_id = ?\"
  ).run('[\"radar\"]', '12345');
  db.close();
"

Environment Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
ANTHROPIC_API_KEY(required)Anthropic API key for LLM calls
IQUE_PORT3900Port for the ique HTTP server
IQUE_DB_PATH./ique/ique.dbPath to the SQLite database
IQUE_URLhttp://localhost:3900URL the adapter uses to reach the server
DISPATCH_INTERVAL2000How often the adapter polls for responses (ms)
RADAR_API_KEY(optional)Matchstick Radar API key for /radar
VAULT_MUSIC_DIR~/Obsidian/workshop/MusicPath to Obsidian vault for track-triage
BOUTIQUE_MODELclaude-haiku-4-5-20251001LLM model workers use

Troubleshooting

Bot doesn't respond at all:

  • Is the terminal still running? Check for crash output.
  • Is TELEGRAM_BOT_TOKEN correct? Try a fresh token from @BotFather.
  • Is ANTHROPIC_API_KEY set? Workers need it to call the LLM.

Bot responds to /radar but not /triage:

  • Is the track-triage worker running? Check the PID output in the terminal.
  • Is track-triage in the boutiques table? Check with:
bash
node -e "
  const { DatabaseSync } = require('node:sqlite');
  const db = new DatabaseSync('ique/ique.db');
  console.log(db.prepare('SELECT boutique_id, status FROM boutiques').all());
  db.close();
"

"Music vault not found" error:

  • Set VAULT_MUSIC_DIR in .env to the directory containing Tracks/, Personas/, Collections/.
  • If you don't have a music vault, comment out the track-triage worker in start.sh.

Task stuck in "queued":

  • The worker for that boutique isn't running. Start it.

Task stuck in "completed":

  • The adapter isn't running or can't reach the ique server. Check IQUE_URL.

Next Steps