Self-hostable agent platform built on Anthropic Managed Agents, with Discord, Slack, MCP, and CLI adapters.
One-click install, operator-run. You deploy daimon once, on your own
Anthropic API key, and it serves any number of Discord servers from that
single deployment — each server is an isolated tenant, so guilds never see
each other's data even though they share your key. You install it, you own
the key, you're responsible for it; the people in your servers just
@mention the bot and get a working agent.
- Mention-triggered threaded conversations —
@daimonin a channel starts (or continues) a threaded turn with session continuity - Slash-command admin surface —
/agent-setup,/routines,/billing,/privacy,/helpmirror the CLI; only/agent-setupand/routinesare gated by Discord's ownManage Serverpermission, the rest are available to everyone - CLI + MCP adapters alongside Discord, all sharing the same core turn pipeline and tenant-scoped stores
- Slack adapter (optional) — full parity with Discord, per-workspace
OAuth install, plus opt-in per-user Slack access; see
docs/slack.mdfor how per-user access is scoped - Per-tenant isolation enforced at the database
tenant_idlayer, not the API-key boundary — one shared Anthropic key powers every guild
- An Anthropic API key with Managed Agents beta access — Managed Agents is a closed beta; request access before you start, or the quickstart below will fail at session-create time
- Docker (for Postgres, and for
docker compose updeploys) uv(Python package/dependency manager)- Python 3.12+ (managed automatically by
uvif not already installed)
Every command below runs in order from a clean checkout and ends with a bot
that responds to an @mention in Discord.
cp .env.example .envOpen .env, uncomment and fill in:
DAIMON_ANTHROPIC__API_KEY— your beta-enabled Anthropic keyDAIMON_MCP__JWT_SECRET— any random string (e.g.openssl rand -hex 32)DAIMON_MCP__PUBLIC_URL—http://localhost:8765/mcpis fine for local use
docker compose interpolates every service in docker-compose.yml — including
mcp and scheduler — for any command against the file, even
docker compose up -d postgres. Those three vars are guarded with
${VAR:?...} (fail-fast on missing value), so all three must be set in .env
before the first docker compose command below, not just the Anthropic key.
POSTGRES_PASSWORD is also required by docker-compose.yml and is guarded
the same way — uncomment POSTGRES_PASSWORD= in .env and set a strong,
URL-safe value (avoid @ : / % #, which break the interpolated asyncpg DSN).
You'll add DAIMON_DISCORD__BOT_TOKEN in step 4. .env is gitignored —
secrets never get committed here.
uv sync --all-extras --all-packagesdocker compose up -d postgres
export DAIMON_DATABASE_URL=postgresql+asyncpg://daimon:<your-POSTGRES_PASSWORD>@localhost:5432/daimon
uv run alembic upgrade headThe alembic CLI reads from the shell environment (it does not auto-load
.env), so this export is required when running alembic directly. Either
the flat DAIMON_DATABASE_URL or nested DAIMON_DATABASE__URL form works.
Seed the default agents/environments/skills:
uv run daimon defaults apply- Go to the Discord Developer Portal and create a new application.
- Under Bot, create a bot user and copy its token into
.envasDAIMON_DISCORD__BOT_TOKEN. - Still under Bot, enable the Message Content Intent — this is a
privileged intent and the bot will not receive message text without it
(the adapter requests
intents.message_content = Trueat startup and will fail to read mentions correctly if the portal toggle is off). - Under OAuth2 → URL Generator, select the
botandapplications.commandsscopes, then under Bot Permissions select at least:Send Messages,Send Messages in Threads,Create Public Threads,Manage Threads,Read Message History. - Copy the generated URL, open it in a browser, and invite the bot to a test server you control.
uv run python -m daimon.adapters.discordIn the Discord server you invited the bot to, send a message that
@mentions the bot. It replies in a new thread — that's a working
deployment.
packages/core/—daimon-corelibrary (MA client, stores, turn pipeline)packages/adapters/cli/— thedaimonadmin CLIpackages/adapters/discord/— the Discord bot adapterpackages/adapters/mcp/— the MCP server adapterpackages/adapters/slack/— the Slack adapter (optional)packages/adapters/scheduler/— the routines scheduler adapterpackages/testing/— shared test fixtures/harnessapps/notebook-host/— standalone marimo notebook host servicedefaults/— YAML defaults seeded into Managed Agents + local DBdocs/slack.md— Slack adapter per-user access modeltests/— cross-package integration tests
- Core / adapters split:
daimon.coreowns schema, stores, and the turn pipeline; it has zero adapter imports. Eachdaimon.adapters.*package (CLI, Discord, MCP, Scheduler, Slack) owns one platform's I/O, rendering, and auth, and adapters never import each other. Enforced byimport-linterin CI. - Managed Agents is the source of truth for agent/environment/session/ skill/vault content. Our own database holds identity, namespacing, and provenance only — no local mirror of MA state.
- Tenancy: one Discord server (guild) that has installed the bot is one
daimon tenant. Many tenants share a single Anthropic API key / MA
workspace — the operator's. Isolation is enforced at the database
tenant_idlayer (and matching MA resource metadata), not at the API-key boundary.
- Docker Compose (this repo's
docker-compose.yml) runs Postgres plus themcp,discord, andschedulerprocess groups from one image — see the Quickstart above for the.envprerequisite. - A Terraform/GCP deployment guide is planned.
See CONTRIBUTING.md for dev environment setup and the
quality gates every PR must keep green.
See SECURITY.md for how to report a vulnerability.