Claude Gateway
A self-hosted multi-agent gateway for Claude Code with custom personas, memory, and plugin-based channel support
Ask AI about Claude Gateway
Powered by Claude Β· Grounded in docs
I know everything about Claude Gateway. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Claude Gateway
A self-hosted multi-agent gateway for Claude Code. Connect Claude agents to Telegram, HTTP APIs, and scheduled tasks β each agent runs in an isolated session with its own personality, memory, and tools.
Features
- Multi-agent β run multiple bots from a single gateway, each with isolated sessions
- Multi-channel MCP β modular tool system per channel (Telegram, Discord, Cron, Skills, extensible to Slack/WhatsApp)
- Agent skills β extensible skill system via SKILL.md files; agents can create, delete, and install skills from URLs at runtime with hot-reload
- Agent identity β define personality, tone, and rules via workspace markdown files
- Live status messages β real-time status updates showing tool usage, thinking, and progress
- Typing indicators β continuous typing animation while the agent is working (Telegram and Discord)
- Streaming API β SSE (Server-Sent Events) endpoint for real-time response streaming
- Auto-forward β agent text output automatically forwarded to Telegram even without explicit reply tool calls
- Heartbeat / scheduled tasks β cron-based proactive messages and recurring tasks via HEARTBEAT.md + REST API; agent jobs deliver output to Telegram, Discord, or both
- Long-term memory β persistent memory system across sessions
- Config auto-migration β automatic schema migration when config format changes
- Access control β allowlist, open, or pairing-based Telegram access policies
- HTTP API β REST API with key-based auth for external integrations
- Session persistence β conversation history saved and restored across restarts
Requirements
- Node.js 18+
- Claude Code CLI v2.1.0+ installed and authenticated β
channels modeis required (claude --version) - Bun β runs the MCP server subprocess (
mcp/server.ts) - A bot token per agent β Telegram (from @BotFather) or Discord (from Discord Developer Portal)
Quick Start
1. Install
git clone <repo>
cd claude-gateway
npm install
npm run build
2. Install MCP server dependencies
The gateway MCP server uses Bun with its own package.json. Install once:
make mcp-install # runs: cd mcp && bun install
This installs grammy (Telegram Bot API) and @modelcontextprotocol/sdk into mcp/node_modules/.
3. Create an agent
The interactive wizard handles everything β workspace files, config, bot token, and pairing:
make create-agent
Steps:
- Choose an agent name
- Describe the agent β Claude generates workspace files
- Review and accept generated files
- Choose a channel: Telegram or Discord
- Paste the bot token β wizard verifies it automatically
- Send any message to the bot to complete pairing
- Agent sends a welcome message
4. Start the gateway
npm start
Config is auto-loaded from ~/.claude-gateway/config.json. Bot tokens are auto-loaded from ~/.claude-gateway/agents/<id>/.env.
Workspace Files
Each agent has a workspace directory with markdown files that define its behaviour:
| File | Required | Purpose |
|---|---|---|
AGENTS.md | Yes | Core identity, rules, capabilities |
IDENTITY.md | No | Agent name, emoji, avatar, personality identity |
SOUL.md | No | Tone, personality, speaking style |
USER.md | No | User profile and preferences |
MEMORY.md | No | Long-term memory (auto-appended by the agent) |
HEARTBEAT.md | No | Scheduled/proactive tasks |
skills/ | No | Directory of SKILL.md files β agent-specific skills |
On startup (and on any file change), all files are assembled into CLAUDE.md which the Claude subprocess reads as its system prompt. Do not edit CLAUDE.md directly.
Configuration Reference
Config lives at ~/.claude-gateway/config.json (or set GATEWAY_CONFIG env var / --config flag).
{
"configVersion": "1.0.0",
"gateway": {
"logDir": "~/.claude-gateway/logs",
"timezone": "Asia/Bangkok",
"api": {
"keys": [
{
"key": "${MY_API_KEY}",
"description": "Internal app",
"agents": ["alfred"]
},
{
"key": "${ADMIN_API_KEY}",
"description": "Admin",
"agents": "*"
}
]
}
},
"agents": [
{
"id": "alfred",
"description": "Personal assistant",
"workspace": "~/.claude-gateway/agents/alfred/workspace",
"env": "",
"session": {
"idleTimeoutMinutes": 30,
"maxConcurrent": 20
},
"telegram": {
"botToken": "${ALFRED_BOT_TOKEN}"
},
"claude": {
"model": "claude-sonnet-4-6",
"dangerouslySkipPermissions": true,
"extraFlags": []
},
"heartbeat": {
"rateLimitMinutes": 30
}
}
]
}
session
| Field | Default | Description |
|---|---|---|
idleTimeoutMinutes | 30 | Kill idle session subprocess after N minutes of inactivity |
maxConcurrent | 20 | Max simultaneous active sessions per agent; oldest idle is evicted when exceeded |
dmPolicy
Access policy is configured per-channel in the agent's workspace state file, not in config.json:
| File | Path |
|---|---|
| Telegram | ~/.claude-gateway/agents/<id>/workspace/.telegram-state/access.json |
| Discord | ~/.claude-gateway/agents/<id>/workspace/.discord-state/access.json |
| Value | Behaviour |
|---|---|
allowlist | Only user IDs in allowFrom can DM the agent (default) |
open | Anyone can DM the agent |
pairing | New users DM the bot to receive a pairing code; approve with npm run pair |
dangerouslySkipPermissions
Set to true for all agents running headless (no interactive terminal). Without it the agent cannot use MCP tools like sending Telegram replies.
gateway.api.keys
Each key has a key string (supports ${ENV_VAR} interpolation), an optional description, and an agents field β either an array of agent IDs or "*" for full access. Keys support both Authorization: Bearer and X-Api-Key headers.
Bot tokens
Tokens are stored per-agent at ~/.claude-gateway/agents/<id>/.env and auto-loaded at startup. Use ${AGENT_BOT_TOKEN} syntax in config to reference them, or set them as shell environment variables.
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Claude Gateway β
β β
Telegram Bot A βββΊ TelegramReceiver(A) βββΊ AgentRunner(A) ββ¬ββΊ Session(chat:111) βββΊ Claude + MCP
βββΊ Session(chat:222) βββΊ Claude + MCP
Telegram Bot B βββΊ TelegramReceiver(B) βββΊ AgentRunner(B) βββ΄ββΊ Session(chat:333) βββΊ Claude + MCP
β
HTTP Client βββΊ POST /api/v1/.../messages βββββββββββββββββ΄ββΊ Session(api:uuid) βββΊ Claude
(sync JSON or SSE stream)
β β
β GatewayRouter (/health, /status, /ui, /api) β
β CronScheduler (HEARTBEAT.md + REST API) β
β TypingManager (live status indicators) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββ
β MCP Server (per session) β
β mcp/server.ts β
β β
β telegram_reply β
β telegram_react β
β telegram_edit_message β
β telegram_download_attachment β
β cron_list / cron_create / ... β
β skill_create / skill_delete / ... β
βββββββββββββββββββββββββββββββββββββ
Each agent runs a dedicated TelegramReceiver (single poller per bot token) and a session pool of isolated Claude subprocesses β one per chat or API session. Each session gets its own MCP server (mcp/server.ts) exposing channel-specific tools (Telegram reply, react, cron management, skill management). Sessions persist history via SessionStore, so Claude remembers the conversation even after idle restart.
Session Pool
Each agent maintains a session pool β a separate Claude subprocess per chat ID (Telegram) or session UUID (API). Sessions are fully isolated: Claude sees only its own conversation history with no cross-session leakage.
TelegramReceiver (1 per agent, spawned by gateway)
- single long-poll connection per bot token
- handles access control (allowlist / pairing)
- runs as: bun mcp/tools/telegram/receiver-server.ts (RECEIVER_MODE)
- POSTs incoming messages to AgentRunner callback
AgentRunner (session pool manager)
βββ SessionProcess(chat:111) βββΊ Claude subprocess + MCP server (SEND_ONLY)
βββ SessionProcess(chat:222) βββΊ Claude subprocess + MCP server (SEND_ONLY)
βββ SessionProcess(api:uuid) βββΊ Claude subprocess (no MCP β API-only)
MCP Tool System
The MCP server (mcp/server.ts) uses a modular multi-channel architecture. Each channel is a separate module implementing ChannelModule or ToolModule interfaces:
| Module | Interface | Tools | Purpose |
|---|---|---|---|
telegram | ChannelModule | telegram_reply, telegram_react, telegram_edit_message, telegram_download_attachment | Send messages, reactions, edit messages in Telegram |
discord | ChannelModule | discord_reply, discord_react, discord_edit_message | Send messages, reactions, edit messages in Discord |
cron | ToolModule | cron_list, cron_create, cron_delete, cron_run, cron_get_runs | Manage scheduled jobs via gateway REST API |
skills | ToolModule | skill_create, skill_delete, skill_install | Create, delete, and install agent skills at runtime |
Tools are prefixed by channel name to avoid collisions. Each module controls its own visibility and lifecycle.
Adding a new channel (e.g. Slack) means implementing ChannelModule interface in mcp/tools/slack/module.ts and registering it in server.ts.
Process Modes
| Mode | Process | Behaviour |
|---|---|---|
TELEGRAM_RECEIVER_MODE | receiver-server.ts | Polls Telegram, handles commands, POSTs to callback β no MCP |
TELEGRAM_SEND_ONLY | server.ts | Exposes MCP tools (telegram_*, cron_*) β no polling |
Session Persistence
History is persisted to SessionStore (.jsonl files) after each message. When a session is spawned after an idle restart, history is injected into the initial prompt so Claude resumes the conversation seamlessly.
Live Status Messages
While an agent is working, the gateway sends real-time status updates to Telegram showing what the agent is doing:
βοΈ : π§ Analyzing the codebase structure...
βοΈ : π Reading: src/agent/runner.ts
βοΈ : π Searching for: "sendMessage" in src/
π : βοΈ Editing: mcp/tools/telegram/typing.ts
(elapsed: 2m 30s)
- Tool tracking β each tool call is displayed with a descriptive label (e.g.
π Reading: config.ts,β‘ Running: npm test) - History β previous steps shown with βοΈ, current step with π
- Thinking β agent's reasoning shown with π§
- Elapsed time β total time since the agent started working
- Auto-cleanup β status message is deleted when the agent finishes
Status updates are sent every 5-10 seconds (first update at 5s, then every 10s).
HTTP API
When gateway.api.keys is configured, the gateway exposes a REST API for external clients.
Pass API key via X-Api-Key: <key> or Authorization: Bearer <key> header.
Endpoints:
| Method | Path | Description |
|---|---|---|
GET | /api/v1/agents | List agents accessible by the provided key |
POST | /api/v1/agents/:agentId/messages | Send a message β sync JSON or SSE stream |
GET | /api/v1/crons | List cron jobs accessible by key |
GET | /api/v1/crons/status | Scheduler status |
POST | /api/v1/crons | Create a scheduled job |
GET | /api/v1/crons/:id | Get a single job |
PUT | /api/v1/crons/:id | Update a job |
DELETE | /api/v1/crons/:id | Delete a job |
POST | /api/v1/crons/:id/run | Trigger a job manually |
GET | /api/v1/crons/:id/runs | Get run history |
See API.md for full reference with request/response schemas and curl examples.
File Structure
Project
claude-gateway/
βββ Makefile β make start / create-agent / update-agent / pair / mcp-install
βββ config.template.json β config template (source of truth for migration)
β
βββ src/ β Gateway core (TypeScript, compiled to dist/)
β βββ index.ts β entrypoint β loads config, starts agents
β βββ types.ts β shared TypeScript types
β βββ logger.ts β structured logging with per-agent files
β β
β βββ agent/ β Agent management
β β βββ runner.ts β session pool manager (spawn/evict sessions)
β β βββ workspace-loader.ts β assembles CLAUDE.md from workspace files + skills
β β βββ context-isolation.ts β context guard for session isolation
β β
β βββ session/ β Session lifecycle
β β βββ process.ts β single Claude subprocess per session
β β βββ store.ts β persist/load conversation history (.jsonl)
β β βββ compactor.ts β summarise + compact old history
β β
β βββ telegram/ β Telegram integration
β β βββ receiver.ts β spawns TelegramReceiver subprocess per agent
β β βββ markdown.ts β markdown/HTML utilities
β β
β βββ api/ β HTTP API
β β βββ gateway-router.ts β HTTP server (/health, /status, /ui, /api)
β β βββ router.ts β REST API router (sync + SSE streaming)
β β βββ auth.ts β API key auth middleware (timing-safe)
β β βββ cron-router.ts β Cron API router (auth + agent-scoped access)
β β
β βββ config/ β Configuration
β β βββ loader.ts β load + validate config.json
β β βββ migrator.ts β auto-migration for config schema changes
β β βββ watcher.ts β hot-reload config on file change
β β
β βββ cron/ β Cron scheduling
β β βββ manager.ts β persistent cron job manager (REST + agentTurn)
β β βββ scheduler.ts β heartbeat task scheduler
β β
β βββ heartbeat/ β Proactive tasks
β β βββ parser.ts β parse HEARTBEAT.md YAML
β β βββ history.ts β track scheduled task execution
β β
β βββ skills/ β Agent skills system
β β βββ index.ts β re-exports (parser, loader, invoker, watcher)
β β βββ parser.ts β parse SKILL.md frontmatter + body
β β βββ loader.ts β load skills from directories, build registry
β β βββ invoker.ts β detect /skill-name in messages, inject context
β β βββ watcher.ts β hot-reload skills on file changes (chokidar)
β β
β βββ memory/ β Long-term memory
β β βββ manager.ts β memory persistence
β β
β βββ webhook/ β Webhooks
β β βββ manager.ts β webhook event dispatch
β β
β βββ ui/ β Dashboard
β βββ web-ui.ts β live HTML dashboard
β
βββ scripts/
β βββ create-agent.ts β interactive agent creation wizard (with channel selection)
β βββ create-agent-prompts.ts β agent workspace generation prompts
β βββ update-agent.ts β update agent.md or manage channels (add/remove)
β βββ interactive-select.ts β interactive selection UI helper
β βββ pair.ts β approve channel pairing (Telegram / Discord)
β βββ setup-claude-settings.js β enables channelsEnabled in Claude Code
β
βββ mcp/ β MCP server (runs in Bun, separate node_modules)
βββ package.json β dependencies: grammy, @modelcontextprotocol/sdk
βββ server.ts β MCP entry point β registers all tool modules
βββ types.ts β ChannelModule / ToolModule interfaces
βββ channel-manager.ts β module lifecycle (init, start, stop, restart)
βββ router.ts β route resolution + channel context rendering
β
βββ tools/
βββ telegram/ β Telegram channel module
β βββ module.ts β ChannelModule: telegram_reply, react, edit, download
β βββ receiver-server.ts β standalone receiver (polling mode, no MCP)
β βββ pure.ts β markdown β Telegram HTML conversion
β βββ typing.ts β typing indicator state
β βββ skills/
β βββ access/SKILL.md β /telegram:access skill
β βββ configure/SKILL.md β /telegram:configure skill
β
βββ cron/ β Cron tool module
β βββ module.ts β ToolModule: cron_list, create, delete, run, get_runs
β βββ client.ts β HTTP client for gateway cron REST API
β βββ skills/
β βββ cron/SKILL.md β /cron skill
β
βββ skills/ β Skills tool module
βββ module.ts β ToolModule: skill_create, skill_delete, skill_install
βββ handlers.ts β skill CRUD + URL install handlers
Runtime data (~/.claude-gateway/)
~/.claude-gateway/
βββ config.json β gateway config
βββ logs/
β βββ alfred.log
β βββ warrior.log
βββ shared-skills/ β shared skills (synced to ~/.claude/skills/ on boot and on change)
β βββ <skill-name>/
β βββ SKILL.md β skill definition (same format as agent skills)
βββ agents/
βββ alfred/
βββ .env β bot token (auto-created by wizard)
βββ sessions/
β βββ <chat_id>.jsonl β conversation history (SessionStore)
βββ workspace/
βββ CLAUDE.md β auto-generated from workspace files, do not edit
βββ AGENTS.md β agent identity, rules, capabilities
βββ IDENTITY.md β name, emoji, avatar
βββ SOUL.md β tone, personality, speaking style
βββ USER.md β user profile and preferences
βββ MEMORY.md β long-term memory (auto-appended)
βββ HEARTBEAT.md β scheduled/proactive tasks
βββ skills/ β agent-specific skills (hot-reloaded)
β βββ <skill-name>/
β βββ SKILL.md β skill definition with frontmatter
βββ .sessions/ β per-session MCP config
β βββ <session_id>/
β βββ mcp-config.json β auto-generated MCP config for this session
βββ .telegram-state/
β βββ access.json β Telegram allowlist and pairing state
βββ .discord-state/
βββ access.json β Discord allowlist and pairing state
Heartbeat / Scheduled Tasks
Define proactive tasks in HEARTBEAT.md:
tasks:
- name: morning-brief
cron: "0 8 * * *"
prompt: "Give a brief morning summary."
- name: check-in
interval: 6h
prompt: "Check if there are any reminders to send."
cronβ standard 5-field cron expressionintervalβ shorthand:30m,1h,6h,1d,1w- If the agent replies with
HEARTBEAT_OK(case-insensitive), no message is sent to Telegram rateLimitMinutesin config suppresses tasks if a proactive message was already sent recently (default: 30 min)
Agent Skills
Skills are reusable capabilities defined as SKILL.md files with YAML frontmatter. They are injected into the agent's system prompt and can be invoked via /skill-name commands.
Skill locations
| Location | Scope | Description |
|---|---|---|
workspace/skills/<name>/SKILL.md | Per-agent | Agent-specific skills |
~/.claude-gateway/shared-skills/<name>/SKILL.md | All agents | Shared skills β synced to ~/.claude/skills/ at boot and on change |
mcp/tools/<channel>/skills/<name>/SKILL.md | All agents | Built-in channel skills (e.g. /telegram:access) |
SKILL.md format
---
name: my-skill
description: What this skill does
user_invocable: true # false = system-only, not shown to user
argument_description: "[args]" # optional, shown in /skill-name [args]
---
Skill instructions go here. Claude follows these instructions
when the user invokes /my-skill.
Runtime skill management
Agents can manage skills at runtime via MCP tools:
| Tool | Description |
|---|---|
skill_create | Create a new skill in the workspace |
skill_delete | Delete an existing skill |
skill_install | Install a skill from a GitHub URL or raw URL |
Skills are hot-reloaded β changes to skill files are detected automatically and the skill registry is updated without restarting the session.
Shared skills sync
Skills placed in ~/.claude-gateway/shared-skills/ are automatically synced to ~/.claude/skills/ β the user-level directory that Claude Code scans for every session:
- At boot β gateway copies all shared skills before spawning any agent
- On change β any add, edit, or delete under
shared-skills/triggers a re-sync - Cleanup β each synced skill is tagged with a
.sharedmarker file; if a skill is removed fromshared-skills/, the marker is used to delete the stale copy from~/.claude/skills/automatically (user-installed skills without the marker are never touched)
This means adding a skill to shared-skills/ makes it available to all agents without per-agent setup or a gateway restart.
Config Auto-Migration
When the config schema changes (new fields added in config.template.json), the gateway automatically detects and migrates your config.json:
- Preserves all existing values
- Adds missing fields with defaults from the template
- Prompts for confirmation before writing (use
--auto-migrateto skip) - Tracks schema version for future migrations
Pairing New Users
- Set
dmPolicytopairinginaccess.json:{ "dmPolicy": "pairing" } - Ask the user to DM the bot β they receive a 6-character pairing code
- Approve it:
npm run pair -- --agent=alfred --code=abc123 - The bot confirms pairing within 5 seconds
- Lock down after everyone is paired:
npm run pair -- --agent=alfred --policy=allowlist
To manage channels (add/remove Telegram or Discord) on an existing agent:
make update-agent # choose "Manage channels"
Telegram Groups
The bot can respond in Telegram groups and supergroups. Groups must be registered before the bot will respond.
Step 1 β Add the bot to the group as Admin
Add your bot to the group and promote it to Admin. Without admin rights, Telegram does not deliver group messages to the bot β it will appear online but never respond.
Minimum required admin permission: "Read Messages" (or any admin role β even the most restricted works).
Step 2 β Get the group ID
Forward any message from the group to @userinfobot. It will reply with the chat ID β a negative number like -1001234567890.
Alternatively, send a message in the group and visit:
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
Look for "chat":{"id": ...} in the result.
Step 3 β Register the group
Edit the agent's access.json directly:
~/.claude-gateway/agents/<your-agent-id>/workspace/.telegram-state/access.json
Add the group under "groups":
{
"dmPolicy": "allowlist",
"allowFrom": ["..."],
"groups": {
"-1001234567890": {
"requireMention": true,
"allowFrom": []
}
}
}
Set "requireMention": false if you want the bot to respond to all messages without needing an @mention.
To restrict to specific members only, add their Telegram user IDs to "allowFrom".
Step 4 β Start chatting
@mention the bot in the group (or reply to one of its messages). Changes to access.json take effect immediately β no restart needed.
Managing groups
Edit access.json to add or remove entries from the "groups" object. The gateway re-reads the file on every inbound message.
Note:
/telegram:accessskill is available when running inside a gateway agent session (TELEGRAM_STATE_DIR is set automatically). For standalone terminal use, editaccess.jsondirectly as shown above.
Optional β Let the bot read all messages (disable Privacy Mode)
By default, Telegram bots in groups only receive messages that start with / or directly @mention the bot. If you want the bot to respond to every message without an @mention (and have set "requireMention": false in access.json), you also need to disable Privacy Mode at the bot level:
- Open @BotFather
- Send
/setprivacy - Select your bot
- Choose Disable
This is a bot-level setting β it applies to all groups the bot joins. If @mention-only is fine, skip this step and keep "requireMention": true.
Telegram Commands
Once paired, the following bot commands are available in a private chat:
Session management
| Command | Description |
|---|---|
/session | Show current session info (name, message count, context %) |
/sessions | List all sessions with inline keyboard β switch or delete |
/new <name> | Create a new session, optionally with a name |
/rename <name> | Rename the current session |
/clear | Clear current session history (with confirmation) |
/compact | Summarise old history and keep only recent messages |
/stop | Interrupt the in-flight turn (gateway sends SIGINT to the subprocess) |
/restart | Graceful session restart β shows a confirmation button; confirms and notifies when the session is back online |
Agent
| Command | Description |
|---|---|
/model | Show the current AI model |
/models | Switch AI model β shows an inline keyboard; selecting a model triggers a graceful restart and notifies when back online |
Account
| Command | Description |
|---|---|
/start | Pairing instructions |
/status | Check your pairing state |
/help | Show available commands |
Monitoring
The gateway runs an HTTP server on port 3000 (set PORT env var to change):
| Endpoint | Description |
|---|---|
GET /health | All agent IDs and running status |
GET /status | JSON stats per agent (sessions, uptime) |
GET /ui | Live HTML dashboard (auto-refreshes every 5s) |
POST /api/v1/agents/:id/messages | Send a message to an agent (requires API key) |
GET /api/v1/agents | List accessible agents (requires API key) |
/api/v1/crons/* | Cron job management β see API.md |
Development
# Build TypeScript
npm run build
# Unit tests only (fast, no external deps)
npm run test:unit
# Integration tests
npm run integration
# All tests
npm test
# Type check without building
npm run typecheck
Troubleshooting
Agent fails to start
- Check workspace path exists and contains
AGENTS.md - Check
dangerouslySkipPermissions: trueis set in config - Check logs in
~/.claude-gateway/logs/<id>.log
Agent not responding to messages
- Verify
dmPolicyinaccess.jsonβ ifallowlist, check the user's ID is inallowFrom - Ensure no other process is polling the same bot token (causes 409 Conflict)
- Only
TelegramReceiverpolls Telegram β MCP session subprocesses run inSEND_ONLYmode (no polling)
Session loses memory after restart
- History is persisted in
~/.claude-gateway/agents/<id>/sessions/<chat_id>.jsonl - If the file is missing, the session starts fresh (no error)
Personality not applied
CLAUDE.mdis auto-regenerated from workspace files on startup and on any file change- Trigger a reload by saving any
.mdfile in the workspace
Heartbeat not firing
- Verify
HEARTBEAT.mdYAML is valid - Check cron expression (5 fields:
min hour day month weekday) - Check rate limit β default 30 min between proactive messages
API returns 403
- Check the key value matches exactly (env var interpolation uses
${VAR}syntax) - Verify the key's
agentslist includes the target agent ID, or set"agents": "*"
MCP tools not working (telegram_reply, cron_list, etc.)
- Ensure
mcp/node_modules/exists β runmake mcp-installif not - Check that
mcp-config.jsonis generated in the session directory - Verify Bun is installed (
bun --version)
Status messages not appearing in Telegram
- First status update is sent after 5 seconds β very fast tasks may complete before it fires
- Check that the MCP server is running in
SEND_ONLYmode for session subprocesses - Verify the bot has permission to send messages in the chat
