Skip to content

Configuration

All configuration is done with environment variables. Copy .env.example to .env (Docker Compose) or paste it into the Portainer stack’s environment variables. .env is in .gitignore; never commit it.

Variable Description
DISCORD_BOT_TOKEN Bot token from the Discord Developer Portal → Bot → Reset Token.
CLAUDE_CODE_OAUTH_TOKEN Claude subscription token. Create it with claude setup-token on your own machine. Recommended.
ANTHROPIC_API_KEY Alternative to the OAuth token: an Anthropic Console API key, billed per token.

Set exactly one of CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY.

Variable Default Description
BOT_MODE bridge bridge: one Claude session per Discord thread (Thread sessions). plugin: one shared session through the Discord channel plugin.

Bridge mode needs DISCORD_ALLOWED_USERS and DISCORD_CHANNELS, and ignores DMs and the DISCORD_DM_POLICY / DISCORD_ACCESS_MODE / DISCORD_STATE_DIR variables.

Plugin mode: leave DISCORD_ALLOWED_USERS empty to manage access by hand with /discord:access instead. When it is set, access.json is rebuilt from these values on every start (see Entrypoint).

Variable Default Description
DISCORD_ALLOWED_USERS (empty) Comma-separated Discord user IDs allowed to use the bot (plugin mode: also to DM it).
DISCORD_CHANNELS (empty) Comma-separated server channel IDs where the bot listens.
DISCORD_CHANNEL_USERS DISCORD_ALLOWED_USERS User IDs allowed to trigger the bot in those channels.
DISCORD_REQUIRE_MENTION true true: a new session starts only on an @mention. Inside a session thread no mention is needed.
DISCORD_DM_POLICY allowlist Plugin mode: allowlist, pairing or disabled. .env.example sets disabled.
DISCORD_ACCESS_MODE (empty) Plugin mode: static reads access.json once at boot and never writes it (no pairing). .env.example sets static.
DISCORD_STATE_DIR ~/.claude/channels/discord Where the plugin keeps its state. Not in .env.example; rarely needed.

To find an ID, enable Developer Mode in Discord (Settings → Advanced), then right-click a user or channel → Copy ID.

Variable Default Description
CLAUDE_PERMISSION_MODE auto auto, manual, acceptEdits, dontAsk, bypassPermissions or plan.
CLAUDE_MODEL account default Model ID, e.g. claude-opus-5-5 or claude-sonnet-5-5.
CLAUDE_EFFORT default low, medium, high, xhigh or max.
CLAUDE_CONTINUE true Plugin mode: resume the previous conversation after a restart. Bridge threads always resume their own session.
Variable Default Description
BRIDGE_MAX_CONCURRENT 3 Sessions that may run at the same time. Each needs roughly 250 MB of memory or more.
BRIDGE_APPROVAL_TIMEOUT_S 600 Seconds to wait for Allow/Deny on a permission prompt before denying.
BRIDGE_CWD /workspace Working directory of every session.
BRIDGE_STATE_DIR ~/.claude/discord-bridge Where the thread → session map is stored.
BRIDGE_INBOX_DIR /workspace/.discord-inbox Where Discord attachments are saved for Claude.
CLAUDE_CODE_PATH /usr/local/bin/claude Claude Code executable the sessions run.

The last four are not in .env.example; the defaults fit the image.

Variable Description
GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL Commit author; also written to the global git config at start.
GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL Commit committer.
GH_TOKEN GitHub token used by gh and by git over HTTPS. Use a fine-grained token scoped to specific repositories.

For a GitHub-verified identity without exposing a personal address, use the account’s noreply email (<id>+<username>@users.noreply.github.com).

Variable Example Description
TZ Europe/Vilnius Container time zone.
BOT_MODE=bridge
DISCORD_BOT_TOKEN=xxxxxxxx
CLAUDE_CODE_OAUTH_TOKEN=xxxxxxxx
DISCORD_ALLOWED_USERS=111111111111111111,222222222222222222
DISCORD_CHANNELS=333333333333333333
DISCORD_REQUIRE_MENTION=true
CLAUDE_PERMISSION_MODE=auto
BRIDGE_MAX_CONCURRENT=3
GIT_AUTHOR_NAME=Your Name
GIT_AUTHOR_EMAIL=12345678+you@users.noreply.github.com
GIT_COMMITTER_NAME=Your Name
GIT_COMMITTER_EMAIL=12345678+you@users.noreply.github.com
GH_TOKEN=github_pat_xxxxxxxx
TZ=Europe/Vilnius