Skip to content

Operations

The bridge logs to the container output: login, one line per finished turn (thread ID, steps, cost) and errors. Use docker compose logs -f or Portainer’s Logs. Permission prompts appear as buttons in the Discord thread, so there is nothing to attach to. !stop in a thread interrupts its running turn.

Attaching to the Claude session (plugin mode)

Section titled “Attaching to the Claude session (plugin mode)”

The container keeps a TTY open so you can see Claude’s terminal and answer permission prompts.

  • Docker: docker attach claude-discord. Detach with Ctrl-P Ctrl-Q (Ctrl-C would stop Claude and the container).
  • Portainer: Containers → claude-discord → Console → Attach.

From the terminal you can also run slash commands such as /discord:access to manage pairing when DISCORD_ALLOWED_USERS is empty.

Terminal window
docker compose restart

Bridge mode: running turns are interrupted; each thread resumes its session on the next message. Plugin mode: with CLAUDE_CONTINUE=true the new session continues the previous conversation. Set it to false to start fresh. Changes to DISCORD_* variables take effect on restart because access.json is rebuilt from env.

The version is pinned and the auto-updater is off. To update:

  1. Change CLAUDE_CODE_VERSION in the Dockerfile (or pass --build-arg), and the matching @anthropic-ai/claude-agent-sdk version in bridge/package.json (cd bridge && npm install @anthropic-ai/claude-agent-sdk@<version>).
  2. Rebuild: docker compose up -d --build, or, for Portainer, recreate claude-discord-build.tar and build the image again, then Recreate the container (pull disabled).

The node user has passwordless sudo, so the bot (or you, in the console) can run sudo apt-get install <package>. Packages installed this way are lost when the container is recreated. Anything needed permanently belongs in the Dockerfile.

Path Volume Survives recreate
/home/node/.claude claude-home yes
/workspace ./workspace or claude-workspace yes
everything else (apt packages, /tmp) none no
Symptom Likely cause
Container exits with DISCORD_BOT_TOKEN is required The variable is missing from .env / stack.env.
Exits with Set CLAUDE_CODE_OAUTH_TOKEN (recommended) or ANTHROPIC_API_KEY No Claude credentials provided.
Bot is online but ignores messages Not @mentioned while DISCORD_REQUIRE_MENTION=true; user not in the allow list; channel ID missing from DISCORD_CHANNELS; Message Content Intent disabled.
git push fails with authentication errors GH_TOKEN unset, expired, or not granted the repository.
Permission denied writing /workspace (Compose) The host folder is not owned by UID 1000.
Claude seems stuck Bridge: look for Allow/Deny buttons in the thread, or send !stop. Plugin: it may be waiting on a permission prompt; attach and answer it.
Bridge exits with DISCORD_CHANNELS must list at least one channel ID Bridge mode needs DISCORD_CHANNELS and DISCORD_ALLOWED_USERS.
A thread stays on ⏳ All BRIDGE_MAX_CONCURRENT slots are busy; it starts when another turn finishes.
Not logged in in a thread The Claude token is missing or expired; check CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_API_KEY.