Prerequisites check
Verifies Docker and Docker Compose are installed on your system
From zero to running bot in under five minutes. The interactive wizard handles project scaffolding, Docker config, and API key setup. You just answer the prompts.
Quick start
One command scaffolds everything: Docker Compose file, .env with your keys, IDENTITY.md and SOUL.md templates, and OpenClaw configuration.
npx @keyoku/bot initThe wizard runs interactively in your terminal. Each prompt has sensible defaults — press Enter to accept them.
Verifies Docker and Docker Compose are installed on your system
OpenAI (API key), OpenAI (ChatGPT subscription), Anthropic, or Google Gemini
Choose the specific model for chat (e.g., openai/gpt-5.4, anthropic/claude-sonnet-4-6)
Enter your LLM provider API key, or configure ChatGPT OAuth (no key needed)
Which provider and model handles memory extraction (can differ from chat LLM for cost savings)
Choose Gemini or OpenAI for semantic memory search embeddings
Telegram, Discord, or API-only
Telegram bot token or Discord bot token and app ID (skipped for API-only)
Writes .env and docker-compose.yml, then optionally runs docker compose up -d
Create a bot through Telegram's official @BotFather, then paste the token into the wizard (or your .env file).
Open Telegram, message @BotFather, send /newbot. Follow the prompts to set a name and username.
BotFather replies with an HTTP API token. Copy it — this goes into TELEGRAM_BOT_TOKEN in your .env file.
Send /setcommands to @BotFather, select your bot, then paste: start - Start the bot, help - Show help. This registers slash commands in the Telegram UI.
Discord requires an application, a bot user, gateway intents, and an OAuth2 invite URL. It takes a few more steps than Telegram but the wizard guides you through it.
Go to discord.com/developers/applications and click New Application. Give it a name.
In your application, go to the Bot tab and click Add Bot. Copy the token — this is DISCORD_BOT_TOKEN.
On the Bot tab, enable Message Content Intent under Privileged Gateway Intents. This lets the bot read message content.
Go to OAuth2 > URL Generator. Select the bot scope. Under Bot Permissions, enable: Send Messages, Read Message History, Embed Links, Attach Files, Use Slash Commands.
Copy the generated URL and open it in your browser. Select your server and authorize the bot.
On the General Information tab, copy the Application ID. This goes into DISCORD_APP_ID in your .env file.
Running
If you didn't start during init, bring up the Docker Compose stack manually. The status command confirms everything is healthy.
# Start all services in background
docker compose up -d
# Verify health, memory stats, and watcher
npx @keyoku/bot statusAll configuration lives in the .env file generated by the wizard. Edit it directly to change providers, models, or channel settings.
The LLM model used for chat responses.
Uses provider prefix format. Examples: openai/gpt-5.4, anthropic/claude-sonnet-4-6, gemini/gemini-2.5-flash.
default: Provider-dependentOpenAI API key.
Required when using OpenAI as bot, extraction, or embedding provider.
default: ---Anthropic API key.
Required when using Anthropic as bot or extraction provider.
default: ---Google Gemini API key.
Required when using Gemini as bot, extraction, or embedding provider.
default: ---LLM provider for memory extraction.
Accepts "openai", "anthropic", or "gemini". Can differ from the chat provider for cost optimization.
default: Same as chat providerSpecific model for extraction.
Use a cheaper/faster model here if chat uses a premium one.
default: Provider-dependentProvider for semantic memory search embeddings.
Accepts "gemini" or "openai".
default: geminiModel used for generating embeddings.
Examples: gemini-embedding-001, text-embedding-3-small.
default: gemini-embedding-001Authentication token for the Keyoku engine API.
Auto-generated during init as a secure random hex string.
default: Auto-generatedPath to the Keyoku SQLite database file inside the container.
default: /data/keyoku.dbPort the Keyoku engine listens on inside the container.
default: 18900Whether the heartbeat watcher starts automatically when the engine launches.
default: trueEnable adaptive heartbeat intervals.
Adjusts based on activity, time of day, and signal density.
default: trueComma-separated list of entity IDs the watcher monitors for heartbeat signals.
default: defaultBase heartbeat interval in milliseconds (300000 = 5 minutes).
Adaptive mode adjusts this dynamically.
default: 300000Authentication token for the OpenClaw gateway.
Auto-generated during init as a secure random hex string.
default: Auto-generatedActive channel: "telegram", "discord", or omitted for API-only.
Determines which adapter loads at startup.
default: telegramBot token from @BotFather.
Required when BOT_CHANNEL is telegram.
default: ---Bot token from the Discord Developer Portal.
Required when BOT_CHANNEL is discord.
default: ---Application ID from the Discord Developer Portal.
Required for Discord channel.
default: ---Now customize its personality with IDENTITY.md and SOUL.md, or explore the CLI commands for debugging and memory inspection.