Getting it into your agent
There is no command for this one: it runs only inside a plugin, and the catalogue could not identify which plugin ships it. The source is linked below.
Wrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/haileyok/cc-discord/claude-md)<a href="https://agentmods.dev/instructions/haileyok/cc-discord/claude-md"><img src="https://agentmods.dev/badge/instructions/haileyok/cc-discord/claude-md.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.03977 | $0.03977 |
| Opus 5 | $0.01988 | $0.01988 |
| Sonnet 5 | $0.00795 | $0.00795 |
| Haiku 4.5 | $0.00398 | $0.00398 |
Grade B, and why
cc-discord CLAUDE.md scanned grade B with 2 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Reads agent configuration directoriesmediumAgent snooping
.claude/, .codex/, .gemini/ hold keys, settings and other credentials a mod has no legitimate need for.
- **`cli doctor` checks settings.json hook paths against `bridge.__file__`.** If you `uv tool install .` the bridge into `~/.local/bin`, `bridge.__file__` resolves into the uv tool venv, not this repo. The doctor's hook- Runs shell commandslowCapability
Expected in a hook, worth knowing in a rule or an instructions file.
- **zellij is client-server: env on the `zellij run` subprocess is invisible to the spawned command.** The spawned process inherits the *server's* env (set when the user originally started zellij), not the bridge daemon' How it starts
The opening of the file, as written. The whole thing — 63 lines — stays where its author put it; the contents beside it link to each section on GitHub.
claude-discord-bridge
Localhost HTTP bridge between Claude Code sessions and Discord. Single-process Python daemon — aiohttp server and discord.py client share one asyncio event loop.
Freshness: 2026-05-09
Repo location and tooling
This repo lives at /home/discord/claude-discord-bridge, outside the /home/discord/discord monorepo. clyde, clint, the monorepo's pre-commit hooks, and Buildkite CI do not apply here. Don't import from or symlink into the monorepo.
Python is pinned to 3.12 via uv (.python-version). The system python3 is 3.10 — always invoke through uv:
- Tests:
uv run pytest(notpytest) - Run daemon in foreground:
scripts/run-foreground.sh(usesuv run)
Gotchas
MESSAGE_CONTENTprivileged intent.bot.pysetsintents.message_content = Truebecause reply routing reads message text. The bot user in the Discord Developer Portal must have this intent enabled, oron_messagepayloads arrive empty. Theinitwizard prints a reminder; agents adding new gateway features should not forget it.- Hooks must always exit 0.
hooks/notify-stop.pyandhooks/notify-notification.pywrapmain()intry/except: pass; finally: sys.exit(0)on purpose — a Claude Code Stop/Notification hook that fails non-zero degrades the user's session. Preserve that contract when editing. - FIFO ordering for
/v1/askis enforced byAskLockMap, notListener.Listener.register()raisesRuntimeErrorif a thread already has a pending ask — this is an invariant guard, not the queueing mechanism. The per-threadasyncio.Lockinserver.AskLockMapmust be acquired before posting the question and released afterunregister. Any new/v1/ask-style endpoint must follow the same lock-then-register pattern. - Single event loop, shared by aiohttp + discord.py. Long blocking work (sync DB calls,
time.sleep,requests) inside any handler starves both the HTTP server and the Discord gateway. Use the async equivalents (aiosqlite,asyncio.sleep,aiohttpclient). SKILL.mdinskills/is symlinked into~/.claude/skills/ask-discord/SKILL.md. Edit the file in this repo; the live skill follows. Don't duplicate.cli doctorchecks settings.json hook paths againstbridge.__file__. If youuv tool install .the bridge into~/.local/bin,bridge.__file__resolves into the uv tool venv, not this repo. The doctor's hook-path check expects<repo>/hooks/notify-*.pypaths in~/.claude/settings.jsonto match wherever the package is currently importing from. Rundoctorfrom the same install you registered hooks against.- Task-scoped settings via
--settingsflag, not env var. Discord-driven sessions (/startslash command) generate a per-task settings file at~/.local/state/claude-discord-bridge/task-settings/<task_id>.jsonand pass it viaclaude --settings <path>. Hooks accumulate (merge), not override — the user's existing~/.claude/settings.jsonhooks (e.g.notify-stop.py,notify-notification.py) still fire alongside the task-scoped hooks. The bridge'sevent.pyhook is idempotent, so duplicate fires from both sources are harmless. - PreToolUse is registered ONLY for
AskUserQuestionandExitPlanMode._on_pre_tool_usedispatches_handle_ask_user_question/_handle_exit_plan_modedirectly from the hook body's structuredtool_input— that's the only moment we have access to the question text and option list (Claude doesn't flush the tool_use to the JSONL until the user answers, and the Notification body just says "Claude Code needs your attention" with no question content). The hook returns nopermissionDecisionso the tool still proceeds to TUI block; the user's Discord reaction reply gets typed into the pane via the existing TUI handler flow. All other PreToolUse traffic is unhooked so auto-mode's classifier still drives approvals._on_notificationskips dispatch when a TUI handler is already running, so PreToolUse + the trailing Notification don't double-post. - Bridge zellij session is shared and configurable. Default name is
meow; override withBRIDGE_ZELLIJ_SESSION. Each task is one named tab (cc-<task_id_prefix>). Don'tzellij kill-session <name>while tasks are running — it kills every tab at once and the bridge will mark them allcrashedon next event. - Self-attach panic. zellij ≥ 0.43 panics if the daemon calls
zellij attach --create-background <name>for the session it's already running inside.zellij._running_inside_target_session()checksZELLIJ_SESSION_NAMEand skips the attach when colocated. New code that wants to ensure the session is alive should callensure_session_alive(), not invoke attach directly. - zellij is client-server: env on the
zellij runsubprocess is invisible to the spawned command. The spawned process inherits the server's env (set when the user originally started zellij), not the bridge daemon's env. To inject task vars, use theenv(1)prefix in the spawn argv —ZellijManager.spawn_taskdoes this forCC_DISCORD_TASK_ID/BRIDGE_URL. Do not rely onsubprocess.Popen(..., env=...)for anything that needs to reach the spawned pane. load_from_dbdefers Discord posts toflush_startup_notices(). Reconcile-against-zellij happens before the HTTP server accepts requests, but the Discord bot logs in later — soself._botisNoneduring reconcile. Stage notices via_pending_startup_notices; the caller flushes them afterbot.is_ready. Don't addself._bot.*calls inside the reconcile branch.- Assistant content streams at PostToolUse boundaries, not all at Stop.
_stream_assistant_progresswalks the transcript at eachPostToolUseand again atStop, posting each new assistant entry'stext/thinkingblocks. Per-taskTask.posted_assistant_uuidsdedupes on entry uuid — cleared onUserPromptSubmitandSessionStart(new turn). The set lives in memory only; if the bridge restarts mid-turn, the new daemon may re-post entries already seen. Acceptable trade-off for the simpler design. - Stop hook fires before Claude flushes the final assistant entry.
_on_stopcalls_wait_for_transcript_stable(waits up to_STOP_TRANSCRIPT_RETRY_SECS, default 10s, for the file's size to stay constant for 250ms) before the final stream pass. Tests override the retry seconds to 0.0 when verifying static-transcript branches. - Edit / MultiEdit / Write get a fenced diff/content block alongside the one-liner summary.
tool_summary.diff_blockproduces the block;_post_tool_diffsends it as a separate Discord post (the aggregator coalesces summaries; diffs are individual messages). Bodies truncate at ~1920 chars to stay under Discord's 2000-char limit. - Subagent activity is collated into per-agent live-edited Discord embeds. Each subagent (Claude's
agentId) gets one embed (title = attribution, description = last 5 actions, footer = "running|finished · N actions · Ns", color = yellow→green) edited in place. Modern CC writes subagent activity to separate<session>/subagents/agent-*.jsonlfiles;_refresh_subagent_blocksscans them on each PostToolUse / Stop / SubagentStop, creates aSubagentBlockper file, andBot.edit_message(embed=…)updates the running embed. Edits are throttled to ~1.5s per block to stay under Discord's per-channel edit rate limit. PostToolUse events classified as sidechain (via_is_sidechain_tool, which also checks subagent files) are suppressed from the main aggregator. Blocks are cleared on UserPromptSubmit / SessionStart. - TodoWrite renders as a checklist alongside the one-liner summary.
tool_summary.diff_block("TodoWrite", input)formats thetodoslist into ✅/▶️/⬜ marks with content text;_post_tool_diffemits it as a separate Discord message after the aggregated summary line. Subagent TodoWrite calls only surface inside the subagent block as• 📋 TodoWrite: N/M done(no full checklist) to keep blocks compact. - Discord attachments are saved under
~/.local/state/claude-discord-bridge/attachments/<task_id>/and their absolute paths are appended to the relayed user message — one per line, no-bullet prefix (a leading dash is fatal tozellij action write-chars, see the zellij architecture entry). Claude reads them with theReadtool (which handles images, PDFs, JSON, plain text). Filenames are sanitized to basename and prefixed withmsg_idto avoid collisions. No size cap beyond Discord's own — large files just stream throughAttachment.read(). - Audio attachments are split off and transcribed before reaching the agent.
voice.transcribe()auto-selects a backend: ifWISPR_FLOW_API_TOKENis set it uses the Wispr Flow REST API (16kHz PCM WAV, base64-encoded,POST https://api.wisprflow.ai/transcribe); otherwise it shells out to a local CLI (defaultwhisperfrompip install -U openai-whisper, override binary viaBRIDGE_WHISPER_BIN, model viaBRIDGE_WHISPER_MODEL, defaultbase). Successful transcriptions become[voice memo] <text>blocks in the relayed prompt — they do NOT appear in the attached-files list. On failure (no backend, ffmpeg missing, CLI missing, HTTP error, timeout) we fall back to[voice memo received — transcription unavailable; raw file: <path>]so the user knows it didn't transcribe but the file is on disk. - Agent → Discord file attachments use the
[[attach: <path>]]marker. When a streamed assistanttextblock contains[[attach: /absolute/path]],_parse_attach_markersstrips the marker, resolves the path (must be absolute and exist), andBot.post_with_attachmentsuploads up to 10 files per Discord message alongside the cleaned text. Useful for screenshots / generated images / log dumps the agent wants to surface visually. Convention is not auto-injected into the agent — instruct claude per-conversation, or add the convention to the project's CLAUDE.md. - Attachment cleanup is paired with task-settings cleanup via
_cleanup_task_artifacts(task_id). Every lifecycle terminal (stop, kill, crash, archive) calls it so the two on-disk artifacts can't drift apart. In addition,sweep_old_attachments()runs at daemon startup and hourly, deleting any file older thanBRIDGE_ATTACHMENT_TTL_SECS(default 7 days) and removing the now-empty per-task dir. /renameauto-generates names by shelling out toclaude -p.TaskRegistry.generate_thread_namereads the first user prompt + first assistant response from the transcript, builds a short kebab-case naming prompt, and runsclaude -p <prompt>in a subprocess (30s timeout). Uses whatever auth/model the user'sclaudeCLI is configured with — no separate Anthropic API key needed. Empty stdout / non-zero exit → returns None and the slash command surfaces a "pass a name explicitly" error./restartuses--settings+--resume. The/restart <task-id>command spawns a new pane with bothclaude --settings <path>(to wire the task hooks) andclaude --resume <session_id>(to pick up from the prior session). Don't manually delete~/.claude/projects/...for a session the bridge is using.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 5d ago First seen · 63 lines · 3,977 tokens per session scan B da7ede0b643a
cc-discord CLAUDE.md is an instructions file published in the GitHub repository haileyok/cc-discord (5 stars, last pushed 13d ago), licensed MIT. It adds 3,977 tokens to every session, about $0.0199 per session on Opus 5. A static security scan graded it B with 2 findings (reads agent configuration directories, runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other instructions, from other repositories
open-code-review AGENTS.md
AGENTS.md instructions for alibaba/open-code-review, covering agent guidelines for open-code-review, project overview, git commit notes, license headers and code style.
eve AGENTS.md
AGENTS.md instructions for vercel/eve, covering agents.md, about eve, repository layout, git workflow and commands.
learn-harness-engineering CLAUDE.md
Instructions for walkinglabs/learn-harness-engineering, covering claude.md, project overview, commands, documentation site and run lecture code examples.
open-code-review CLAUDE.md
Claude Code instructions for alibaba/open-code-review: See AGENTS.md for all project guidelines.
trueforge AGENTS.md
AGENTS.md instructions for truefoundry/trueforge, a project described as: The open-source agent harness - the runtime layer that turns an LLM into a working agent.
dshcode copilot-instructions.md
Copilot instructions for whitelonng/dshcode, a project described as: Community desktop companion for DeepSeek Harness — one-click Electron app for macOS and Windows.