aidaemon
Website · Documentation · Discord · 𝕏
A self-hosted AI agent that runs on your machine and talks to you on Telegram, Slack, or Discord. It can run commands, browse the web, manage files, remember things across conversations, and learn your workflows over time.
I built this because I wanted to control my computer from my phone, from anywhere. Send a message on Telegram, and it runs a command, checks a log, deploys something, or researches a topic — then replies with the result. I also wanted it to run on cheap hardware: a Raspberry Pi, an old laptop, a $5/month VPS.
What makes it different
- It's yours — runs on your machine, your API keys, your data. Nothing goes to a third party beyond the LLM API calls you choose to make.
- It remembers you — persistent memory with fact extraction, vector embeddings, and semantic recall. It learns your preferences, your projects, the people you mention. Not a shallow "memory" feature — a full knowledge graph that grows over time.
- It's always on — runs as a background daemon. Message it on Telegram at 3am from your phone. Schedule tasks with cron syntax or natural language. It's not an app you open — it's an assistant that's always available.
- It can act — 40+ tools: terminal commands, file operations, git, web browsing, web research, HTTP requests with OAuth, MCP servers. It doesn't just answer questions — it does things.
- It's a single binary — no Docker, no Node.js, no Python environment. One binary, copy it anywhere and run it. Starts in milliseconds, uses minimal RAM.
- It works with any LLM — OpenAI, xAI (Grok), Anthropic, Google Gemini, DeepSeek, Moonshot, MiniMax, Ollama, OpenRouter, Cloudflare AI Gateway, or any OpenAI-compatible API. Switch providers without changing anything else.
Quick Start
One-line install
curl -sSfL https://get.aidaemon.ai | bash
Homebrew
brew install davo20019/tap/aidaemon
Cargo
cargo install aidaemon
Then run aidaemon — the setup wizard walks you through picking a provider, entering your API key, and connecting a channel.
Features
Channels
Talk to it on Telegram, Slack (Socket Mode), or Discord. Run multiple bots, add new ones at runtime with /connect, no restart needed.
Send images with a caption and the agent analyzes them via vision-capable LLMs (toggle with [files] vision_enabled in config).
Ask it to create an image and the provider-neutral generate_image tool saves and attaches the result, ready for send_file. The bundled image backend uses a connected ChatGPT subscription and works even when the conversational model is Anthropic, Gemini, or another configured provider.
Send voice notes or audio files on Telegram, Slack, or Discord. Audio-capable models receive native input_audio blocks; otherwise enable local Whisper STT fallback under [files.stt] (requires whisper-cli, a GGUF model, and ffmpeg for OGG/Opus). See config.toml.example for settings. Restart after config changes.
Telegram owners can also run /terminal [agent] [working_dir] to launch the hosted terminal Mini App (https://terminal.aidaemon.ai) for direct CLI-agent sessions with automatic secure daemon pairing.
Tools & Agents
40+ built-in tools including terminal execution, file operations, git, web browser (headless Chrome), web search, HTTP requests with auth profiles, and MCP server integration. Tools declare their risk level — read-only operations run freely, side effects require approval.
Delegate complex tasks to sub-agents or external CLI agents (Claude, Gemini, Codex, Aider — auto-discovered).
Memory
SQLite-backed persistent memory with vector embeddings (AllMiniLML6V2). Background consolidation extracts durable facts from conversations. Semantic episode recall is the coarse discovery layer; search_history adds authorized FTS5 search over exact retained user/assistant messages, anchored context, task bookends, and signed forward/backward paging. Exact recall follows state.retention.messages_days (90 by default; 0 opts into permanent active-database history), independently of short-lived diagnostic events. Database encrypted at rest by default.
Skills
Trigger-based instructions that teach it new workflows. Load from files, URLs, or remote registries. Successful procedures auto-promote to skills after enough consistent use.
Automation
Cron-style scheduled tasks with natural language time parsing. Email triggers via IMAP IDLE. Long-running goal tracking with task breakdown and multi-schedule support.
Security
Terminal command allowlists, inline approval flow (Allow Once / Allow Always / Deny), SSRF protection, input sanitization, encrypted state, secrets in OS keychain, and role-based access control. See the security docs for the full model.
Running as a Service
# macOS
aidaemon install-service
launchctl load ~/Library/LaunchAgents/ai.aidaemon.plist
# Linux
sudo aidaemon install-service
sudo systemctl enable --now aidaemon
Configuration
All settings live in config.toml, generated by the setup wizard. See config.toml.example for the full reference and the documentation for detailed guides on each feature. The provider config supports both model-level fallbacks on the primary backend and ordered cross-provider fallbacks via [[provider.fallbacks]].
Execution environments
By default, agent-visible files and commands run locally with the same behavior as earlier releases. You can instead put the entire workspace behind a persistent Docker container or an SSH host:
[execution]
backend = "local" # local | docker | ssh
# workspace_root = "/absolute/path/to/workspace"
# allow_outside_workspace = true # path tools: true locally, false remotely
Filesystem tools, terminal commands, Git operations, CLI agents, attachments, and generated result files all use the selected backend. This keeps the model on one coherent filesystem. Configuration, encrypted state, channel transport, credentials, approvals, and browser/computer-use sessions remain on the daemon host.
Docker support is deliberately optional so the default build remains a single-binary, Docker-free installation:
cargo install aidaemon --features execution-docker
The Docker backend creates or reuses one persistent container and defaults to
no network access. The SSH backend uses the local OpenSSH client and honors
existing host aliases, ssh-agent, ProxyJump, known-host, and hardware-key
configuration. allow_outside_workspace confines path-based tools and command
working directories; shell commands still have the permissions of the
selected local/SSH account or container and remain subject to terminal
approval. Persistent terminal approvals are scoped to the concrete execution
target. See config.toml.example for complete Docker and
SSH examples.
Workspace source checkpoints
For remotely operated agents, the local execution backend can create a conflict-aware source checkpoint before the first workspace mutation in each turn:
[execution]
backend = "local"
workspace_root = "/absolute/path/to/project"
allow_outside_workspace = false
[checkpoints]
enabled = true
Checkpoints use a bare shadow-Git object store in aidaemon's platform data
directory. They never modify the project's .git directory, index, or
working-tree metadata. .env* secrets (except example/template files), keys,
credentials, dependencies, build outputs, caches, logs, special files, and
oversized files are excluded; project .gitignore rules are respected.
Owners can use /checkpoints or the read-only list_checkpoints tool to list
them. /rollback <id> produces a conflict preview and short-lived confirmation
token; /rollback confirm <token> restores only paths still matching the
agent's finalized post-turn tree. Independently changed paths are preserved,
and a safety checkpoint is taken before rollback.
This beta is local-backend only. Raw terminal/agent bridge sessions are not covered, and checkpoints involving detached/background mutation are marked unsafe rather than offered for rollback. The external object store is owner-readable and contains plaintext copies of eligible source files; use retention and size limits appropriate for the machine.
Customize your agent
The setup wizard asks what your agent should be called, what role it should serve, and how it should communicate. It writes those choices to an editable persona.md next to config.toml.
You can also configure it manually:
[agent]
name = "Nova"
persona_file = "persona.md"
Use the persona file for the agent's role, communication style, priorities, and working preferences:
# Role
You are a research and project-management partner.
# Communication style
- Be concise and direct.
- Challenge questionable assumptions constructively.
- Explain technical subjects in plain language.
Relative persona paths resolve next to config.toml; absolute paths are also supported. Restart aidaemon after changing the name, persona path, or persona file. Persona instructions customize behavior without replacing aidaemon's privacy, security, tool-use, or completion-honesty rules.
The built-in policy profiles cheap, balanced, and strong are execution presets, not separate model tiers. They all use your configured default model; the differences are context budget, tool budget, verification depth, and approval behavior. The open-source default auto-routing now floors at balanced for better reliability, while cheap remains available as a lower-budget preset for custom forks and policy tweaks.
Model supervision is trust-tiered. By default (trust_tier = "auto" under [policy]), recognized frontier models (Claude, GPT-4/5, o-series, Gemini 2.5+, Grok 3/4) run a thin loop where behavioral supervision gates are telemetry-only, while every other model gets the full supervision scaffolding. The auto list matches known model families, so a capable open model it doesn't recognize (for example kimi-k2.5 or a large qwen/deepseek variant) lands in the supervised tier, where a gate misfire can cost extra LLM round-trips before an answer is accepted. If you run such a model, set trust_tier = "autonomous" to opt out of the supervision gates; anti-fabrication checks and hard safety caps (iteration/token/wall-clock limits, repetition guards) remain active on every tier. The override is global — it applies to every configured model, including fallbacks — so keep "auto" if your fallback chain mixes a strong cloud model with a small local one. See config.toml.example for details.
Using a ChatGPT subscription instead of an API key
aidaemon can run on a ChatGPT Plus/Pro/Business plan rather than metered OpenAI API billing. Sign in once:
aidaemon auth login openai # add --paste for headless/remote installs
aidaemon auth status
aidaemon auth logout openai
The setup wizard offers the same option. Then point the provider at it:
[provider]
kind = "openai_chatgpt"
api_key = "" # unused; credentials come from the OAuth store
reasoning_effort = "medium" # none | minimal | low | medium | high | xhigh | max | ultra
[provider.models]
primary = "gpt-5.6-terra" # sol = flagship, terra = balanced, luna = fast
fast = "gpt-5.6-luna"
smart = "gpt-5.6-sol"
Model and reasoning effort are both yours to pick. Effort is passed through verbatim, so newly added levels work without a client update; each model supports its own subset and the API rejects ones it doesn't.
Sign-in is OAuth 2.0 + PKCE against auth.openai.com, with the redirect landing
on http://localhost:1455/auth/callback (the port is fixed by OpenAI's client
registration — use --paste when no local browser can reach it). Tokens are
stored in the OS keychain and refreshed automatically. Requests identify
themselves with an originator: aidaemon header.
The same login also enables generate_image (when [files] enabled = true).
It uses ChatGPT's subscription-backed image service and does not require an
OPENAI_API_KEY. The image backend is selected independently from the chat
provider, so a conversation running on Anthropic, Gemini, xAI, or a local model
can still generate through the connected ChatGPT account.
Internally, generate_image targets a provider-neutral
ImageGenerationBackend interface. The ChatGPT subscription adapter is the
first bundled implementation; adding another provider's native image API only
requires a new adapter, without changing the tool schema, agent loop, attachment
handling, or delivery flow. Until such an adapter is configured, image requests
still require the ChatGPT login above. Disable the tool explicitly with
[tools] disabled = ["generate_image"] if that fallback is not wanted.
Subscription plans meter usage: when a cap is hit, the provider reports a rate limit and the configured fallbacks take over. Background goals and heartbeats pointed at a subscription model will reach that cap faster than interactive use alone. These credentials do not work with OpenAI's Realtime endpoints, which still need a Platform API key.
Secrets (API keys, bot tokens) are stored in your OS keychain by default — not in config files.
If you prefer env-only secrets, set AIDAEMON_NO_KEYCHAIN=1. In that mode:
- aidaemon reads secrets from environment variables /
.env - secret writes (including OAuth token refresh rotation) are persisted back to the env file
- set
AIDAEMON_ENV_FILE=/absolute/path/.envto control which env file is used (default:.envin working directory)
For env-only mode, keep the env file private (chmod 600) and out of version control.
For external APIs, the built-in auth flow is:
manage_apifor a single deterministic connect + learn + verify flowmanage_oauthfor OAuth services, including custom OAuth 2.0 PKCE, authorization-code, and client-credentials providers you register at runtimemanage_http_authfor API keys, bearer tokens, custom headers, basic auth, or OAuth 1.0a credentialsmanage_skillswithlearn_apito ingest the official docs or OpenAPI/Swagger URL into a reusable API guide after auth is set up
learn_api now prefers OpenAPI/Swagger when available, crawls multiple docs pages on the same host when needed, discovers linked specs from docs, bundles remote OpenAPI $ref documents, and can switch to GraphQL schema introspection when a GraphQL endpoint is available.
manage_api can now auto-derive a safe verification probe from a learned OpenAPI spec, and for GraphQL onboarding it can reuse introspection as the verification probe when you didn’t provide a separate verify_url.
Both paths keep secrets in the keychain by default, or in the configured .env file when AIDAEMON_NO_KEYCHAIN=1.
Building from Source
cargo build --release # standard build
cargo build --release --features "slack,discord" # with Slack and Discord
cargo build --release --features "browser" # with headless Chrome
cargo test # run tests
See CLAUDE.md for architecture details, module map, and contributor guidance.
No comments yet
Be the first to share your take.