# What is BabyClaw? BabyClaw is a self-hosted gateway that connects an AI agent to Telegram. You run a single process on your machine (or a server), and it becomes a bridge between your messaging app and an AI model. You message it, it thinks, it can use tools, and it messages you back. ## Why BabyClaw? [OpenClaw](https://github.com/openclaw/openclaw){rel=""nofollow""} is a great project, but it's also a beast -- dozens of channels, companion apps, voice wake, canvas, sandboxing, and a codebase that moves fast. BabyClaw exists because sometimes you just want a personal AI assistant that you can understand end-to-end, hack on, and keep running without chasing upstream changes. It's not a fork. It's a reimplementation of the parts that matter most for a single-user personal assistant. Same workspace concept. Same skill ecosystem (ClawHub compatible). Just \~5% of the complexity. ## What's included - **Agent loop** built on the [Vercel AI SDK](https://sdk.vercel.ai/){rel=""nofollow""} -- streaming tool calls, multi-provider support - **SQLite database** managed with [Drizzle](https://orm.drizzle.team/){rel=""nofollow""} -- sessions, messages, schedules, heartbeats, all in one file - **Telegram channel** via [grammY](https://grammy.dev/){rel=""nofollow""} -- text, photos, streaming replies, command approval buttons - **Scheduler** -- one-off and recurring cron tasks with timezone support and overlap prevention - **Heartbeat system** -- periodic proactive check-ins with configurable active hours - **Memory extraction** -- automatic daily memory files - **Workspace and skills** -- personality files, agent instructions, and the full [ClawHub](https://clawhub.ai){rel=""nofollow""} skill ecosystem - **Shell tool** with allowlist/approval modes - **Web search** via Brave Search API - **Cross-chat messaging** -- link chats with aliases, send messages between them - **CLI** with interactive setup wizard, service management, and diagnostics ## Architecture ```mermaid flowchart TB Telegram["Telegram (grammY)"] --> Gateway Gateway --> AgentLoop["Agent Loop (Vercel AI SDK)"] Gateway --> SQLite["SQLite (Drizzle)"] Gateway --> Scheduler Gateway --> Heartbeat Gateway --> MemorySystem["Memory System"] Gateway --> Skills["Skills / ClawHub"] AgentLoop --> Providers["Anthropic / OpenAI / Google / Mistral / xAI / OpenRouter"] ``` ## BabyClaw vs OpenClaw | | BabyClaw | OpenClaw | | ------------------ | ----------------------- | ----------------------------------- | | **Codebase** | \~5% of OpenClaw's size | Large (TypeScript + Swift + Kotlin) | | **Agent loop** | Vercel AI SDK | Custom Pi agent runtime | | **Database** | SQLite (Drizzle) | In-memory + file-based | | **Channels** | Telegram (extensible) | 13+ channels | | **Companion apps** | None | macOS, iOS, Android | | **Voice** | No | Wake word + Talk Mode | | **Canvas** | No | A2UI visual workspace | | **Sandboxing** | No | Docker per-session | | **Skills** | ClawHub compatible | ClawHub compatible | | **Workspace** | Same concept | Same concept | ## What you need - **Node.js 20** or newer - A **Telegram bot token** (free, from [@BotFather](https://t.me/BotFather){rel=""nofollow""}) - An **AI provider API key** (Anthropic recommended, but OpenAI, Google, Mistral, xAI, and OpenRouter all work) Ready to set it up? Run the one-liner or head to [Installation](https://docs.babyclaw.org/getting-started/installation) for the full guide: ```bash curl -fsSL https://babyclaw.org/install.sh | bash ``` # Installation This guide takes you from zero to a running BabyClaw instance with a working Telegram bot. ## Quick install (recommended) The fastest way to get started — a single command that checks your environment, installs BabyClaw, and walks you through the setup wizard: ```bash curl -fsSL https://babyclaw.org/install.sh | bash ``` The installer will: - Verify Node.js >= 20 is present (and help you install it if not) - Install the `babyclaw` CLI globally via npm - Launch the interactive setup wizard - Run diagnostics to confirm everything works Once it finishes you can skip ahead to [Send your first message](https://docs.babyclaw.org/#5-send-your-first-message). ## Manual install If you prefer to install manually, or want to develop on BabyClaw itself, follow the steps below. ### Prerequisites - **Node.js 20** or newer -- check with `node --version` - **pnpm** -- install with `npm install -g pnpm` if you don't have it ### 1. Install via npm ```bash npm install -g babyclaw ``` Or, to build from source: ```bash git clone https://github.com/babyclaw/babyclaw.git cd babyclaw pnpm install pnpm build ``` ## 2. Create a Telegram bot 1. Open Telegram and message [@BotFather](https://t.me/BotFather){rel=""nofollow""} 2. Send `/newbot` and follow the prompts 3. Copy the bot token (looks like `123456789:ABCdefGHIjklMNOpqrsTUVwxyz`) You'll need this token in the next step. ## 3. Run the setup wizard ```bash pnpm babyclaw config init ``` This creates a config file at `~/.config/babyclaw/config.json` with placeholder values. Next, configure your AI provider interactively: ```bash pnpm babyclaw model configure ``` Or edit the config file directly -- the minimum you need is a Telegram bot token and one AI provider: ```json { "version": 1, "channels": { "telegram": { "botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" } }, "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." } }, "models": { "chat": "anthropic:claude-sonnet-4-20250514" }, "aliases": {} } } ``` See [AI Providers](https://docs.babyclaw.org/configuration/ai-providers) for how to configure other providers. ## 4. Start the gateway ```bash pnpm babyclaw service start ``` Or run it directly in the foreground: ```bash node packages/gateway/dist/main.js ``` ## 5. Send your first message Open Telegram and message your bot. On the first conversation, the agent will go through a bootstrap process -- it'll ask your name, pick its own identity, and set up the workspace files. This is normal and only happens once. ## 6. Verify everything works ```bash pnpm babyclaw doctor ``` This runs diagnostics and checks that your config, database, and Telegram connection are healthy. ## Next steps - [Workspace](https://docs.babyclaw.org/getting-started/workspace) -- learn about the workspace files and how to customize your agent - [Configuration overview](https://docs.babyclaw.org/configuration/overview) -- understand the full config file - [Telegram](https://docs.babyclaw.org/features/telegram) -- more on how the Telegram integration works # Your Agent's Workspace The workspace is a directory where your agent keeps everything it needs: its identity, personality, instructions, memory, and installed skills. By default, it lives at `~/.config/babyclaw/workspace/`, but you can change this with the `workspace.root` config option. On first run, BabyClaw creates a set of template files in the workspace. These are starting points -- you and the agent will fill them in together during the bootstrap conversation. ## Workspace files | File | What it's for | | -------------- | ------------------------------------------------------------------ | | `IDENTITY.md` | The agent's name, creature type, vibe, and emoji | | `SOUL.md` | Personality, boundaries, and behavioral guidelines | | `USER.md` | Information about you -- name, timezone, preferences | | `AGENTS.md` | Workspace rules, conventions, and operating instructions | | `TOOLS.md` | Notes about local tools -- SSH hosts, API quirks, device names | | `HEARTBEAT.md` | Checklist for periodic heartbeat checks | | `BOOTSTRAP.md` | First-run onboarding script (deleted after the agent completes it) | ## The bootstrap process When the workspace is brand new, BabyClaw creates a `BOOTSTRAP.md` file. The first time you message the agent, it reads this file and walks through a getting-to-know-you conversation: picking a name, figuring out its personality, learning about you. Once bootstrap is done, the agent deletes `BOOTSTRAP.md`. It won't come back unless you create a completely fresh workspace. ## Customizing your agent You can edit any of these files at any time. The agent reads them at the start of each session. **Want a different personality?** Edit `SOUL.md`. The default template encourages the agent to be helpful without being performative, have opinions, and be resourceful. Change it to whatever works for you. **Want to give the agent context about you?** Edit `USER.md` with your name, timezone, projects you're working on, or anything else that helps. **Want to change how the agent operates?** Edit `AGENTS.md`. This is where conventions, safety rules, and workspace-specific instructions live. ## Memory The workspace also holds your agent's memory: - `memory/YYYY-MM-DD.md` -- daily memory files, created automatically after conversations - `MEMORY.md` -- curated long-term memory that the agent maintains over time See [Memory](https://docs.babyclaw.org/features/memory) for more on how this works. ## Skills Installed skills live in `skills/` inside the workspace. Each skill is a subdirectory with a `SKILL.md` file. The agent discovers them automatically. See [Skills](https://docs.babyclaw.org/features/skills) for how to install and manage skills. ## Directory structure A workspace after some use might look like this: ```text workspace/ ├── AGENTS.md ├── IDENTITY.md ├── SOUL.md ├── USER.md ├── TOOLS.md ├── HEARTBEAT.md ├── MEMORY.md ├── memory/ │ ├── 2026-02-18.md │ ├── 2026-02-19.md │ └── 2026-02-20.md └── skills/ ├── some-skill/ │ └── SKILL.md └── another-skill/ └── SKILL.md ``` # Configuration Overview BabyClaw reads its configuration from a JSON file. If you ran `babyclaw config init`, this file lives at `~/.config/babyclaw/config.json`. ## Minimal config The bare minimum to get BabyClaw running is a Telegram bot token and one AI provider: ```json { "version": 1, "channels": { "telegram": { "botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" } }, "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." } }, "models": { "chat": "anthropic:claude-sonnet-4-20250514" }, "aliases": {} } } ``` Everything else has sensible defaults. You only need to add config for things you want to change. ## Config sections The config file is organized into these top-level sections: | Section | What it controls | | ----------- | ----------------------------------------------------------- | | `version` | Always `1` (required) | | `channels` | Telegram bot token | | `ai` | Providers, models, and aliases | | `database` | SQLite database path | | `workspace` | Workspace directory path | | `session` | Message limits, history, reply chain mode, title generation | | `tools` | Which tools are enabled, shell security, web search | | `skills` | Per-skill enable/disable, API keys, environment variables | | `scheduler` | Timezone for scheduled tasks | | `heartbeat` | Periodic check-in settings | | `logging` | Log level, format, output | ## Validation BabyClaw validates the config strictly against its schema. If something is wrong -- unknown keys, bad types, missing required fields -- the gateway will refuse to start and tell you what's wrong. You can check your config without starting the gateway: ```bash babyclaw config validate ``` ## Editing the config There are a few ways to edit the config: **Open in your editor:** ```bash babyclaw config edit ``` **Interactive model setup:** ```bash babyclaw model configure ``` **Edit manually:** Open `~/.config/babyclaw/config.json` in any text editor. The gateway will pick up changes on the next restart. ## Defaults Most config fields have defaults, so you don't need to specify them. For example: - `database.url` defaults to `"file:../data/babyclaw.db"` - `scheduler.timezone` defaults to `"UTC"` - `session.historyLimit` defaults to `40` - `tools.shell.mode` defaults to `"allowlist"` - `heartbeat.enabled` defaults to `false` See the [Configuration Reference](https://docs.babyclaw.org/configuration/reference) for every field and its default value. ## Next steps - [AI Providers](https://docs.babyclaw.org/configuration/ai-providers) -- setting up different AI providers - [Configuration Reference](https://docs.babyclaw.org/configuration/reference) -- every field, type, and default # AI Providers BabyClaw uses the [Vercel AI SDK](https://sdk.vercel.ai/){rel=""nofollow""} under the hood, which means it works with multiple AI providers out of the box. You can configure one or several providers and assign different models to different tasks. ## Supported providers - **Anthropic** (Claude) -- recommended - **OpenAI** (GPT, o-series) - **Google** (Gemini) - **Mistral** - **xAI** (Grok) - **OpenRouter** (any model behind their API) - **Vercel AI Gateway** Each provider just needs an API key. Some also accept a custom `baseUrl` if you're using a proxy or self-hosted endpoint. ## Configuring a provider Add providers under `ai.providers` in your config. The key is the provider name, and the value has at least an `apiKey`: ```json { "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." } } } } ``` You can configure multiple providers at once: ```json { "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." }, "openai": { "apiKey": "sk-..." }, "google": { "apiKey": "AIza..." } } } } ``` ### Custom base URL If you're using a proxy, self-hosted endpoint, or OpenRouter, set `baseUrl`: ```json { "ai": { "providers": { "openrouter": { "apiKey": "sk-or-...", "baseUrl": "https://openrouter.ai/api/v1" } } } } ``` ## Setting models BabyClaw uses up to two models for different tasks: | Model | Required | Purpose | | -------- | -------- | ------------------------------------------------------------- | | `chat` | Yes | Main conversation model -- handles messages and tool calls | | `vision` | No | Used when processing images (falls back to `chat` if not set) | Models are referenced as `provider:modelId`: ```json { "ai": { "models": { "chat": "anthropic:claude-sonnet-4-20250514", "vision": "openai:gpt-4o" } } } ``` The provider name before the colon must match a key in `ai.providers`. ## Model aliases Aliases let you define short names for models. This is handy if you switch models often or want something easier to type: ```json { "ai": { "aliases": { "sonnet": "anthropic:claude-sonnet-4-20250514", "gpt4": "openai:gpt-4o", "gemini": "google:gemini-2.5-pro" } } } ``` Alias names must be lowercase alphanumeric with hyphens or underscores (`^[a-z0-9_-]+$`). You can manage aliases from the CLI: ```bash babyclaw model alias # list aliases babyclaw model alias set --name sonnet --model anthropic:claude-sonnet-4-20250514 babyclaw model alias remove --name gpt4 ``` ## Provider examples ### Anthropic (recommended) ```json { "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." } }, "models": { "chat": "anthropic:claude-sonnet-4-20250514" } } } ``` ### OpenAI ```json { "ai": { "providers": { "openai": { "apiKey": "sk-..." } }, "models": { "chat": "openai:gpt-4o" } } } ``` ### Google (Gemini) ```json { "ai": { "providers": { "google": { "apiKey": "AIza..." } }, "models": { "chat": "google:gemini-2.5-pro" } } } ``` ### OpenRouter OpenRouter lets you access many models through a single API. Set the `baseUrl` to their endpoint: ```json { "ai": { "providers": { "openrouter": { "apiKey": "sk-or-...", "baseUrl": "https://openrouter.ai/api/v1" } }, "models": { "chat": "openrouter:anthropic/claude-sonnet-4" } } } ``` ### Mixed providers You can use different providers for different tasks: ```json { "ai": { "providers": { "anthropic": { "apiKey": "sk-ant-..." }, "openai": { "apiKey": "sk-..." } }, "models": { "chat": "anthropic:claude-sonnet-4-20250514", "vision": "openai:gpt-4o" } } } ``` ## Interactive setup If you'd rather not edit JSON, the CLI has an interactive wizard: ```bash babyclaw model configure ``` This walks you through picking a provider and entering your API key. # Configuration Reference This is the complete field-by-field reference for BabyClaw's config file (`~/.config/babyclaw/config.json`). ## `version` | | | | ------------ | ----------- | | **Type** | `number` | | **Required** | Yes | | **Value** | Must be `1` | Schema version. Always set this to `1`. ## `channels` ### `channels.telegram` | | | | ------------ | -------- | | **Type** | `object` | | **Required** | No | #### `channels.telegram.botToken` | | | | ------------ | ----------------------------------- | | **Type** | `string` | | **Required** | Yes (if `channels.telegram` is set) | Your Telegram bot token from [@BotFather](https://t.me/BotFather){rel=""nofollow""}. --- ## `telegram` | | | | ------------ | -------- | | **Type** | `object` | | **Required** | No | Legacy alternative to `channels.telegram`. Has the same `botToken` field. You can use either location -- `channels.telegram.botToken` is preferred. --- ## `ai` ### `ai.providers` | | | | ------------ | ----------------------------------------- | | **Type** | `object` (map of provider name to config) | | **Required** | Yes | At least one provider must be configured. Each provider has: | Field | Type | Required | Description | | --------- | -------------- | -------- | ------------------------------------------------------------- | | `apiKey` | `string` | Yes | API key for the provider | | `baseUrl` | `string` (URL) | No | Custom endpoint URL (for proxies, self-hosted, or OpenRouter) | ### `ai.models` | | | | ------------ | -------- | | **Type** | `object` | | **Required** | Yes | | Field | Type | Required | Default | Description | | -------- | -------- | -------- | ------- | -------------------------------------------- | | `chat` | `string` | Yes | -- | Main conversation model (`provider:modelId`) | | `vision` | `string` | No | -- | Model for image processing | ### `ai.aliases` | | | | ------------ | ------------------------------------------ | | **Type** | `object` (map of alias to model reference) | | **Required** | No | | **Default** | `{}` | Short names for models. Alias names must match `^[a-z0-9_-]+$`. --- ## `database` ### `database.url` | | | | ----------- | ---------------------------- | | **Type** | `string` | | **Default** | `"file:../data/babyclaw.db"` | SQLite connection string. The default stores the database alongside the gateway. --- ## `scheduler` ### `scheduler.timezone` | | | | ----------- | ------------------------ | | **Type** | `string` (IANA timezone) | | **Default** | `"UTC"` | Timezone used for scheduled tasks and heartbeat active hours. Must be a valid IANA timezone like `"America/New_York"` or `"Europe/London"`. --- ## `workspace` ### `workspace.root` | | | | ----------- | -------- | | **Type** | `string` | | **Default** | `"."` | Path to the agent's workspace directory. This is where personality files, memory, and skills live. --- ## `session` ### `session.maxMessagesPerSession` | | | | ----------- | --------- | | **Type** | `integer` | | **Default** | `120` | Maximum number of messages stored per session. Older messages are pruned when this limit is reached. ### `session.historyLimit` | | | | ----------- | --------- | | **Type** | `integer` | | **Default** | `40` | Number of recent messages included in the agent's context for each turn. Lower values reduce token usage; higher values give the agent more context. ### `session.replyChainMode` | | | | ----------- | ---------------------------- | | **Type** | `string` | | **Default** | `"default"` | | **Options** | `"default"`, `"reply-chain"` | In `"default"` mode, sessions are determined by chat and thread. In `"reply-chain"` mode, replying to a specific message continues that session's context. ### `session.titleGeneration` | | | | ----------- | -------- | | **Type** | `object` | | **Default** | `{}` | | Field | Type | Required | Description | | -------- | -------- | -------- | ----------------------------------------------------------------------- | | `model` | `string` | No | Model to use for generating session titles (defaults to the chat model) | | `prompt` | `string` | No | Custom prompt for title generation | --- ## `tools` ### `tools.enableGenericTools` | | | | ----------- | --------- | | **Type** | `boolean` | | **Default** | `true` | When `true`, the agent has access to workspace, shell, state, web search, messaging, media, and working memory tools. Set to `false` to restrict the agent to only scheduler and self-management tools. ### `tools.shell` | | | | -------- | -------- | | **Type** | `object` | #### `tools.shell.mode` | | | | ----------- | ------------------------------ | | **Type** | `string` | | **Default** | `"allowlist"` | | **Options** | `"allowlist"`, `"full-access"` | In `"allowlist"` mode, the agent can only run commands from the `allowedCommands` list. In `"full-access"` mode, it can run any command (a warning is logged at startup). #### `tools.shell.allowedCommands` | | | | ----------- | ------------------- | | **Type** | `array` of `string` | | **Default** | See below | Commands the agent is allowed to run in allowlist mode. The default list includes common file operations, text processing, git, Node.js/Python package managers, and network tools: `ls`, `cat`, `head`, `tail`, `wc`, `grep`, `rg`, `find`, `file`, `du`, `df`, `date`, `echo`, `env`, `pwd`, `sort`, `uniq`, `cut`, `awk`, `sed`, `tr`, `xargs`, `tee`, `diff`, `which`, `basename`, `dirname`, `realpath`, `mkdir`, `cp`, `mv`, `rm`, `touch`, `chmod`, `git`, `node`, `npm`, `npx`, `pnpm`, `yarn`, `python`, `python3`, `pip`, `pip3`, `curl`, `wget`, `jq`, `tar`, `zip`, `unzip`, `remindctl` ### `tools.webSearch` | | | | -------- | -------- | | **Type** | `object` | #### `tools.webSearch.braveApiKey` | | | | ----------- | ------------------ | | **Type** | `string` or `null` | | **Default** | `null` | API key for the [Brave Search API](https://brave.com/search/api/){rel=""nofollow""}. When set, the agent gets a `web_search` tool. When `null`, web search is disabled. --- ## `skills` ### `skills.entries` | | | | ----------- | -------------------------------------- | | **Type** | `object` (map of skill name to config) | | **Default** | `{}` | Per-skill configuration. Each entry can have: | Field | Type | Default | Description | | --------- | --------- | ------- | ---------------------------------------------- | | `enabled` | `boolean` | `true` | Enable or disable this skill | | `apiKey` | `string` | -- | API key for the skill (if it needs one) | | `env` | `object` | -- | Environment variables to inject for this skill | Example: ```json { "skills": { "entries": { "web-scraper": { "enabled": true }, "image-gen": { "enabled": true, "apiKey": "key-here", "env": { "IMAGE_MODEL": "dall-e-3" } } } } } ``` --- ## `logging` ### `logging.level` | | | | ----------- | ---------------------------------------- | | **Type** | `string` | | **Default** | `"info"` | | **Options** | `"debug"`, `"info"`, `"warn"`, `"error"` | ### `logging.format` | | | | ----------- | ------------------------------------------------ | | **Type** | `string` | | **Default** | `"pretty"` (development) / `"json"` (production) | | **Options** | `"json"`, `"pretty"` | ### `logging.output` | | | | ----------- | ---------- | | **Type** | `string` | | **Default** | `"stdout"` | Where to write logs. Defaults to standard output. ### `logging.redact` | | | | ----------- | ------------------- | | **Type** | `array` of `string` | | **Default** | `[]` | List of field names to redact from log output. ### `logging.includeTimestamps` | | | | ----------- | --------- | | **Type** | `boolean` | | **Default** | `true` | ### `logging.includeHostname` | | | | ----------- | --------- | | **Type** | `boolean` | | **Default** | `false` | --- ## `heartbeat` ### `heartbeat.enabled` | | | | ----------- | --------- | | **Type** | `boolean` | | **Default** | `false` | Enable periodic heartbeat check-ins. See [Heartbeat](https://docs.babyclaw.org/features/heartbeat). ### `heartbeat.intervalMinutes` | | | | ----------- | --------- | | **Type** | `integer` | | **Default** | `30` | | **Minimum** | `5` | Minutes between heartbeat runs. ### `heartbeat.activeHours` | | | | -------- | -------- | | **Type** | `object` | #### `heartbeat.activeHours.start` | | | | ----------- | ---------------------------- | | **Type** | `string` (`HH:MM`) or `null` | | **Default** | `null` | Start of the active window. When `null`, heartbeats can run at any time. #### `heartbeat.activeHours.end` | | | | ----------- | ---------------------------- | | **Type** | `string` (`HH:MM`) or `null` | | **Default** | `null` | End of the active window. ### `heartbeat.prompt` | | | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **Type** | `string` | | **Default** | `"Read HEARTBEAT.md if it exists. Follow its instructions. Do not infer or repeat old tasks from prior chats. If nothing needs attention, say so."` | The prompt sent to the agent on each heartbeat run. You can customize this, but the default works well with the standard `HEARTBEAT.md` workflow. # Telegram Telegram is currently the only messaging channel in BabyClaw. The integration is built on [grammY](https://grammy.dev/){rel=""nofollow""} and supports text messages, photos, streaming replies, slash commands, and inline approval buttons. ## Creating a bot 1. Open Telegram and message [@BotFather](https://t.me/BotFather){rel=""nofollow""} 2. Send `/newbot` 3. Choose a name (displayed in chats) and a username (must end in `bot`) 4. BotFather gives you a token -- copy it Add the token to your config: ```json { "channels": { "telegram": { "botToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" } } } ``` Start the gateway and message your bot. That's it. ## How conversations work Each Telegram chat (or topic within a forum-style group) creates a separate **session** in BabyClaw. The agent maintains independent context for each session, so conversations in different chats don't bleed into each other. The first chat you message the bot from becomes the **main session**. The main session is special -- it's the only one where cross-chat messaging tools and long-term memory extraction are active. ### Reply chains If you reply to one of the bot's messages, BabyClaw links your reply to the original session context. This is useful in groups where multiple conversations might be happening. You can also enable `"reply-chain"` mode in the config, which scopes sessions by reply thread rather than just by chat: ```json { "session": { "replyChainMode": "reply-chain" } } ``` ## Supported message types **Inbound (you to the bot):** - Text messages - Photos (processed with the vision model if configured) - Replies to bot messages **Outbound (bot to you):** - Text with Telegram MarkdownV2 formatting - Images - Files (documents, audio, video, animations) - Typing indicators while the agent is thinking ## Streaming replies When the agent generates a response, BabyClaw streams it to Telegram as a draft message that gets updated as new text arrives. You'll see the message being "typed" in real-time rather than waiting for the full response. If the agent is using tools (running a shell command, searching the web, etc.), you'll see a brief status update while it works. ## Slash commands The Telegram bot responds to a few built-in commands: | Command | What it does | | --------------- | ----------------------------------------------------------------- | | `/link ` | Link this chat with an alias so the agent can send messages to it | | `/unlink` | Unlink this chat | | `/schedules` | List active schedules for this chat | | `/heartbeat` | Show heartbeat status (enabled, next run time) | ### Linking chats Chat linking lets the agent send messages across different Telegram chats. To link a group chat: 1. Add your bot to the group 2. Send `/link my-group` (the alias is a short name you pick) 3. Now the agent can target `my-group` when sending scheduled messages or cross-chat messages Aliases must be lowercase alphanumeric with hyphens, like `work-chat` or `family`. ## Shell command approval When the agent tries to run a shell command that isn't in the allowlist, BabyClaw can send you an inline keyboard button to approve or deny it (instead of just blocking it). This gives you control without having to add every possible command to the allowlist upfront. ## Sending "stop" If the agent is in the middle of a long response or running tools, send `stop` to cancel the current turn. The agent will stop what it's doing and wait for your next message. # Tools BabyClaw gives the agent a set of tools it can use during conversations. When you ask it to read a file, run a command, or search the web, it's calling these tools behind the scenes. Tools are split into two groups: **always available** (scheduler and self-management) and **generic tools** (everything else). You can disable generic tools entirely by setting `tools.enableGenericTools` to `false` in your config. ## Workspace tools The agent can read, write, list, move, and delete files within its workspace directory. | Tool | What it does | | ------------------ | -------------------------- | | `workspace_read` | Read a file's contents | | `workspace_write` | Write or overwrite a file | | `workspace_list` | List files and directories | | `workspace_delete` | Delete a file | | `workspace_move` | Move or rename a file | These are scoped to the workspace directory -- the agent can't access files outside of it. ## Shell tools The agent can run shell commands on your machine. This is where things get interesting (and where you should think about security). | Tool | What it does | | ------------ | ----------------------- | | `shell_exec` | Execute a shell command | ### Shell security modes The `tools.shell.mode` config controls what the agent is allowed to run: **`"allowlist"` (default):** The agent can only run commands from the `tools.shell.allowedCommands` list. If it tries to run something else, the command is blocked (or sent to you for approval if you have the Telegram approval flow set up). The default allowlist includes common commands like `ls`, `cat`, `grep`, `git`, `node`, `python`, `curl`, and more -- about 50 commands that cover most everyday tasks. **`"full-access"`:** The agent can run any command. A warning is logged at startup. Use this if you trust the agent and your setup, but be aware of the risk. To add a command to the allowlist: ```json { "tools": { "shell": { "mode": "allowlist", "allowedCommands": ["ls", "cat", "git", "docker", "kubectl"] } } } ``` Note that setting `allowedCommands` replaces the entire default list, so include any defaults you still want. ## State tools A simple persistent key-value store scoped to the workspace. | Tool | What it does | | -------------- | ------------------- | | `state_get` | Read a value by key | | `state_set` | Store a value | | `state_list` | List all keys | | `state_delete` | Remove a key | State is stored as files in the workspace. Useful for the agent to track things between sessions. ## Web search When configured with a Brave Search API key, the agent can search the web. | Tool | What it does | | ------------ | --------------------------------- | | `web_search` | Search the web using Brave Search | To enable it, get an API key from the [Brave Search API](https://brave.com/search/api/){rel=""nofollow""} and add it to your config: ```json { "tools": { "webSearch": { "braveApiKey": "BSA..." } } } ``` ## Messaging tools In the main session, the agent can send messages to linked chats. | Tool | What it does | | ------------------ | --------------------------------------- | | `send_message` | Send a text message to a linked chat | | `list_known_chats` | List all linked chats and their aliases | These only appear in the main session. In other sessions, messaging tools aren't available (to prevent the agent from leaking context across chats). ## Media tools The agent can send files through the channel. | Tool | What it does | | ----------- | -------------------------------------------------------- | | `send_file` | Send an image, document, audio file, video, or animation | ## Working memory A per-session scratchpad that the agent uses to keep notes during a conversation. | Tool | What it does | | ----------------------- | ----------------------------------- | | `update_working_memory` | Update the session's working memory | Working memory is temporary -- it exists for the duration of a session and is included in the agent's context on each turn. The agent uses it to track things like file paths, IDs, or intermediate results it needs to remember within a conversation. ## Self tools The agent can check its own status and manage the gateway. | Tool | What it does | | -------------- | --------------------------------------------------------------------- | | `self_status` | Check gateway status, uptime, active turns, scheduler/heartbeat state | | `self_restart` | Restart the gateway process | ## ClawHub tools The agent can install skills from ClawHub during a conversation. | Tool | What it does | | ----------------- | ----------------------------------------- | | `clawhub_install` | Install a skill from the ClawHub registry | ## Scheduler tools Always available, regardless of the `enableGenericTools` setting. | Tool | What it does | | ------------------ | ----------------------------------------------- | | `get_current_time` | Get the current time in the configured timezone | | `create_schedule` | Create a one-off or recurring schedule | | `list_schedules` | List active schedules | | `cancel_schedule` | Cancel a schedule | See [Scheduling](https://docs.babyclaw.org/features/scheduling) for more on how scheduling works. # Scheduling BabyClaw has a built-in scheduler that lets the agent create tasks to run at specific times or on a recurring basis. You don't configure schedules in the config file -- instead, you just ask the agent to schedule something in conversation. ## How it works The agent has access to scheduler tools (`create_schedule`, `list_schedules`, `cancel_schedule`) during conversations. When you say something like "remind me to check email every morning at 9am", the agent creates a recurring schedule using these tools. When a schedule fires, the agent runs a turn with the scheduled prompt, and the result gets delivered to the original chat (or a different chat if cross-chat delivery was set up). ## One-off schedules Ask the agent to do something at a specific time: > "Remind me to call the dentist tomorrow at 2pm" > "Send me a weather report at 6am on Saturday" The agent creates a one-off schedule that runs once and then is done. ## Recurring schedules Ask for something to repeat on a schedule: > "Every Monday at 9am, check my email and summarize anything important" > "Every day at 6pm, give me a summary of what we worked on today" Recurring schedules use cron expressions under the hood. The agent handles the cron syntax -- you just describe when you want it to run. The minimum interval for recurring schedules is 5 minutes. ## Timezone Schedules use the timezone from your config: ```json { "scheduler": { "timezone": "America/New_York" } } ``` If you don't set this, it defaults to UTC. The agent also has a `get_current_time` tool that returns the current time in the configured timezone, so it knows what "tomorrow at 9am" means in your local time. ## Cross-chat delivery If you've [linked chats](https://docs.babyclaw.org/features/telegram#linking-chats) with aliases, you can ask the agent to deliver scheduled messages to a different chat: > "Every morning at 8am, send a good morning message to family-chat" The schedule runs in the context of the chat where you created it, but the output gets delivered to the target chat. ## Managing schedules You can manage schedules through conversation or slash commands: **In conversation:** > "What schedules do I have?" > "Cancel the morning email check" **Telegram command:** ```text /schedules ``` This lists all active schedules for the current chat. ## How scheduled runs work When a schedule fires: 1. The agent starts a turn with the scheduled prompt 2. It has access to all its normal tools (workspace, shell, web search, etc.) 3. If the run produces output, it's sent to the target chat 4. The run is recorded in the database with a status (succeeded or failed) 5. If a run fails, it retries up to 3 times with delays between attempts For recurring schedules, if the previous run is still going when the next one is due, the new run is skipped to prevent overlap. Old schedule runs are cleaned up after 30 days. # Heartbeat The heartbeat system lets BabyClaw run periodic agent check-ins on a schedule. Instead of only responding when you message it, the agent can proactively check things and alert you if something needs attention. Heartbeat is **disabled by default**. Enable it when you want the agent to do background work. ## Enabling heartbeat ```json { "heartbeat": { "enabled": true, "intervalMinutes": 30 } } ``` This runs a heartbeat every 30 minutes. The minimum interval is 5 minutes. ## How it works On each heartbeat: 1. The agent reads `HEARTBEAT.md` from the workspace (if it exists) 2. It follows the instructions in that file 3. It decides whether anything needs attention 4. If something does, it sends you a message. If not, it stays quiet. The key idea: **silent when nothing's happening, vocal when something matters.** ## Writing a HEARTBEAT.md The `HEARTBEAT.md` file in your workspace tells the agent what to check during heartbeats. Keep it short -- each heartbeat costs tokens. Example: ```markdown # Heartbeat Checklist - Check if there are any unread emails from $BOSS - Look at my calendar for the next 4 hours -- anything coming up? - If the weather is going to be bad today, let me know ``` The agent will work through these items and only message you if something stands out. If everything looks fine, it stays quiet. You can also let the agent edit this file over time -- it might add items based on your conversations. ## Active hours If you don't want heartbeats at 3am, set an active window: ```json { "heartbeat": { "enabled": true, "intervalMinutes": 30, "activeHours": { "start": "08:00", "end": "22:00" } } } ``` Times are in 24-hour format and use the `scheduler.timezone` from your config. Outside this window, heartbeats are skipped. ## Custom prompt You can change the prompt sent to the agent on each heartbeat: ```json { "heartbeat": { "prompt": "Check HEARTBEAT.md. If nothing needs attention, stay quiet." } } ``` The default prompt is: > "Read HEARTBEAT.md if it exists. Follow its instructions. Do not infer or repeat old tasks from prior chats. If nothing needs attention, say so." ## Heartbeat vs scheduling Both heartbeat and [scheduling](https://docs.babyclaw.org/features/scheduling) can trigger the agent periodically, but they work differently: | | Heartbeat | Scheduling | | ----------------- | --------------------------------- | ---------------------------------------- | | **Configured in** | Config file | Created by the agent during conversation | | **Good for** | Batching multiple periodic checks | Precise timing, one-off reminders | | **Context** | Runs in the main session | Runs in its own context | | **Timing** | Approximate (every N minutes) | Exact (cron expressions) | | **Output** | Messages you only when needed | Always delivers output | A common pattern: use heartbeat for background monitoring (email, calendar, weather) and scheduling for specific tasks ("remind me in 20 minutes", "every Monday at 9am"). ## Checking heartbeat status In Telegram, use the `/heartbeat` command to see if heartbeat is enabled and when the next run is scheduled. # Memory The agent starts each session fresh -- it doesn't inherently remember previous conversations. Memory in BabyClaw is file-based: the agent reads and writes files in its workspace to maintain continuity across sessions. There are two kinds of memory: **working memory** (temporary, per-session) and **long-term memory** (extracted from conversations, persisted to files). ## Working memory Working memory is a per-session scratchpad. The agent uses the `update_working_memory` tool to jot down things it needs to track during a conversation -- file paths, intermediate results, IDs, or anything else that helps it stay on track. Working memory is included in the agent's context on each turn within the session. It goes away when the session ends. ## Long-term memory After conversations in the main session, BabyClaw automatically extracts notable information and saves it to daily memory files. ### How extraction works 1. After the agent finishes a turn in the main session, memory extraction is queued 2. After a 5-minute debounce (to batch multiple messages), the extractor runs 3. It reviews the conversation and pulls out things worth remembering: decisions, preferences, context, lessons learned 4. It writes these to `memory/YYYY-MM-DD.md` in the workspace 5. Extraction avoids duplicating things already captured in existing memory files The extraction is AI-powered -- the agent uses the same chat model to decide what's worth keeping. It skips transient chat, obvious implementation details, and anything already recorded. ### What gets extracted The extractor focuses on durable information: - Decisions you made ("we're using PostgreSQL for this project") - Preferences ("I prefer dark mode", "don't use semicolons") - Context about your life or work ("starting a new job in March") - Lessons learned ("the deploy script needs `--force` on staging") - Things you explicitly asked the agent to remember It skips: - Casual back-and-forth - Step-by-step implementation details - Things already in existing memory files ### Where memories live ```text workspace/ └── memory/ ├── 2026-02-18.md ├── 2026-02-19.md └── 2026-02-20.md ``` Each daily file contains timestamped entries from that day's conversations. ### MEMORY.md The workspace also has a top-level `MEMORY.md` file for curated long-term memory. This is different from the daily files -- it's meant to be a distilled summary that the agent maintains over time, pulling the most important things from daily notes and organizing them. The agent reads `MEMORY.md` at the start of main sessions (it's part of the instructions in `AGENTS.md`). Daily files are also read for recent context (typically today and yesterday). ## Memory is only for the main session Memory extraction only runs after main session conversations. Other sessions (linked group chats, scheduled task runs) don't trigger extraction. This is a deliberate choice -- the main session is where personal context lives, and keeping it isolated prevents leaking information to other contexts. ## Session startup At the start of each session, the agent reads: 1. `SOUL.md` -- who it is 2. `USER.md` -- who you are 3. Recent daily memory files (today + yesterday) 4. `MEMORY.md` (main session only) This gives it enough context to pick up where things left off, even though the actual conversation history is limited to the `session.historyLimit` most recent messages. # Skills Skills are extensions that teach the agent how to use specific tools or services. Each skill is a directory with a `SKILL.md` file that contains instructions and metadata. The agent reads eligible skills at the start of a session and uses them when relevant. BabyClaw uses the same skill format as OpenClaw, so it's compatible with the [ClawHub](https://clawhub.ai){rel=""nofollow""} skill registry. ## Where skills live Skills are stored in the `skills/` directory inside the workspace: ```text workspace/ └── skills/ ├── web-scraper/ │ └── SKILL.md └── image-gen/ └── SKILL.md ``` The agent discovers all skill directories automatically on session start. ## Skill format A `SKILL.md` file has YAML frontmatter followed by instructions: ```markdown --- name: web-scraper description: Scrape web pages and extract structured data metadata: { "openclaw": { "requires": { "bins": ["curl"] }, "primaryEnv": "SCRAPER_API_KEY" } } --- ## How to use Use the shell tool to run `curl` with the following patterns... ``` The frontmatter tells BabyClaw about the skill. The body tells the agent how to use it. ### Frontmatter fields | Field | Required | Description | | ------------- | -------- | ------------------------------------------------------------ | | `name` | Yes | Skill identifier | | `description` | Yes | Short description of what the skill does | | `metadata` | No | JSON object with eligibility requirements and other metadata | ## Bundled skills BabyClaw ships with a set of bundled skills that are available out of the box. Bundled skills are **disabled by default** and must be explicitly enabled from the CLI. List available bundled skills: ```bash babyclaw skill bundled ``` Enable a bundled skill: ```bash babyclaw skill enable --slug ``` If you want to skip automatic dependency setup, pass `--skip-setup`: ```bash babyclaw skill enable --slug --skip-setup ``` Disable a bundled skill: ```bash babyclaw skill disable --slug ``` When you enable a bundled skill, its dependencies are automatically set up. The skill files stay in the package and are read directly at runtime -- they are not copied into your workspace. This means bundled skills are automatically updated when you update BabyClaw. The same eligibility checks (required binaries, environment variables, etc.) apply to bundled skills. ## Installing skills from ClawHub [ClawHub](https://clawhub.ai){rel=""nofollow""} is a public registry of skills. You can install skills from it using the CLI: ```bash babyclaw skill install --slug ``` Or let the agent install skills during a conversation -- it has a `clawhub_install` tool that does the same thing. If the agent notices it needs a skill it doesn't have, it can look it up on ClawHub and install it. After installation, a post-install setup step runs where the agent can help configure the skill (e.g., setting API keys). ## Configuring skills You can enable, disable, and configure skills in the config file: ```json { "skills": { "entries": { "web-scraper": { "enabled": true }, "image-gen": { "enabled": true, "apiKey": "your-api-key", "env": { "IMAGE_MODEL": "dall-e-3" } }, "unused-skill": { "enabled": false } } } } ``` | Field | Type | Default | Description | | --------- | --------- | ------- | ----------------------------------------------------- | | `enabled` | `boolean` | `true` | Whether the skill is loaded | | `apiKey` | `string` | -- | API key (mapped to the skill's `primaryEnv`) | | `env` | `object` | -- | Environment variables injected when the skill is used | Environment variables from `env` are injected only during agent runs, not globally. They won't override variables already set in your environment. ## Eligibility Skills can declare requirements that must be met for them to be loaded. This is done through the `metadata.openclaw.requires` field: | Requirement | What it checks | | ----------- | ----------------------------------------------------------------- | | `bins` | All listed binaries must exist on your PATH | | `anyBins` | At least one of the listed binaries must exist | | `env` | Listed environment variables must be set (or provided via config) | | `config` | Listed config paths must be truthy | If a skill has an `always: true` flag in its metadata, it's loaded regardless of requirements. Skills can also be restricted to specific operating systems with the `os` field (e.g., `["darwin", "linux"]`). ## Writing your own skills Create a directory in `workspace/skills/` with a `SKILL.md` file: ```text workspace/skills/my-skill/ └── SKILL.md ``` Write the frontmatter and instructions. The instructions should tell the agent: - What the skill does - When to use it - How to invoke the underlying tools or commands - Any quirks or gotchas The agent reads these instructions and follows them when the skill is relevant to a conversation. Keep instructions concise -- they're included in the agent's context and cost tokens on every session. # CLI Commands BabyClaw includes a CLI for configuration, service management, model setup, and diagnostics. The CLI has interactive prompts where needed -- if you omit a required option, it will ask you for it. ## Setup ### `babyclaw setup` Interactive first-time setup wizard. Walks you through everything needed to get BabyClaw running: 1. **Telegram bot token** -- connect to your bot from @BotFather (can be skipped) 2. **AI providers** -- configure one or more providers (Anthropic, OpenAI, Google, etc.) with API keys 3. **Model selection** -- pick which models to use for chat 4. **Timezone** -- set your scheduler timezone 5. **Tool settings** -- choose shell access mode, configure web search 6. **Service install** -- optionally install and start BabyClaw as a system service If a config file already exists, you can choose to update it or start fresh. ## Config ### `babyclaw config init` Creates a new config file with default values and placeholder tokens. Run this first when setting up BabyClaw. ### `babyclaw config validate` Validates your current config file against the schema. Reports any errors without starting the gateway. ### `babyclaw config edit` Opens the config file in your default editor (`$EDITOR`). ## Model management ### `babyclaw model` Shows the current model configuration -- which providers are set up, what models are assigned to chat/vision. ### `babyclaw model configure` Interactive wizard that walks you through setting up an AI provider. It asks which provider you want, prompts for your API key, and updates the config. ### `babyclaw model alias` Lists all configured model aliases. ### `babyclaw model alias set --name --model ` Creates or updates a model alias. For example: ```bash babyclaw model alias set --name sonnet --model anthropic:claude-sonnet-4-20250514 ``` If you omit `--name` or `--model`, the CLI will prompt you interactively. ### `babyclaw model alias remove --name ` Removes a model alias. If you omit `--name`, the CLI will prompt you. ## Service management ### `babyclaw service install` Installs BabyClaw as a system service so it starts automatically. Uses **launchd** on macOS and **systemd** on Linux. ### `babyclaw service uninstall` Removes the system service. ### `babyclaw service start` Starts the BabyClaw service. ### `babyclaw service stop` Stops the running service. ### `babyclaw service restart` Restarts the service. ### `babyclaw service status` Shows whether the service is running. See [Running as a Service](https://docs.babyclaw.org/cli/service-management) for more details. ## Gateway ### `babyclaw gateway status` Queries the running gateway for its current status (uptime, active turns, etc.) via the admin socket. ### `babyclaw gateway reload` Sends a health check / reload signal to the running gateway. ## Skills ### `babyclaw skill search --query ` Searches [ClawHub](https://clawhub.ai){rel=""nofollow""} for available skills. If you omit `--query`, the CLI will prompt you. ```bash babyclaw skill search --query notion ``` Additional options: `--json` to output raw JSON. ### `babyclaw skill install --slug ` Installs a skill from [ClawHub](https://clawhub.ai){rel=""nofollow""} into the workspace. The skill is downloaded and placed in `workspace/skills//`. If you omit `--slug`, the CLI will prompt you. Additional options: `--version`, `--force`, `--skip-setup`. ## Diagnostics ### `babyclaw doctor` Runs a set of diagnostic checks and reports any issues. Useful for debugging when something isn't working: - Config file exists and validates - Database is accessible - Telegram bot token is valid - AI provider keys are configured - Workspace directory exists # Running as a Service If you want BabyClaw running in the background and starting automatically when your machine boots, install it as a system service. ## Why run as a service Running BabyClaw as a service means: - It starts automatically when your machine boots - It restarts if it crashes - You don't need to keep a terminal open - Heartbeats and schedules keep running even when you're not looking If you just want to try BabyClaw out, running it directly with `node packages/gateway/dist/main.js` is fine. Set up the service when you're ready to use it day-to-day. ## Installing the service ```bash babyclaw service install ``` On **macOS**, this creates a launchd plist and loads it. The gateway will start on login. On **Linux**, this creates a systemd user service. The gateway will start when you log in. ### Linux: enabling lingering By default, systemd stops user services when you log out. For an always-on assistant (especially on a server), you need to enable lingering: ```bash sudo loginctl enable-linger $USER ``` This keeps your user services running even when you're not logged in. The install command tries to do this for you, but it may need sudo. ## Managing the service ```bash babyclaw service start # start the service babyclaw service stop # stop the service babyclaw service restart # restart the service babyclaw service status # check if it's running ``` ## Uninstalling the service ```bash babyclaw service uninstall ``` This removes the launchd plist (macOS) or systemd unit file (Linux) and stops the service. ## Running without a service If you prefer not to use a system service, you can run the gateway directly: ```bash node packages/gateway/dist/main.js ``` Or use a process manager like `pm2`: ```bash pm2 start packages/gateway/dist/main.js --name babyclaw ``` The gateway runs in the foreground and logs to stdout. Press `Ctrl+C` to stop it. # Sessions A session is a conversation context. Each session has its own message history, working memory, and title. The agent maintains separate sessions for different chats, so conversations don't mix. ## Session identity Each session is identified by a combination of: - **Platform** -- always `telegram` for now - **Chat ID** -- the Telegram chat (DM, group, etc.) - **Thread ID** -- the topic/thread within a forum-style group (if applicable) This means each Telegram chat gets its own session automatically. In forum groups with topics, each topic gets its own session. ## Main session The first chat you message the bot from becomes the **main session**. It's special in a few ways: - Messaging tools (`send_message`, `list_known_chats`) are only available here - Long-term memory extraction only runs after main session conversations - The agent reads `MEMORY.md` at the start of main sessions This keeps personal context isolated from other chats. ## Reply chain mode BabyClaw supports two modes for session scoping: ### Default mode Sessions are scoped by chat (and thread, if in a forum group). All messages in a chat share the same session. ### Reply-chain mode When `session.replyChainMode` is `"reply-chain"`, replying to a specific bot message continues that session's context. This is useful in groups where you might have multiple unrelated conversations. ```json { "session": { "replyChainMode": "reply-chain" } } ``` ## Message history Two settings control how much history the agent works with: ### `session.historyLimit` How many recent messages are included in the agent's context for each turn. Default is `40`. Lower values mean less context but fewer tokens per turn. ### `session.maxMessagesPerSession` The maximum number of messages stored in a session before old ones are pruned. Default is `120`. This is the total stored -- the agent only sees the most recent `historyLimit` messages. ## Title generation BabyClaw auto-generates a title for new sessions based on the first message. This helps identify sessions in logs and status output. You can customize the model and prompt used for title generation: ```json { "session": { "titleGeneration": { "model": "anthropic:claude-haiku-3", "prompt": "Generate a short title for this conversation" } } } ``` Both fields are optional. If not set, the chat model and a default prompt are used. ## Session configuration | Field | Default | Description | | -------------------------------- | ------------ | ---------------------------------- | | `session.maxMessagesPerSession` | `120` | Max messages stored per session | | `session.historyLimit` | `40` | Messages included in agent context | | `session.replyChainMode` | `"default"` | `"default"` or `"reply-chain"` | | `session.titleGeneration.model` | (chat model) | Model for title generation | | `session.titleGeneration.prompt` | (default) | Prompt for title generation | # Troubleshooting ## Run diagnostics first When something isn't working, start here: ```bash babyclaw doctor ``` This checks your config, database, Telegram connection, and AI provider setup. It'll tell you what's wrong. ## Common issues ### "Config validation failed" The gateway won't start if the config file has errors. Common causes: - **Unknown keys** -- BabyClaw uses strict validation. Typos in key names will be rejected. - **Wrong types** -- e.g., a string where a number is expected. - **Missing required fields** -- `version`, `ai.providers`, and `ai.models.chat` are all required. Run `babyclaw config validate` to see the exact errors. ### Bot not responding on Telegram Check these in order: 1. **Is the gateway running?** Run `babyclaw service status` or `babyclaw gateway status`. 2. **Is the bot token correct?** Make sure `channels.telegram.botToken` matches what BotFather gave you. 3. **Did you message the right bot?** Search for your bot's username in Telegram. 4. **Check the logs.** If the gateway is running but the bot isn't responding, look at the log output for errors. The default log output is stdout. ### "At least one provider must be configured" You need at least one entry in `ai.providers` with a valid API key. See [AI Providers](https://docs.babyclaw.org/configuration/ai-providers). ### Model errors / API key issues If the agent starts but fails on the first message: - Check that the model string matches the format `provider:modelId` (e.g., `anthropic:claude-sonnet-4-20250514`) - Check that the provider name in the model string matches a key in `ai.providers` - Verify your API key is valid and has credit/quota ### Database errors BabyClaw uses SQLite with Drizzle. The database file is created automatically at `/.data/babyclaw.db`. If you see database errors: - Make sure the directory exists and is writable - If the database is corrupted, you can delete the `.db` file and let BabyClaw recreate it (you'll lose session history and schedule data) ### Schedules not firing - Check that the gateway is running continuously (schedules only fire while the gateway is up) - Verify the timezone in `scheduler.timezone` is correct - Check `babyclaw gateway status` to see if the scheduler is active ### Heartbeat not running - Make sure `heartbeat.enabled` is `true` in the config - Check `activeHours` -- heartbeats are skipped outside the active window - The minimum interval is 5 minutes - Use `/heartbeat` in Telegram to check the status ## Debug logging For more detail on what's happening, set the log level to debug: ```json { "logging": { "level": "debug" } } ``` This produces a lot of output but can help track down issues. Set it back to `"info"` when you're done. ## Redacting sensitive data from logs If you're sharing logs for debugging, you can redact specific fields: ```json { "logging": { "redact": ["apiKey", "botToken"] } } ``` ## Getting help BabyClaw is a small project. If you're stuck, check the [GitHub issues](https://github.com/babyclaw/babyclaw/issues){rel=""nofollow""} or open a new one with: - Your config (with API keys removed) - The error message or log output - What you expected to happen