Agent Daemon Documentation
What is This?
The agent daemon is a background service that runs your AI agent and keeps it online 24/7. Your agent is like a member of Mutiro (a messaging platform) - it can receive and send messages, just like a human user would.
The Big Picture
Mutiro is a messaging platform where users can chat with each other and with AI agents. Your agent daemon:
- Receives messages from users via Mutiro
- Sends them to an AI (like Claude or Genie) for processing
- Sends the AI's response back to the user
- Stays running 24/7 so your agent is always available
What You Can Build
- Personal assistant - An always-on AI helper for yourself
- Customer support bot - Automated help for your users
- Code assistant - AI that helps with programming tasks
- Team helper - Shared AI agent for your organization
How It Works (Simple View)
AI Engines Explained
An AI engine is the actual AI brain that generates responses. The daemon supports three options:
- Claude - Anthropic's Claude AI (powerful, conversational, great for most uses)
- Genie - A customizable AI with file access and tool usage
- Echo - Simple test engine that echoes messages back (for development)
What Makes the Daemon Different?
The daemon is one way to run an agent on Mutiro. Key characteristics:
Runs continuously in background Responds to messages automatically Perfect for always-on bots and assistants Requires configuration file
Use the daemon when: You want an always-on agent that responds to messages automatically without manual intervention.
Configuration
The daemon needs a configuration file to know how to behave. This file is called .mutiro-agent.yaml
and should be in the directory where you run the mutiro start
command.
How to get this file:
Run mutiro agents create --username your_bot_name --engine claude
(or genie
/echo
). This command:
- Creates your agent on Mutiro
- Generates the API key for authentication
- Creates
.mutiro-agent.yaml
with your agent's credentials
Think of it as: The instruction manual for your AI bot - it tells the daemon which AI to use, what username to give your bot, and how it should behave.
Key Settings Explained
Before diving into the full configuration, here are the most important settings you need to know:
Required Settings (automatically set by mutiro agents create
):
agent.username
- Your bot's username (likemy_assistant
)agent.api_key
- Secret key to connect to Mutiro (generated when you create the agent)agent.engine
- Which AI to use (claude
,genie
, orecho
)
Important Settings:
workspace
- Where your AI can read/write files (set this if your agent needs file access)allowlist
- Who can message your agent (defaults to only you - see Access Control & Security)
Optional Settings:
- Everything else has sensible defaults and you can ignore them at first
api_endpoint
anduse_tls
- Only for developers running local Mutiro services
Complete Configuration Reference
Here's a full example showing all possible settings:
Environment Variable Substitution
What is this? Instead of hardcoding secrets in your config file, you can reference environment variables (values stored in your terminal session or .env
file).
Why use it? Keep API keys secret and out of version control (like git).
How it works: Put ${VARIABLE_NAME}
anywhere in your config:
Setting environment variables:
Option 1: Using a .env
file (recommended):
The daemon automatically loads .env
files from the current directory.
Option 2: Export in terminal:
Pro tip: Use descriptive variable names like ${MUTIRO_SUPPORT_BOT_KEY}
instead of generic ${MUTIRO_API_KEY}
when you have multiple agents. This makes it clear which key is for which agent.
Workspace Variables
What is a workspace? A folder where your AI can read and write files. Think of it as the AI's "working directory."
Why use workspace variables? To give each conversation its own isolated folder, preventing file conflicts.
The workspace
setting supports special variables that change based on who's talking:
${CONVERSATION_ID}
: Unique ID for each conversation (likeconv_abc123
)${USERNAME}
: Who sent the message (likealice
)
Examples:
Setting up workspaces automatically:
The workspace_init
script runs once when a workspace is first created:
Variables available in the init script:
$CONVERSATION_ID
- The conversation ID$USERNAME
- Who's talking$WORKSPACE
- The full workspace path
Access Control & Security
Who Can Message Your Agent?
By default: Only you (the agent creator) can message your agent. This is the safest option.
Why this matters: Your agent can execute code, access files, and take actions on your behalf. You want to control who can trigger these actions!
The Allowlist
The allowlist
setting controls which users can send messages to your agent:
Default behavior (when you create an agent):
Sharing with Specific Users
Share with a few trusted people:
Public Agents
- Your agent has no sensitive access
- You understand the security implications
- You're ready to handle potential abuse
Make agent public to everyone:
Blocking Specific Users
Block individual users:
The !
prefix means "reject this user."
Security Best Practices
1. Start restrictive, expand carefully:
2. For public agents, limit capabilities:
- Use Echo engine for testing
- Don't give file access (
workspace
not set) - Monitor logs regularly
- Set up rate limiting (future feature)
3. Review who's using your agent:
4. Different agents for different purposes:
Session Management
What is a Session?
A session is like a conversation's memory. When you talk to Claude AI, it remembers what you said earlier in the conversation - that's the session. Without sessions, the AI would have amnesia and forget everything between messages!
Example without sessions:
Example with sessions:
How the Daemon Manages Sessions
The daemon keeps separate sessions per conversation so users don't accidentally share context:
This means Alice and Bob can both talk to your bot without seeing each other's conversation history.
Where Sessions are Stored
Sessions are saved in a database on your computer so they survive restarts:
What does this mean?
~/.mutiro/agents/
- Hidden folder in your home directory{project_hash}
- A unique code based on your workspace path (ensures consistent location){agent_username}
- Your bot's usernameagent.db
- The local database file
Example:
What Gets Stored
The database remembers:
- Session IDs: Which Claude session belongs to which conversation
- Processed Messages: Which messages we've already responded to (prevents duplicates)
- Message Hashes: Fingerprint of the last message processed
- First Startup Flag: Whether we've sent the welcome message yet
- API Key: Your bot's authentication key
Session Persistence Across Restarts
The magic: When you restart the daemon, it picks up right where it left off!
How it works:
- Loads session from storage - Checks the database for existing sessions
- Resumes conversation - Tells Claude "continue session XYZ"
- Maintains full context - The AI remembers everything from before the restart
Example:
Performance optimization: The daemon keeps recent sessions in memory (RAM) for instant access. Only checks the database when a session isn't in memory yet. This makes responses faster after the first message in a conversation.
Claude --continue Mode (Advanced)
Special feature for personal assistants: You can share context between manually running claude code
and your Mutiro bot!
Setup:
How it works:
- Work on your code manually:
claude code
in your terminal - Start your Mutiro bot:
mutiro start
in the same folder - Message your bot on Mutiro
- The bot continues your manual session! It sees all the context from step 1
- Keep working in terminal - the daemon picks up your changes
Real-world example:
The magic: Both manual Claude and the daemon can run simultaneously! Each time either one accesses the session, it gets the latest state. Your manual work is visible to the bot, and vice versa.
When to use:
Personal assistant (only you use the bot) Multi-user bot (would mix everyone's conversations - bad!) Seamless switching between terminal and Mutiro Bot can see your manual work in real-time
Technical details:
- Claude stores sessions in
~/.claude/projects/{project-path}/
--continue
finds the most recent session file- Session updates are picked up by both processes
- Session files are
.jsonl
files with UUID names
How the Daemon Behaves
What Happens When You Start It
When you run mutiro start
, here's what happens behind the scenes:
- Reads your config from
.mutiro-agent.yaml
- Sets up storage in
~/.mutiro/agents/
for sessions and state - Checks if this is the first time
- If yes: Sends you a welcome message
- Saves a flag so it doesn't welcome you again
- Connects to Mutiro services
- Messaging (to receive/send messages)
- Presence (to show your bot as "online")
- Starts listening for messages
- Tries port 9090 (or your configured port)
- If busy, tries ports 50050-50100
- If all busy, uses a random available port
- Starts health check (daemon_port + 1000, so if daemon is on 9090, health check is on 10090)
- Ready! Your bot is now online and waiting for messages
The Welcome Message
The first time your bot starts, it sends you a friendly greeting:
Important: This only happens once! The daemon remembers it said hello and won't spam you on every restart.
How Messages Get Processed
When someone sends your bot a message, here's the journey it takes:
Key insight: Steps 2-8 happen in milliseconds! The AI part (step 6-7) is the slowest.
What If Connection Drops?
Don't worry! The daemon automatically handles connection issues and no messages are lost.
What happens:
- Agent goes offline (network issue, restart, etc.)
- Users can keep sending messages - Mutiro queues them
- Daemon reconnects automatically after
reconnect_delay
(default 5s) - Picks up where it left off - Processes all queued messages in order
- No messages missed - The daemon tracks the last processed message
Real-world example:
Key benefit: Users don't need to know if your agent is online or offline. They can send messages anytime, and the agent will catch up when it reconnects.
Future improvement: Exponential backoff (wait longer after repeated failures)
Stopping the Daemon Safely
When you press Ctrl+C or send a stop signal:
- Stops accepting new messages - "No more work, please!"
- Finishes current work - Completes messages it's already processing
- Closes AI connections - Cleanly shuts down Claude/Genie
- Saves everything - Flushes database to disk
- Shuts down - Exits cleanly
Result: No data loss, no corrupted state. Safe to restart anytime!
Storage & State
What's in the Database?
The daemon stores everything in a local database (like a dictionary with key-value pairs):
What's Stored | Example | Why |
---|---|---|
API Key | your-secret-key-123 |
Authentication |
Sessions | session:conv_abc → session_xyz |
Remember conversations |
Message Hashes | hash:conv_abc → a1b2c3 |
Know which message we last processed |
Processed Messages | processed:msg_123 → timestamp |
Prevent duplicates |
First Startup Flag | first_startup → true |
Remember we sent the greeting |
Think of it like: A small notebook where the daemon writes down important things to remember.
Resetting Everything (Nuclear Option)
Want to start fresh? Delete the database:
- Forget all sessions (fresh conversations)
- Reprocess old messages (might duplicate responses)
- Send the greeting message again
- Forget its API key (you'll need to reconfigure)
AI Engine Setup
Claude Engine
What is it? Uses Anthropic's Claude AI via the Claude Code CLI tool.
Simplest setup:
That's it! Just make sure you have Claude Code installed and ANTHROPIC_API_KEY
set.
Custom settings:
Session options:
Setting | What Happens | Best For |
---|---|---|
(default) | Separate session per conversation | Multi-user bots |
command: "claude --continue" |
Share session with manual usage | Personal assistant |
Add extra instructions to Claude:
Behind the scenes:
- Daemon adds
--resume {session-id}
automatically - If you use
--continue
, daemon skips adding--resume
- Session ID extracted from Claude's response and saved
Genie Engine
What is it? Genie is a customizable AI with tool access - it can run commands, read files, and take actions on your computer. You define "personas" (personalities/behaviors).
Developed by Mutiro Labs as an open-source project.
Learn more: github.com/kcaldas/genie
Why use Genie?
- More control over AI behavior via personas
- Can run shell commands and scripts
- Local file access and manipulation
Setup:
-
Create a persona folder:
mkdir -p .genie/personas/my_helper/ -
Add
prompt.yaml
defining the persona's behavior -
Configure the daemon:
agent: engine: genie workspace: /absolute/path/to/workspace # Where Genie can work genie: persona: my_helper # Must match folder name auto_approve: false # Ask before running commands
Important notes:
auto_approve: false
means Genie asks before running commands (safer!)auto_approve: true
means Genie runs commands automatically (faster but riskier!)- Working directory comes from
workspace
field
Echo Engine (For Testing)
What is it? A dummy AI that just repeats your messages back. Perfect for testing!
Why use it?
- No API keys needed
- Instant responses
- Test your daemon setup without using real AI
Setup:
What you'll see:
Pro tip: Use delay: 0ms for instant testing, or add delay to simulate real AI response times.
Common Use Cases
Here are some real-world examples to get you started!
Personal Assistant (Just For You)
Goal: Your own private AI that remembers your conversations across terminal and Mutiro.
Config:
How to use:
- Code in your terminal:
claude code
- Ask Claude to write a feature
- Start daemon:
mutiro agent daemon
- Message your bot on Mutiro: "Add tests for that feature"
- Bot remembers the feature from your terminal session!
Multi-User Support Bot
Goal: A bot that helps multiple users, keeping their conversations separate.
Config:
What happens:
- Alice talks to the bot → Gets her own session
- Bob talks to the bot → Gets his own session
- They never see each other's messages
- Bot remembers context separately for each
- Daemon restart doesn't lose any context
Quick Testing
Goal: Test your daemon setup without spending money on API calls.
Config:
Perfect for:
- Verifying daemon starts correctly
- Testing message delivery
- Debugging configuration issues
- No API key needed (besides Mutiro)
Code Assistant with File Access
Goal: AI that can read/write files, with isolated workspace per user.
Config:
What happens:
- User messages bot for first time
- Daemon creates workspace folder
- Runs init script (clones repo)
- Claude gets file access to that workspace only
- Each user gets their own isolated copy
Troubleshooting
Common problems and how to fix them!
Bot Forgets Everything After Restart
Problem: Your bot has amnesia every time you restart it.
Why this happens:
- The workspace path keeps changing
- Database gets created in different locations
- Can't find old sessions
Fix: Use an absolute path for workspace:
Bad examples:
Good examples:
Bot Responds Twice to Same Message
Problem: You send one message, bot replies twice (or more!)
Why this happens:
- Database got deleted or corrupted
- Daemon can't track which messages it already processed
How to check:
How to fix:
- Check logs:
tail ~/.mutiro/logs/agents/my_assistant-*.log
- Look for database errors
- If corrupted, delete and restart:
rm -rf ~/.mutiro/agents/*/my_assistant/
Can't Find Claude
Problem: Error says claude: executable file not found
Why: Your computer doesn't know where Claude is installed.
Fix #1 - Add Claude to PATH:
Fix #2 - Use full path in config:
Check if Claude is installed:
If not installed: Install Claude Code from claude.ai/code
Sessions Not Loading Correctly
Problem: Sessions seem to disappear randomly or don't persist.
Debug steps:
1. Check the logs for session operations:
2. Look for these messages:
- Good!Session loaded from storage
- Good!Session saved for conversation
- Good!Session found in cache Any errors - Bad!
3. Inspect database (advanced):
Genie Can't Find Persona
Problem: Error says persona not found: my_helper
Common mistakes:
1. Wrong folder structure:
2. Missing environment variable:
3. YAML file has syntax errors:
- No tabs allowed, only spaces
- Check indentation is consistent
- Validate at yamllint.com
Daemon Using Too Much Memory
Problem: Memory usage keeps growing.
Why this happens:
- Daemon keeps one AI engine per conversation in memory
- More active conversations = more memory
- This is normal and expected!
Is it a problem?
- 10 conversations: Probably fine
- 100 conversations: Might need more RAM
- 1000+ conversations: Consider restarting periodically
Solution if needed:
- Restart daemon daily/weekly:
systemctl restart mutiro-daemon
- Or just Ctrl+C and restart manually
Where Are the Logs?
All daemon activity gets logged here:
Useful commands: