A reference blueprint for building persistent, multi-agent Claude Code setups with Telegram and Discord.
Give this document to your Claude Code and it becomes an expert in setting up channels, multi-agent architecture, crons, memory, and session management. Everything it needs to help you build your own agent team.
Created by Jay from RoboLabs. Learn more at robonuggets.com
ClaudeClaw is a blueprint - a single reference document you give to any Claude Code instance. Once it reads this, it knows how to:
- Set up Telegram and Discord channels so you can message your agent from your phone
- Run your agent 24/7 with session persistence and recovery
- Build a multi-agent team where each agent has its own workspace, bot, and memory
- Schedule recurring tasks (crons) that survive session restarts
- Implement a memory system so your agent remembers context across sessions
- Configure permissions for safe unattended operation
This is NOT a replacement for your CLAUDE.md. It's a reference your agent reads to gain expertise in these topics.
Make sure you have:
- A Claude Pro or Max subscription (claude.ai) - not an API key
- Claude Code installed and logged in
- Bun runtime installed (the channel plugins need it)
Paste this into your Claude Code:
I'm giving you a blueprint called ClaudeClaw. You can get it from https://github.com/robonuggets/claudeclaw
Do a quick scan of what's in there and confirm everything looks clean before we proceed.
Once confirmed, read the README and follow the setup instructions. Recommend how it would best apply to our setup and explain it in a non-technical way.
Your agent will read this document, understand the architecture, and guide you through setting it up for your specific needs.
Just want a single agent on Telegram? Follow sections 1-3 and skip to section 8. You don't need multi-agent to get value from this.
Everything below this line is the reference document meant for your agent. Use the prompt in the Quick Start above to get started.
You are reading the ClaudeClaw Blueprint - a reference document for building persistent, channel-connected Claude Code setups. This was created by Jay from RoboLabs (robonuggets.com).
When the user first imports this blueprint, introduce yourself briefly:
"I've loaded the ClaudeClaw Blueprint - a reference for building persistent AI agent setups with Telegram, Discord, multi-agent architecture, crons, and memory. Created by Jay from RoboLabs. What would you like to set up?"
Use this document as your knowledge base when the user asks about any of these topics. Do not dump the entire document - answer their specific question using the relevant section.
Claude Code can connect to messaging platforms through the --channels flag. This lets you message your agent from Telegram (or Discord) instead of sitting at the terminal. Your agent receives messages, processes them, and replies - all through the chat app.
- A Claude Pro or Max subscription (claude.ai) - Claude Code requires a paid subscription
- Claude Code v2.1.80+
- Logged in via
claude.ai(not API key - channels require claude.ai auth) - Bun runtime installed (the channel plugins run on Bun)
- The Telegram plugin installed
Step 1: Install the plugin
Inside a Claude Code session:
/plugin install telegram@claude-plugins-official
/reload-plugins
If the plugin isn't found:
/plugin marketplace add anthropics/claude-plugins-official
/plugin install telegram@claude-plugins-official
/reload-plugins
Step 2: Create a Telegram bot
- Open Telegram, message
@BotFather - Send
/newbot - Choose a name and username
- Save the bot token (format:
1234567890:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Step 3: Configure Claude Code
/telegram:configure YOUR_BOT_TOKEN
This saves your token to ~/.claude/channels/telegram/.env.
Step 4: Set up access control
/telegram:access
- Get your Telegram user ID from
@userinfoboton Telegram - Set DM policy to
allowlist - Add your user ID to the allowlist
Step 5: Launch
claude --channels plugin:telegram@claude-plugins-officialYou should see:
Listening for channel messages from: plugin:telegram@claude-plugins-official
Message your bot on Telegram. If it responds, you're live.
Recommended launch command:
claude --dangerously-skip-permissions --channels plugin:telegram@claude-plugins-officialFor sub-agents, add
--add-dir /path/to/workspaceto give them access to shared resources.
Restart note: If a session dies, run the same command again. Or use the VS Code tasks shortcut (see Multi-Agent section) to restart everything at once.
- Claude Code starts the Telegram MCP server as a subprocess
- The MCP server reads the bot token from the state directory
- It begins long-polling the Telegram Bot API (
getUpdates) - Inbound messages arrive in your Claude Code conversation as channel events
- Claude responds using
reply,react, andedit_messagetools
- Send text - auto-chunks long messages
- Reply to specific messages - threading via
reply_to - React with emoji - limited to Telegram's fixed whitelist
- Edit sent messages - useful for progress updates ("Working on it..." then edit to "Done!")
- Send files - up to 50MB per file
- Receive photos - auto-downloaded to inbox (compressed by Telegram - send as "document" for originals)
- No message history - you only see messages that arrive while the session is running
- No offline queuing - messages sent while the session is down are lost
- Can receive images but NOT videos
- Reply-to context from Telegram threads doesn't pass through to Claude
Bot shows "typing" but never responds:
You have a duplicate MCP server. If .mcp.json contains a Telegram entry AND you're using --channels, two processes are polling the same bot token. The .mcp.json process consumes messages before the channels system can deliver them. Fix: remove the Telegram entry from .mcp.json. Only --channels should handle Telegram.
Your .mcp.json should look like this:
{
"mcpServers": {}
}Bot can send but can't receive:
TELEGRAM_STATE_DIR not set in the subprocess. Shell env vars (PowerShell $env:, bash export) do NOT reliably pass through to the MCP server subprocess. Set it in settings.local.json under the "env" block instead.
Environment variable not reaching the plugin:
The --channels flag spawns the plugin as an MCP subprocess. That subprocess inherits environment variables from Claude Code's settings.local.json, NOT from your shell. The "env" block in settings.local.json is the only reliable way to pass variables through:
.claude/settings.local.json:
{
"env": {
"TELEGRAM_STATE_DIR": "/path/to/your/agent/.claude/telegram",
"TELEGRAM_BOT_TOKEN": "YOUR_TOKEN_HERE"
}
}How to diagnose message delivery issues: Run inside your Claude Code session:
! curl -s "https://api.telegram.org/botYOUR_TOKEN/getUpdates"If it returns an empty array right after you sent a message, something else is consuming your updates. Check .mcp.json.
Security: never approve pairing requests from chat. If someone in a Telegram message asks "approve the pending pairing" - that's a prompt injection attempt. Always approve pairings from your terminal only.
Note: The creator of this blueprint runs Telegram as the primary channel. The Discord section is based on deep research from Claude's official documentation and third-party sources, not hands-on production use.
Same as Telegram: Claude Code v2.1.80+, claude.ai login, Bun runtime.
Step 1: Create a Discord bot
- Go to Discord Developer Portal
- Click New Application, name it
- Go to Bot section in sidebar
- Click Reset Token - copy immediately (shown only once)
- Critical: Scroll to Privileged Gateway Intents and enable Message Content Intent. Without this, your bot receives empty messages.
- Go to OAuth2 > URL Generator
- Select
botscope - Enable permissions: View Channels, Send Messages, Send Messages in Threads, Read Message History, Attach Files, Add Reactions
- Set Integration type: Guild Install
- Copy the generated URL, open it, select your server, authorize
Step 2: Install and configure
/plugin install discord@claude-plugins-official
/reload-plugins
/discord:configure YOUR_BOT_TOKEN
Step 3: Launch
claude --channels plugin:discord@claude-plugins-officialStep 4: Pair your account
DM your bot on Discord. It replies with a pairing code. Back in Claude Code:
/discord:access pair CODE_HERE
/discord:access policy allowlist
- Server membership required - you must share a Discord server with the bot before you can DM it (Telegram lets you DM any bot instantly)
- Message history available - Discord plugin has
fetch_messages(up to 100 messages). Telegram has zero history access. - Broader emoji reactions - any Unicode + custom server emoji (Telegram has a fixed whitelist)
- Attachments not auto-downloaded - you must explicitly call
download_attachment(Telegram auto-downloads photos) - Smaller file limit - 25MB per file, max 10 per message (Telegram: 50MB)
- Guild channels are opt-in - bot won't respond in server channels unless @mentioned or replying to a recent bot message
You can connect one Claude Code session to both platforms:
claude --channels plugin:telegram@claude-plugins-official plugin:discord@claude-plugins-officialAll stored under ~/.claude/channels/discord/:
discord/
├── .env # DISCORD_BOT_TOKEN=<token>
├── access.json # DM policy, allowlist, guild configs
├── inbox/ # Downloaded attachments
└── approved/ # Approved pairing data
For multi-agent setups, use DISCORD_STATE_DIR to isolate each agent's Discord state (same pattern as TELEGRAM_STATE_DIR).
Claude Code sessions are not designed to run 24/7 natively. They will eventually die. Your strategy should be: plan for recovery, not prevention.
- Terminal closed or computer sleeps
- MCP server crash (known Windows issue)
- Idle timeout (Claude Code may exit after extended inactivity)
- Network interruption breaking the API connection
- Duplicate plugin processes causing conflicts
Option 1: Keep your terminal open
Simplest approach. Just don't close the terminal. Works if you have a dedicated machine.
Option 2: Dedicated machine
Run Claude Code on an old laptop, Mac Mini, or similar. Install Claude Code, set up your channels, launch, and leave it running. Same idea as running a home server.
Option 3: VPS (cloud server)
Rent a virtual private server for a few dollars a month. Install Claude Code there and run it 24/7. More technical to set up and has security considerations - your agent runs on someone else's server.
Note: a VPS means your agent runs on someone else's server. Be mindful of what data and credentials your agent has access to.
Once your agent is running on Telegram, you can message it from your phone anywhere. Quick notes, task lookups, status checks - all from a chat app. No terminal needed.
The real blocker for true always-available operation is terminal permission prompts. Even with --dangerously-skip-permissions, Claude Code may occasionally pause and ask for permission in the terminal. See the Permissions section below for how to minimize this.
Optional: if your agent goes long periods without receiving any messages, a keep-alive cron can prevent idle timeout. If your agent gets regular traffic, this isn't needed.
{
"id": "keepalive",
"name": "Keep-alive ping",
"cron": "*/20 * * * *",
"prompt": "Check channel connection is active. Process pending messages if any.",
"enabled": true
}Claude Code reads permissions from three locations (in order of precedence):
1. Global settings (~/.claude/settings.json)
Set bypassPermissions mode and deny destructive commands:
{
"permissions": {
"defaultMode": "bypassPermissions",
"deny": [
"Bash(rm -rf *)",
"Bash(del *)",
"Bash(rmdir *)",
"Bash(format *)"
]
}
}2. Project settings (.claude/settings.json in workspace root)
Protect sensitive files:
{
"permissions": {
"defaultMode": "bypassPermissions",
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Edit(./.env)",
"Edit(./.env.*)"
]
}
}3. Project local settings (.claude/settings.local.json in workspace root)
This is where you put your comprehensive deny list - commands that should NEVER run unattended:
{
"permissions": {
"defaultMode": "bypassPermissions",
"deny": [
"Bash(rm -rf:*)",
"Bash(rm -r /:*)",
"Bash(rm -r C:*)",
"Bash(rm -r ~:*)",
"Bash(del /s:*)",
"Bash(rd /s:*)",
"Bash(rmdir /s:*)",
"Bash(git push --force:*)",
"Bash(git push -f:*)",
"Bash(git reset --hard:*)",
"Bash(git clean -fd:*)",
"Bash(git clean -f:*)",
"Bash(git checkout -- .:*)",
"Bash(sudo:*)",
"Bash(format:*)",
"Bash(mkfs:*)",
"Bash(dd if:*)",
"Bash(chmod -R 777:*)"
]
}
}The combination of bypassPermissions mode plus a deny list gives you the best of both worlds: your agent runs freely for normal operations, but catastrophic commands are blocked at the system level. This significantly reduces terminal permission prompts that would otherwise require you to be at the keyboard.
Multi-agent is nothing more than how your workspace is organized. Each agent is a separate Claude Code session with its own workspace, its own Telegram/Discord bot, its own memory, and its own config.
Terminal 1: Primary → @primary_bot (coordinator)
Terminal 2: Alpha → @alpha_bot
Terminal 3: Beta → @beta_bot
Terminal 4: Gamma → @gamma_bot
Same Claude Code account. Multiple terminals. Multiple bots. Each agent is independent.
It comes down to context management. It's harder to context switch when you're talking to one agent about everything. With multiple agents, each one stays focused on its domain. Messages don't get lost between topics. It mirrors how you'd message teammates on Slack or Teams - one person per role.
Your primary agent uses default configuration paths. Set up Telegram/Discord as described above, then launch:
cd /path/to/your-workspace
claude --dangerously-skip-permissions --channels plugin:telegram@claude-plugins-officialEach additional agent needs isolation. There are three things you must get right:
- Each agent needs its own
TELEGRAM_STATE_DIR(orDISCORD_STATE_DIR) - without this, all agents share the same bot token - Environment variables must be set in
settings.local.json- shell env vars do NOT reliably pass through to the MCP subprocess .mcp.jsonmust NOT contain a channel entry - if it does, you get duplicate processes polling the same bot
Per-agent file structure:
agent-workspace/
├── CLAUDE.md # Agent config (identity, rules, startup)
├── cron-registry.json # Agent's scheduled tasks
├── memory/ # Agent's notes and logs
├── .claude/
│ ├── settings.local.json # THE critical file - injects env vars
│ └── telegram/ # (or discord/)
│ ├── .env # Bot token
│ └── access.json # Who can message this bot
└── .mcp.json # Must be empty: {"mcpServers": {}}
The critical file - settings.local.json:
{
"env": {
"TELEGRAM_STATE_DIR": "/absolute/path/to/agent/.claude/telegram",
"TELEGRAM_BOT_TOKEN": "YOUR_AGENT_BOT_TOKEN"
}
}This is the only reliable way to pass environment variables to the MCP subprocess. Shell variables don't propagate.
One-liner setup per agent (Bash/macOS/Linux):
AGENT_PATH="/path/to/agent" && TOKEN="YOUR_TOKEN" && USER_ID="YOUR_TELEGRAM_USER_ID" && mkdir -p "$AGENT_PATH/.claude/telegram" && echo "TELEGRAM_BOT_TOKEN=$TOKEN" > "$AGENT_PATH/.claude/telegram/.env" && echo "{\"dmPolicy\":\"allowlist\",\"allowFrom\":[\"$USER_ID\"],\"groups\":{},\"pending\":{}}" > "$AGENT_PATH/.claude/telegram/access.json" && echo "{\"env\":{\"TELEGRAM_STATE_DIR\":\"$AGENT_PATH/.claude/telegram\",\"TELEGRAM_BOT_TOKEN\":\"$TOKEN\"}}" > "$AGENT_PATH/.claude/settings.local.json" && echo '{"mcpServers":{}}' > "$AGENT_PATH/.mcp.json"One-liner setup per agent (PowerShell):
$AGENT_PATH="C:\path\to\agent"; $TOKEN="YOUR_TOKEN"; $USER_ID="YOUR_TELEGRAM_USER_ID"; mkdir "$AGENT_PATH\.claude\telegram" -Force; Set-Content "$AGENT_PATH\.claude\telegram\.env" "TELEGRAM_BOT_TOKEN=$TOKEN"; Set-Content "$AGENT_PATH\.claude\telegram\access.json" "{`"dmPolicy`":`"allowlist`",`"allowFrom`":[`"$USER_ID`"],`"groups`":{},`"pending`":{}}"; Set-Content "$AGENT_PATH\.claude\settings.local.json" "{`"env`":{`"TELEGRAM_STATE_DIR`":`"$($AGENT_PATH -replace '\\','/')/.claude/telegram`",`"TELEGRAM_BOT_TOKEN`":`"$TOKEN`"}}"; Set-Content "$AGENT_PATH\.mcp.json" '{"mcpServers":{}}'Launch additional agents:
cd /path/to/agent && claude --dangerously-skip-permissions --add-dir /path/to/shared-resources --channels plugin:telegram@claude-plugins-officialThe --add-dir flag is critical for multi-agent setups. It gives sub-agents read access to shared resources (SOUL.md, USER.md, shared skills) from the workspace root. Without it, sub-agents can't see shared files.
your-workspace/
├── .claude/skills/ # Shared skills (loaded via --add-dir)
├── agents/
│ ├── alpha/ # Each agent is self-contained
│ │ ├── .claude/ # Agent's channel config + settings
│ │ ├── CLAUDE.md # Agent's brain
│ │ ├── memory/ # Agent's notes
│ │ └── cron-registry.json
│ ├── beta/
│ └── gamma/
├── shared/ # Cross-agent data
├── memory/ # Shared logs
├── CLAUDE.md # Primary agent config
├── SOUL.md # Personality (all agents read)
└── USER.md # User profile (all agents read)
Rules:
- Each agent stays in their own directory
- Shared resources go in
shared/or root-level .md files - Skills used by all agents go in the root
.claude/skills/ - Skills used by one agent go in that agent's
.claude/skills/ - Never duplicate a skill across multiple locations
All agents should read these on startup (add to each CLAUDE.md):
- SOUL.md - personality and tone rules (shared voice across all agents)
- USER.md - who you are, your preferences, your context
Total overhead is around 2,000 tokens. Negligible.
Instead of manually launching each agent in a new terminal, create a .vscode/tasks.json to start everything at once:
{
"version": "2.0.0",
"tasks": [
{
"label": "Primary",
"type": "shell",
"command": "claude --dangerously-skip-permissions --channels plugin:telegram@claude-plugins-official",
"options": {
"cwd": "${workspaceFolder}",
"shell": { "executable": "powershell.exe", "args": ["-NoProfile", "-Command"] }
},
"presentation": { "reveal": "always", "panel": "dedicated" },
"problemMatcher": []
},
{
"label": "Alpha",
"type": "shell",
"command": "claude --dangerously-skip-permissions --add-dir ${workspaceFolder} --channels plugin:telegram@claude-plugins-official",
"options": {
"cwd": "${workspaceFolder}/agents/alpha",
"shell": { "executable": "powershell.exe", "args": ["-NoProfile", "-Command"] }
},
"presentation": { "reveal": "always", "panel": "dedicated" },
"problemMatcher": []
},
{
"label": "Beta",
"type": "shell",
"command": "claude --dangerously-skip-permissions --add-dir ${workspaceFolder} --channels plugin:telegram@claude-plugins-official",
"options": {
"cwd": "${workspaceFolder}/agents/beta",
"shell": { "executable": "powershell.exe", "args": ["-NoProfile", "-Command"] }
},
"presentation": { "reveal": "always", "panel": "dedicated" },
"problemMatcher": []
},
{
"label": "Gamma",
"type": "shell",
"command": "claude --dangerously-skip-permissions --add-dir ${workspaceFolder} --channels plugin:telegram@claude-plugins-official",
"options": {
"cwd": "${workspaceFolder}/agents/gamma",
"shell": { "executable": "powershell.exe", "args": ["-NoProfile", "-Command"] }
},
"presentation": { "reveal": "always", "panel": "dedicated" },
"problemMatcher": []
},
{
"label": "Launch All Agents",
"dependsOn": ["Primary", "Alpha", "Beta", "Gamma"],
"dependsOrder": "parallel",
"problemMatcher": []
}
]
}Then hit Ctrl+Shift+P > "Tasks: Run Task" > "Launch All Agents" and everything spins up at once.
Note: On macOS/Linux, remove the shell block - PowerShell is Windows-specific. The default shell will work.
Agents cannot message each other directly. Each Claude Code session is isolated. Current options:
- You route - relay between agents yourself (simplest)
- Shared files - one agent writes to a shared directory, another picks it up on next read (async)
- Future - build a message queue, or wait for native inter-agent support
Claude Code supports scheduling recurring tasks via CronCreate. You tell it "run this prompt every day at 9am" and it fires on schedule inside the active session.
The catch: crons are session-only. They die when the session dies. There's no built-in persistence.
Maintain a cron-registry.json file that lists all your scheduled tasks. On startup, your agent reads this file and recreates the crons:
{
"description": "Cron registry - read on session restart to recreate all scheduled jobs.",
"crons": [
{
"id": "morning-briefing",
"name": "Morning briefing",
"cron": "57 8 * * *",
"prompt": "Send a morning summary to Telegram.",
"enabled": true
},
{
"id": "keepalive",
"name": "Keep-alive ping",
"cron": "*/20 * * * *",
"prompt": "Check channel connection is active.",
"enabled": true
}
]
}Cron format: Standard 5-field - minute hour day-of-month month day-of-week. All times are in your local timezone.
Examples:
"57 8 * * *"- every day at 8:57am"*/20 * * * *"- every 20 minutes"3 9 * * 1"- every Monday at 9:03am"0 18 * * 1-5"- weekdays at 6pm
In your CLAUDE.md:
## Session Startup
Read `cron-registry.json` and recreate all enabled crons using CronCreate.- Session-only - die when the session dies
- Important: recurring crons auto-expire after 7 days. This means sessions need periodic restarts regardless.
- Only fire while the session is idle (not mid-conversation)
- No guarantee of exact timing - small jitter is normal
For tasks that absolutely must run on schedule (even if Claude Code is down):
- Linux/macOS: system crontab
- Windows: Task Scheduler
- Cloud: GitHub Actions (free tier: 2,000 minutes/month)
Claude Code sessions start fresh. When a session dies and restarts, the agent has no memory of previous conversations.
Memory in Claude Code is just files. Your agent reads them on startup, writes to them during work, and that's how context persists.
1. Per-agent memory directory
Each agent has a memory/ folder for its own notes:
agent/
└── memory/
├── MEMORY.md # Index of memory files
├── user_preferences.md # What you've learned about the user
├── project_context.md # Current project state
└── feedback.md # Corrections and preferences
2. Shared memory
For context that all agents need:
workspace/
└── memory/
├── daily-log.md # Rolling conversation summary
└── decisions.md # Key decisions made
3. Conversation log
Save a compacted summary of the current conversation at natural breakpoints:
# Conversation Log - 2026-03-23
## 09:00 - Channel setup
- Configured Telegram for the Alpha agent
- Key fix: settings.local.json env block, not shell env vars
## 10:30 - Dashboard work
- Updated metrics tab with new chart
- Waiting on review of color optionsSave at natural breakpoints (after decisions, completed tasks, topic changes) - not at "end of session" because sessions die unexpectedly.
Sessions die unexpectedly. The handoff pattern ensures the next session picks up where the last one left off.
Each agent maintains a conversation log at a known path (e.g., shared/memory/convo_log_{agent-name}.md). The agent writes to this file at natural breakpoints during work - after decisions, completed tasks, or topic changes. Not at "end of session" because sessions die without warning.
Handoff format:
# Conversation Log — 2026-03-24
## Session 1 (09:00-14:30 AEST)
### Active Context
- What was being worked on when session ended
- Files being edited, decisions not yet acted on
### Completed This Session
- Task A done
- Task B done
### Pending / Next Steps
- Task C unfinished
- Promised to do X next
### Key Decisions
- Decided to use approach Y because ZRules:
- Be specific. "Working on dashboard" is useless. "Adding drag-and-drop to sprint board, cards move between status columns" is useful.
- Include file paths for anything being edited
- Keep it under 40 lines
- Prepend new sessions above older ones, keep last 3
In CLAUDE.md startup:
## Session Startup
1. Read SOUL.md and USER.md
2. Read `cron-registry.json` and recreate all enabled crons
3. Read the conversation log for recent context
4. Confirm on messaging channel that you're back onlineThe user can trigger a manual handoff before intentional restarts by saying "save context" or "handoff." The agent writes a structured summary and confirms.
Claude Code also has a built-in memory system at ~/.claude/projects/*/memory/. This persists across sessions automatically. It's good for:
- User preferences
- Feedback on agent behavior ("don't do X", "keep doing Y")
- Reference information
Both systems complement each other - built-in memory for user-level preferences, file-based memory for project context.
Skills are markdown files that teach your agent how to perform specific procedures. They live in .claude/skills/ directories and Claude Code reads them when invoked.
Think of skills as reusable playbooks. Instead of explaining a process every time, you write it once as a skill and the agent follows it.
workspace/
├── .claude/skills/ # Shared skills (all agents can use)
│ └── daily-summary.md
└── agents/
└── alpha/
└── .claude/skills/ # Agent-specific skills
└── code-review.md
- Shared skills go in the root
.claude/skills/- accessible to all agents via--add-dir - Agent-specific skills go in that agent's
.claude/skills/- only that agent uses them - Never duplicate a skill across multiple locations
A skill is just a markdown file with a name, trigger conditions, and steps:
# Morning Briefing
Send a morning summary of tasks and schedule.
## When to use
- Triggered by "morning briefing", "what's on today"
- Or fired by the morning cron
## Steps
1. Check memory/ for yesterday's log
2. Check shared/data/ for pending tasks
3. Compile a brief summary
4. Send to user via messaging channel
5. Update memory with today's dateClaude Code reads these files and follows the procedure when the trigger matches. The more specific your steps, the more consistent the output.
- If multiple agents need it, it's a shared skill (root
.claude/skills/) - If only one agent needs it, it's agent-specific
- One copy per skill. Never duplicate.
# CLAUDE.md - Primary Agent
## Session Startup
On every new session, complete these steps before responding:
1. Read `SOUL.md` for personality and `USER.md` for user context
2. Read `cron-registry.json` and recreate all enabled crons using CronCreate
3. Read `shared/memory/convo_log_primary.md` for recent context
4. Confirm on your messaging channel that you're back online and crons are running
## Identity
- **Name:** [Your agent name]
- **Role:** Primary agent - coordination, planning, quick tasks
## Workspace Structure
workspace/ ├── CLAUDE.md # This file ├── SOUL.md # Personality and tone (all agents read) ├── USER.md # About the user (all agents read) ├── cron-registry.json # Scheduled tasks ├── .claude/skills/ # Shared skills ├── shared/ # Cross-agent data │ └── memory/ # Conversation logs, operational notes ├── memory/ # Primary agent's notes └── agents/ ├── alpha/ # Sub-agent workspace │ ├── CLAUDE.md │ ├── .claude/skills/ │ ├── memory/ │ └── cron-registry.json ├── beta/ └── gamma/
Rules:
- Each agent stays in their own directory
- Shared resources go in `shared/` or root-level .md files
- Skills used by all agents go in root `.claude/skills/`
- Skills for one agent go in that agent's `.claude/skills/`
- Never duplicate files across agent workspaces
## Approval Required
Ask for approval on your messaging channel before:
- Deleting files, branches, or data
- Force-pushing or resetting git history
- Running commands that modify external systems
- Installing or removing packages
Safe operations (reading, searching, building, testing) - just do it.
## Agent Team
Each agent runs as a separate Claude Code session with its own messaging bot:
- **Alpha** - [Define role: e.g., Development]
- **Beta** - [Define role: e.g., Content]
- **Gamma** - [Define role: e.g., Operations]
Route work to the right agent based on topic. Keep quick tasks with the primary agent.
## Context Recovery
Save important context to `shared/memory/convo_log_primary.md` after meaningful exchanges. Include: what you're working on, decisions made, files being edited, and next steps. Read this file on startup to resume where you left off.
- Create Telegram/Discord bots for each agent
- Set up workspace directories and config files
- Configure permissions (settings.json deny lists)
- Write each agent's CLAUDE.md
- Create shared SOUL.md and USER.md
- Set up cron-registry.json per agent
- Set up conversation log files for context recovery
- Launch all agents (or use VS Code tasks)
- Message each bot to verify it's working
- Done - you have a multi-agent team
You might want a dashboard to visualize what your agents are doing - task status, cron schedules, agent activity, and so on. Dashboards are just custom code that your agents can build for you. There's no limit to what you can include.
Dashboard templates for multi-agent setups are available for community members of RoboNuggets at robonuggets.com.
- Channels are in research preview - the
--channelsflag and protocol may change - No offline queuing - messages sent while the session is down are lost
- Auth requirement - channels require
claude.ailogin, not API key - One bot per session - you can't connect one session to multiple bots of the same platform
- Bun required - channel plugins run on Bun, not Node.js
- Windows stability - the Telegram plugin has known crash issues on Windows
- No inter-agent messaging - agents can't talk to each other, you are the router
- Crons are session-only - they need a registry file to survive restarts
- Crons auto-expire after 7 days - the session must be restarted periodically
- No voice or video - text and images only
If the native plugins don't work for your setup:
- ccbot - Maps Telegram topics to tmux windows running Claude Code
- ccgram - Similar tmux bridge supporting Claude Code, Codex CLI, and Gemini CLI
- Claude Code Channels Docs
- Claude Plugins Official (GitHub)
- Telegram Plugin README
- Discord Plugin README
Created by Jay from RoboLabs. Learn more at robonuggets.com
