aidaemon
Website ยท Documentation ยท GitHub ยท ๐
A personal AI agent that runs as a background daemon, accessible via Telegram, Slack, or Discord, with tool use, MCP integration, web research, scheduled tasks, and persistent memory.
I built this because I wanted to control my computer from my phone, from anywhere. I also wanted it to run on cheap hardware - a Raspberry Pi, an old laptop, a $5/month VPS - without eating all the RAM just to sit idle waiting for messages.
Why Rust?
aidaemon runs 24/7 as a background daemon. It needs to be small, fast, and run on anything:
- Runs on cheap/old hardware - ~10 MB idle memory. A Node.js process sits at 50-80 MB doing nothing. On a Raspberry Pi or a $5 VPS with 512 MB RAM, that difference is the difference between running and not running.
- Single binary, zero runtime -
cargo install aidaemongives you one binary. No Node.js, no Python, no Docker. Copy it to any machine and run it. - Startup in milliseconds - restarts after a crash are near-instant, which matters for the auto-recovery retry loop.
- No garbage collector - predictable latency. No GC pauses between receiving the LLM response and sending the reply.
If you don't care about resource usage and want more channels (WhatsApp, Signal, iMessage) or a web canvas, check out OpenClaw which does similar things in TypeScript.
Features
Channels
- Telegram interface - chat with your AI assistant from any device
- Slack integration - Socket Mode support with threads, file sharing, and inline approvals (feature flag:
--features slack) - Discord integration - bot with slash commands and thread support (feature flag:
--features discord)
LLM Providers
- Multiple providers - native Anthropic, Google Gemini, DeepSeek, and OpenAI-compatible (OpenAI, OpenRouter, Ollama, etc.)
- Smart model routing - auto-selects Fast/Primary/Smart tier by query complexity (keyword heuristics, message length, code detection)
- Token/cost tracking - per-session and daily usage statistics with optional budget limits
Tools & Agents
- Agentic tool use - the LLM can call tools (system info, terminal commands, MCP servers) in a loop
- MCP client - connect to any MCP server (filesystem, databases, etc.) and the agent gains those tools automatically
- Browser tool - headless Chrome with screenshot, click, fill, and JS execution
- Web research - search (DuckDuckGo/Brave) and fetch tools for internet access
- Sub-agent spawning - recursive agents with configurable depth, iteration limit, and dynamic budget extension
- CLI agent delegation - delegate tasks to claude, gemini, codex, aider, copilot (auto-discovered via
which) - Skills system - trigger-based markdown instructions loaded from a directory
Memory & State
- Persistent memory - SQLite-backed conversation history + facts table, with fast in-memory working memory
- Memory consolidation - background fact extraction with vector embeddings (AllMiniLML6V2) for semantic recall
- Database encryption - optional SQLCipher AES-256 encryption at rest (feature flag:
--features encryption)
Automation
- Scheduled tasks - cron-style task scheduling with natural language time parsing
- Email triggers - IMAP IDLE monitors your inbox and notifies you on new emails
- Background task registry - track and cancel long-running tasks
File Transfer
- File sharing - send and receive files through your chat channel
- Configurable inbox/outbox - control where files are stored and which directories the agent can access
Security & Config
- Config manager - LLM can read/update
config.tomlwith automatic backup, restore, and secrets redaction - Command approval flow - inline keyboard (Allow Once / Allow Always / Deny) for unapproved terminal commands
- Secrets management - OS keychain integration + environment variable support for API keys
Operations
- Web dashboard - built-in status page with usage stats, active sessions, and task monitoring
- Channel commands -
/model,/models,/auto,/reload,/restart,/clear,/cost,/tasks,/cancel,/help - Auto-retry with backoff - exponential backoff (5s โ 10s โ 20s โ 40s โ 60s cap) for dispatcher crashes
- Health endpoint - HTTP
/healthfor monitoring - Service installer - one command to install as a systemd or launchd service
- Setup wizard - interactive first-run setup, no manual config editing needed
Quick Start
# Build
# First run - launches the setup wizard
# After setup, run the daemon
The wizard will guide you through:
- Selecting your LLM provider (OpenAI, OpenRouter, Ollama, Google AI Studio, Anthropic, etc.)
- Entering your API key
- Setting up your Telegram bot token and user ID
Configuration
All settings live in config.toml (generated by the wizard). See config.toml.example for the full reference.
Secrets Management
API keys and tokens can be specified in three ways (resolution order):
"keychain"โ reads from OS credential store (macOS Keychain, Windows Credential Manager, Linux Secret Service)"${ENV_VAR}"โ reads from environment variable (for Docker/CI)- Plain value โ used as-is (not recommended for production)
The setup wizard stores secrets in the OS keychain automatically.
Provider
[]
= "openai_compatible" # "openai_compatible" (default), "google_genai", or "anthropic"
= "keychain" # or "${AIDAEMON_API_KEY}" or plain value
= "https://openrouter.ai/api/v1"
[]
= "openai/gpt-4o"
= "openai/gpt-4o-mini"
= "anthropic/claude-sonnet-4"
The kind field selects the provider protocol:
openai_compatible(default) โ works with OpenAI, OpenRouter, Ollama, DeepSeek, or any OpenAI-compatible APIgoogle_genaiโ native Google Generative AI API (Gemini models)anthropicโ native Anthropic Messages API (Claude models)
The three model tiers (fast, primary, smart) are used by the smart router. Simple messages (greetings, short lookups) route to fast, complex tasks (code, multi-step reasoning) route to smart, and everything else goes to primary.
Telegram
[]
= "keychain" # or "${TELOXIDE_TOKEN}" or plain value
= [123456789]
Slack
Requires building with --features slack:
[]
= true
= "keychain" # xapp-... Socket Mode token
= "keychain" # xoxb-... Bot token
= ["U12345678"] # Slack user IDs (strings)
= true # Reply in threads (default: true)
Terminal Tool
[]
# Set to ["*"] to allow all commands (only if you trust the LLM fully)
= ["ls", "cat", "head", "tail", "echo", "date", "whoami", "pwd", "find", "grep"]
MCP Servers
[]
= "npx"
= ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
Browser
[]
= true
= true
= 1280
= 720
# Use an existing Chrome profile to inherit cookies/sessions
# user_data_dir = "~/Library/Application Support/Google/Chrome"
# profile = "Default"
Sub-agents
[]
= true
= 3 # max nesting levels
= 10 # initial agentic loop iterations per sub-agent
= 25 # max iterations even with dynamic budget extension
= 8000
= 300 # 5 minute timeout per sub-agent
Sub-agents can request additional iterations via the request_more_iterations tool, up to max_iterations_cap.
CLI Agents
[]
= true
= 600
= 16000
# Tools are auto-discovered via `which`. Override or add your own:
[]
= "claude"
= ["-p", "--output-format", "json"]
[]
= "gemini"
= ["-p", "--output-format", "json", "--sandbox=false"]
Skills
[]
= true
= "skills" # relative to config.toml location
Email Triggers
[]
= "imap.gmail.com"
= 993
= "you@gmail.com"
= "keychain" # or "${AIDAEMON_EMAIL_PASSWORD}"
= "INBOX"
Web Search
[]
= "duck_duck_go" # "duck_duck_go" (default, no API key) or "brave"
= "keychain" # required for Brave Search
Scheduled Tasks
[]
= true
= 30 # how often to check for due tasks
[[]]
= "daily-summary"
= "every day at 9am" # natural language or cron syntax
= "Summarize my unread emails"
= false # if true, runs once then deletes
= false # if true, skips terminal approval
File Transfer
[]
= true
= "~/.aidaemon/files/inbox" # where received files are stored
= ["~"] # directories the agent can send files from
= 10
= 24 # auto-delete received files after this time
Daemon & Dashboard
[]
= 8080
= "127.0.0.1" # bind address for health endpoint (default: 127.0.0.1)
= true # enable web dashboard (default: true)
The dashboard provides a web UI at http://127.0.0.1:8080/ with status, usage stats, active sessions, and task monitoring. Authentication uses a token stored in the OS keychain.
State
[]
= "aidaemon.db"
= 50
= 6 # how often to run memory consolidation
= 100 # max facts to include in system prompt
= 1000000 # optional daily token limit (resets at midnight UTC)
# encryption_key = "keychain" # SQLCipher encryption (requires: --features encryption)
Channel Commands
These commands work in Telegram, Slack, and Discord:
| Command | Description |
|---|---|
/model |
Show current model |
/model <name> |
Switch to a specific model (disables auto-routing) |
/models |
List available models from provider |
/auto |
Re-enable automatic model routing by query complexity |
/reload |
Reload config.toml (applies model changes, re-enables auto-routing) |
/restart |
Restart the daemon (picks up new binary, config, MCP servers) |
/clear |
Clear conversation context and start fresh |
/cost |
Show token usage statistics for current session |
/tasks |
List running and recent background tasks |
/cancel <id> |
Cancel a running background task |
/help |
Show available commands |
Running as a Service
# macOS (launchd)
# Linux (systemd)
Security Model
- User authentication โ
allowed_user_idsis enforced on every message and callback query. Unauthorized users are silently ignored. - Terminal allowlist โ commands must match an
allowed_prefixesentry using word-boundary matching ("ls"allowsls -labut notlsblk). Set to["*"]to allow all. - Shell operator detection โ commands containing
;,|,`,&&,||,$(,>(,<(, or newlines always require approval, regardless of prefix match. - Command approval flow โ unapproved commands trigger an inline keyboard (Allow Once / Allow Always / Deny). The agent blocks until you respond.
- Persistent approvals โ "Allow Always" choices are persisted across restarts.
- Untrusted trigger sessions โ sessions originating from automated sources (e.g. email triggers, scheduled tasks with
trusted = false) require terminal approval for every command. - Config secrets redaction โ when the LLM reads config via the config manager tool, sensitive keys (
api_key,password,bot_token, etc.) are replaced with[REDACTED]. - Config change approval โ sensitive config modifications (API keys, allowed users, terminal wildcards) require explicit user approval.
- File permissions โ config backups are written with
0600(owner-only read/write) on Unix.
Inspired by OpenClaw
aidaemon was inspired by OpenClaw (GitHub), a personal AI assistant that runs on your own devices and connects to channels like WhatsApp, Telegram, Slack, Discord, Signal, iMessage, and more.
Both projects share the same goal: a self-hosted AI assistant you control. The key differences:
| aidaemon | OpenClaw | |
|---|---|---|
| Language | Rust | TypeScript/Node.js |
| Channels | Telegram, Slack, Discord | WhatsApp, Telegram, Slack, Discord, Signal, iMessage, Teams, and more |
| Scope | Lightweight daemon with web dashboard | Full-featured platform with web UI, canvas, TTS, browser control |
| Config | Single config.toml with keychain secrets |
JSON5 config with hot-reload and file watching |
| Error recovery | Inline error classification per HTTP status, model fallback, config backup rotation | Multi-layer retry policies, auth profile cooldowns, provider rotation, restart sentinels |
| State | SQLite + in-memory working memory (optional encryption) | Pluggable storage with session management |
| Install | cargo install aidaemon |
npm/Docker |
| Dependencies | ~30 crates, single static binary | Node.js ecosystem |
aidaemon is designed for users who want a lightweight daemon in Rust with essential features. If you need more channels (WhatsApp, Signal, iMessage) or a richer plugin ecosystem, check out OpenClaw.
Architecture
Channels โโโ Agent โโโ Smart Router โโโ LLM Provider
(Telegram, โ (OpenAI-compatible / Anthropic / Google Gemini)
Slack, โ
Discord) โโโโ Tools
โ โโโ System info
โ โโโ Terminal (with approval flow)
โ โโโ Browser (headless Chrome)
โ โโโ Web research (search + fetch)
โ โโโ Config manager
โ โโโ MCP servers (JSON-RPC over stdio)
โ โโโ Sub-agents (recursive, depth-limited)
โ โโโ CLI agents (claude, gemini, codex, aider, copilot)
โ โโโ Scheduler (create/list/cancel tasks)
โ
โโโโ State
โ โโโ SQLite (conversation history + facts + usage)
โ โโโ In-memory working memory (VecDeque, capped)
โ
โโโโ Memory Manager
โ โโโ Fact extraction (background consolidation)
โ โโโ Vector embeddings (AllMiniLML6V2)
โ
โโโโ Task Registry (background task tracking)
โ
โโโโ Skills (trigger-based markdown instructions)
Triggers โโโ EventBus โโโ Agent โโโ Channel notification
โโโ IMAP IDLE (email)
โโโ Scheduler (cron tasks)
Health server (axum) โโโ GET /health + Web Dashboard
- Agent loop: user message โ build history โ smart router selects model tier โ call LLM โ if tool calls, execute and loop (max iterations) โ return final response
- Working memory:
VecDeque<Message>in RAM, capped at N messages, hydrated from SQLite on cold start - Session ID = channel-specific chat/thread ID
- MCP: spawns server subprocesses, communicates via JSON-RPC over stdio
- Memory consolidation: periodically extracts durable facts from conversations, stores with vector embeddings for semantic retrieval
- Token tracking: per-request usage logged to SQLite, queryable via
/costcommand or dashboard