Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add instructions/windborne/zulipmcp/claude-mdgit clone --depth 1 https://github.com/windborne/zulipmcpWrote 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/windborne/zulipmcp/claude-md)<a href="https://agentmods.dev/instructions/windborne/zulipmcp/claude-md"><img src="https://agentmods.dev/badge/instructions/windborne/zulipmcp/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 | $0.00922 | $0.00922 |
| Opus 5 | $0.00461 | $0.00461 |
| Sonnet 5 | $0.00184 | $0.00184 |
| Haiku 4.5 | $0.00092 | $0.00092 |
Grade B, and why
zulipmcp CLAUDE.md scanned grade B with 1 finding 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 4d 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 MCP configurationmediumAgent snooping
mcp.json carries server URLs and auth tokens; reading it lets a mod discover and abuse other integrations.
- **Codex MCP config is not `.mcp.json` native.** The listener translates `.mcp.json` into Codex `-c mcp_servers...` overrides. Keep secrets in env/header fields; env refs in command/args/cwd/url must fail closed to avoi This is a copy
100% identical to zulipmcp CLAUDE.md — 0 lines differ, which has more behind it and is treated as the original. This page carries a canonical link to it rather than competing with it.
How it starts
The opening of the file, as written. The whole thing — 35 lines — stays where its author put it; the contents beside it link to each section on GitHub.
zulipmcp
Public open-source repo. All code, commits, and PRs are visible to the world.
Rules
- Nothing WindBorne-specific. No internal URLs, emails, Zulip instances, or infra references.
- No internal context in PRs, commits, or comments.
- Elegant, general code. Type hints everywhere. Minimal dependencies.
Architecture
core.py— Zulip API wrappers. No MCP dependency. Returns Python objects.mcp.py— MCP tool layer +SessionState. Thin wrappers overcore.py. Hooks system lives here.agent_backends.py— Claude/Codex/OpenCode command builders for the listener. No Zulip API dependency.hermes_plugin/zulip/— Native Hermes gateway transport. It does not use MCP session state.
Separation is load-bearing: core.py must stay MCP-agnostic so it works as a standalone library import.
Gotchas
listen()is async, everything else is sync. It runsget_events()in a thread executor to interleave MCP keepalive pings. Don't make other tools async — FastMCP handles sync tools fine.- Event queue narrow does NOT filter reactions.
is_dismiss_reaction()receives reactions from all streams — it fetches the reacted-on message to verify stream/topic. Don't remove that check. _sessionis module-level singleton. One session per process. Don't add multi-session — MCP is one-client-per-server.reply()checks for missed messages before sending. Thelast_seen_message_idbookkeeping is subtle — trace it carefully before changing.- Send tools enforce
MAX_MESSAGE_LENGTH. Zulip silently truncates over-limit messages and still reports success — the guard returns an error to the caller instead. It measures the normalized form (postnormalize_zulip_markdown()), since normalization can grow content. Override withZULIP_MAX_MESSAGE_LENGTHfor non-default realm caps. - Two dismiss-check paths exist intentionally.
listen()catches via events,reply()via REST poll. Both needed — user might react during tool execution (not listening). - Interrupt-file reads must go through
_consume_interrupt_file(). It claims via atomic rename before reading, so a writer replacing the file mid-consume can't have its content deleted unread — and it decodes witherrors="replace"so a bad-bytes file can't wedge every future poll. Don't inline a read+delete elsewhere. - Private stream security is asymmetric on purpose. Unset
BOT_ALLOWED_PRIVATE_STREAMS= no access (default-deny). UnsetBOT_ALLOWED_WRITE_STREAMS= all writes allowed (backwards-compat). Don't "fix" the asymmetry. configure()must be called beforerun_server().run_server()may auto-init a session that reads hook state.- Codex MCP config is not
.mcp.jsonnative. The listener translates.mcp.jsoninto Codex-c mcp_servers...overrides. Keep secrets in env/header fields; env refs in command/args/cwd/url must fail closed to avoid argv leaks. - OpenCode MCP config is not
.mcp.jsonnative. The listener translates.mcp.jsoninto inline JSON viaOPENCODE_CONFIG_CONTENT. Header values are embedded directly (no env-var indirection like Codex). Env refs in command/args/url are rejected. core.pysend paths (send_message/send_direct_message/edit_message) rewrite markdown vianormalize_zulip_markdown(). Blank lines are injected before tables and bold/link combos Zulip breaks on are rewritten. Fenced/indented code is exempt from both fixes; inline code spans are exempt only for the bold/link rewrite. The Hermes gateway adapter sends via the raw client and is NOT normalized.ZULIPMCP_MARKDOWN_AUTOFIX=0disables all of it.remove_reaction()needs explicitreaction_typefor custom emoji. Zulip's DELETE reactions endpoint defaultsreaction_typetounicode_emoji— custom emoji removals fail silently without it. The listen indicator caches_listen_reaction_typealongside_listen_emoji; always pass both when removing.
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.
- 4d ago First seen · 35 lines · 922 tokens per session scan B 0d401fa52144
zulipmcp CLAUDE.md is an instructions file published in the GitHub repository windborne/zulipmcp (0 stars, last pushed 1mo ago), licensed Apache-2.0. It adds 922 tokens to every session, about $0.0046 per session on Opus 5. A static security scan graded it B with 1 finding (reads mcp configuration). It is 100% identical to zulipmcp CLAUDE.md, differing in 0 lines, and is treated as a copy.
Other instructions, from other repositories
next.js AGENTS.md
AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.
codex AGENTS.md
AGENTS.md instructions for openai/codex, covering rust/codex-rs, the codex-core crate, code review rules, crate api surface and model visible context.
vscode buildNext.instructions.md
Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).
spec-kit AGENTS.md
AGENTS.md instructions for github/spec-kit, covering agents.md, about spec kit and specify, quickstart — add a new integration in 5 steps, integration architecture and integrationmanifest — file tracking.
langchain AGENTS.md
AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.
vscode oss-third-party-notices.instructions.md
Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, applying the notice (cutover) and fallback chain (never fail the build).