Attributed compile (not original research)
Primary source: Getting started with Claude Code mods by Addy Osmani (claude.dev), published 2026-10-01
Secondary roundup: Anthropic Launches Claude Code Mods, TypeScript Agent Hooks (AI Weekly), published 2026-10-02
This post restates Anthropic’s Claude Code Mods launch packaging in my own words, with a builder checklist for first hooks and install hygiene. I did not run Claude Code Mods for this article. Hook shapes, example mods, version floors, and trust claims below are vendor-reported (or clearly attributed to the named secondary source). Code snippets adapt the public API patterns from Osmani’s guide — not a dump of the full sample modules.
Anthropic shipped Claude Code Mods on October 1, 2026. Per Osmani’s guide, a mod is a small JavaScript or TypeScript module that lives inside a plugin, registers hooks into Claude Code’s event loop, and can rewrite prompts, hold or deny tool calls, approve or refuse permissions, redact secrets, and draw or replace UI. Claude Code 2.1.287+ is the floor; mods are on by default.
That last detail is the product decision. You are not opting into a toy extension API. You are sitting on a middleware layer that already powers first-party features — and that runs with the same machine reach as Claude Code itself.
What a mod actually is (middleware, not a settings shell)
Osmani frames mods as hooks that ship inside plugins. The folder is a normal plugin (.claude-plugin/plugin.json). hooks/hooks.json points at one module under modules. That module exports register(on, options), and inside it you attach handlers with on(event, matcher?, hook).
Every hook shares one shape (API pattern from Osmani’s post):
on("tool.call", { tool: "Bash" }, async ($, e, next) => {
// $ = mods API (ui, session, state, fs, process, …)
// e = this event's plain data
// next = pass e down the chain to other mods / Claude Code
return next(e);
});
Hooks chain like Express middleware. The first-loaded mod sees the event first and the result last — AI Weekly restates the same load-order rule from Anthropic’s packaging. Inside a hook you pick one of three moves:
| Move | Pattern | Typical use |
|---|---|---|
| Observe | const r = await next(e); /* inspect */; return r |
Log edits, meter context, build a replay |
| Rewrite | return next({ ...e, command: safer }) |
Change what the rest of the chain sees |
| Answer |
return { deny: "…" } without calling next
|
Refuse a tool call; serve a command yourself |
Events cover tool calls, prompt submit, turn start/finish, session lifecycle, slash commands, and ui.render. Osmani notes the module itself has no DOM and no Node — everything outside goes through $. That is not the same as “sandboxed from your laptop.” $ exposes fs, process, http, and friends. Treat install like npm: trusted source or skip.
First-party features are already mods
Claude Code dogfoods the system. Osmani says AGENTS.md support and the /diff pane beside the conversation ship as mods; their sources live under mods/ in the public anthropics/claude-code repo. AI Weekly adds that Team/Enterprise plans load a built-in sec-default mod first, aimed at blocking risky overrides of permission denials.
Practical takeaway: if Anthropic’s own UX is a mod, your team’s conventions, cost meters, and Bash guards belong in the same layer — not as one-off shell hooks that restart on every event.
Three example mods (vendor demos, not my harness)
Osmani walks three public demos. I am summarizing behavior only; numbers and line counts are from the guide.
-
Token Weather (~80 lines) — After each main-loop turn, reads
$.session.usage(), keeps history in$.state, and draws a one-line forecast in theAbovePromptband (Clear → Cloudy → Showers → Storm → Compact soon). Teaching point: hot reload wipes module variables; put session history in$.state. -
Blast Radius — On risky
Bash(rm -rf,git reset --hard, force push, migrations, …), classifies the command, dry-runs impact via$.process.run, opens a Proceed/Cancel pane, and eithernext(e)or returns{ deny: "…" }. Teaching point: the Answer move is how you hold a call without rewriting Claude Code. -
Replay Theater — Observes Edit/Write calls, registers
/replay, and steps diffs in a pane. Teaching point: observe-only mods never calldeny; they pairturn.start/turn.completeand filter out subagents viae.agentId.
If you only build one thing this week, build a Blast Radius–style guard tuned to your stack (production kubectl contexts, terraform apply, drop-table SQL). Permission rules are still the hard block; Blast Radius is a safety net that reads command text and can miss $(…), aliases, and nested scripts — Osmani says that explicitly.
Minimal Blast Radius core (adapted pattern)
The heart of holding Bash is the Answer move. Adapted from Osmani’s Blast Radius sketch (not the full module):
on("tool.call", { tool: "Bash" }, async ($, e, next) => {
const risk = classify(String(e.command ?? ""));
if (risk === null) return next(e); // safe path: pass through
// measure($, …) dry-runs via git status / git clean -n / du, etc.
const report = await measure($, risk, await $.session.cwd());
const decision = await askUser($, report); // pane or AbovePrompt band
if (decision === "proceed") return next(e);
return {
deny: `Held by Blast Radius: ${report.summary}`,
};
});
Validate with claude plugin validate ./your-mod before you share it. Osmani’s guide shows the validator listing hooks, $ calls, and declared PluginState keys — fail closed on undeclared state.
Install path and the trust model
Shipping is the existing plugin channel. From Osmani:
/plugin marketplace add your-org/my-mods
/plugin install token-weather@your-mods
/reload-plugins
Claude directory submissions go through claude.ai/directory/manage. Hot reload watches the folder in a session started with --plugin-dir; Claude may ask once to enable it.
Trust is the feature, not a footnote. AI Weekly quotes Anthropic bluntly: mods run with the same access to your machine as Claude Code; they are not sandboxed; install only sources you trust. Osmani’s share section says the same in packaging language — publisher code, not Anthropic-signed isolation. sec-default helps Team/Enterprise at the front of the chain; it does not make a random marketplace plugin safe.
Shortcut Osmani highlights: describe the mod to Claude Code and let it scaffold the plugin. You still own the review of what it wrote before /plugin install hits a shared machine.
Builder checklist (this week)
-
Upgrade to Claude Code 2.1.287+ and confirm
claude --version. - Do not mass-install marketplace mods until you have a trusted-source list (internal org marketplace first).
-
Scaffold one observe mod (Token Weather–style) so you learn
$.state+ui.render/AbovePromptwithout touching Bash. - Scaffold one Answer mod (Blast Radius–style) for the three commands your team fears most; keep permission rules as the hard deny.
-
Run
claude plugin validateand at least oneclaude plugin testbefore sharing. -
Prefer
$.stateover modulelet— hot reload re-runsregisterandsession.start. -
On Team/Enterprise, confirm
sec-defaultis loaded first; document whether local users can dilute it (AI Weekly flags this as an open admin question). -
Review any mod Claude writes for you the same way you review a PR that gets
fs+process.
Why this post exists
Coding agents are becoming extension hosts. Mods make Claude Code’s loop a public middleware surface: rewrite, hold, redraw. The durable skill is not memorizing AbovePrompt — it is treating install hygiene as part of agent security, and shipping one guard that matches your blast radius before the directory fills with convenience plugins.
Byline: YongBo Yu — Toronto AI engineer (agents, LLM workflows). GitHub: YongBoYu1.
Top comments (0)