howto

kanipi

AI agent across telegram, whatsapp, and discord.
From your phone.

A multitenant Claude agent gateway. Send it a message on Telegram, Discord, or WhatsApp — it reads and edits files, runs commands, searches the web, and deploys web apps via Vite. Each conversation gets its own container.

Contents
Setup
01

Prerequisites

Docker on your server
A messaging account — Telegram, Discord, or WhatsApp
Claude OAuth token from claude.ai
02

Clone and build

terminal
$ git clone https://krons.fiu.wtf/kanipi
$ cd kanipi
$ make image
03

Create instance

terminal
$ ./kanipi create mybot

Creates:

/srv/data/kanipi_mybot/.env configuration
/srv/data/kanipi_mybot/store/ SQLite DB, auth state
/srv/data/kanipi_mybot/groups/ per-group folders
/srv/data/kanipi_mybot/data/ IPC, sessions
/srv/data/kanipi_mybot/web/ Vite web app
systemd service unit
04

Configure

Edit /srv/data/kanipi_mybot/.env:

.env
ASSISTANT_NAME="mybot"
CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat-..."

# enable channels by adding their token
TELEGRAM_BOT_TOKEN="123456:ABC-xyz..."
DISCORD_BOT_TOKEN="MTIz..."

VITE_PORT=5173

Channel activation:

Telegram — set TELEGRAM_BOT_TOKEN
Discord — set DISCORD_BOT_TOKEN
WhatsApp — auto-enabled when auth credentials exist in store/auth/
05

Start

terminal
$ sudo systemctl start kanipi_mybot

Or manually with docker:

docker
$ docker run -i --rm --network=host \
    -v /srv/data/kanipi_mybot:/srv/app/home \
    -v /var/run/docker.sock:/var/run/docker.sock \
    kanipi \
    ./kanipi mybot
06

Usage

Mention the bot or send it a direct message — it responds as Claude
It can build and deploy web apps to /workspace/web/, served by Vite
Each conversation spawns its own Docker container with full shell access
Containers idle-timeout automatically when inactive

Web file layout

Web files live under /workspace/web/ inside the container. The /pub/ URL prefix is the auth boundary:

web/pub/ — publicly accessible, no authentication required
web/priv/ — auth-gated, not accessible without login

Agent identity (character.json)

Agent personality is defined in container/character.json (ElizaOS-style: bio, topics, adjectives, style, messageExamples). Fields are randomized per query. Per-instance overrides go in /workspace/global/character.json and are merged at runtime.

Upgrading existing instances (migration system)

Skills and CLAUDE.md are seeded per group on first spawn. To sync all groups after a kanipi update, use the /migrate skill. It checks container/skills/self/MIGRATION_VERSION against each group's applied version and runs any pending numbered migration files from container/skills/self/migrations/.

Registering groups

Start the bot, add it to a chat, then register the group. List available (unregistered) chats the bot has seen:

terminal
$ ./kanipi config mybot group list
$ ./kanipi config mybot group add tg:-1234567890
$ ./kanipi config mybot group rm  tg:-1234567890

The first group registered becomes folder=main with no trigger required. Subsequent groups require a trigger (@botname) and a folder name as the third argument.

07

Agent capabilities

Steering a running agent

Send a follow-up message while an agent is still processing. The gateway pipes it into the active container — no new container is spawned. The agent sees it as a new user turn and can change course.

Messages sent while no container is running queue normally and start a fresh container.

Subagents (Agent Teams)

The agent can spawn subagents via the Task tool. Subagents run inside the same container — shared filesystem, shared mounts, same MCP server. They are not independent docker containers and cannot be addressed separately.

Subagents can call send_message to push updates to the chat, and can read/write the same /workspace/group/ folder.

Progress messages

The agent can send messages mid-task via the mcp__nanoclaw__send_message tool. The final result is sent automatically — send_message is for intermediate updates only.

CLAUDE.md hint
# in the agent's CLAUDE.md or system prompt:
For tasks expected to take >30s, call send_message
with a brief progress update every ~60s.

Scheduled tasks

Agents schedule work via mcp__nanoclaw__schedule_task. Each run spawns a fresh independent container — unlike subagents, these are fully isolated.

cronRecurring on a schedule — 0 9 * * * for daily 9am
intervalRecurring every N milliseconds
onceSingle run at a specific local timestamp. After running, status becomes completed and the task never runs again. Use cancel_task to delete it.

Tasks run in group context (with conversation history) or isolated context (fresh session — include all needed context in the prompt).

Features
#
Multi-channel
Telegram, Discord, WhatsApp
[ ]
Container isolation
Per-conversation sandboxing
</>
Web deploy
Vite apps from chat
MCP
MCP sidecars
Extensible tool servers
cron
Scheduled tasks
Cron, interval, or once
>_
Subagents
Parallel work via Task tool
···
Progress updates
Mid-task messages via IPC