10月1日、claude.devが「Getting started with Claude Code mods / claude.dev Blog」と題した記事を公開した。この記事では、Claude Codeに独自のUIやロジックを組み込める「Mods」機能の仕組みと、実際に約80行のモジュールを一から作る手順について詳しく紹介されている。たとえば、コンテキストウィンドウの残量を「天気予報」として常時表示するToken Weatherのように、CursorやGitHub Copilotでは難しいセッション常駐型のカスタムUIを、TypeScript数十行で実現できる点がModsの最大の特徴だ。
なぜ今Modsが重要なのか
Claude Codeはここ数か月でエコシステムを急速に拡張している。設定ファイル、スラッシュコマンド、スキルといった既存のカスタマイズ手段に加え、Modsはその最上位レイヤーとして位置づけられる。
CursorやGitHub Copilotのような競合AIコーディングツールもプラグイン機構を持つが、それらはあくまで「エディタ拡張」という形態だ。ModsはClaude Code本体のイベントループに直接フックし、セッションに常駐しながらUIを書き換えるという設計で、よりAIエージェントの動作そのものに近い位置で介入できる。Claude Code自身の機能の一部(AGENTS.mdサポートや/diffペイン)もModsとして実装されており、そのソースはanthropics/claude-codeのmods/以下で公開されている。この事実は、Modsが「外付けプラグイン」ではなく、Claude Codeのコアアーキテクチャとして設計されていることを示している。
Claude Code Modsとは何か
ModsはClaude Codeのイベント処理を書き換え・差し替えできるうえ、カスタムUIの描画まで行える。フック(hook)をJavaScriptまたはTypeScriptモジュールとして実装し、プラグインとして配布するという構造だ。各フックはセッション中に常駐し、ツール呼び出し・プロンプト送信・ターン開始/終了・スラッシュコマンドといったあらゆるイベントをリアルタイムに捕捉できる。
on("tool.call", { tool: "Bash" }, async ($, e, next) => {
// $ Mods API: ui, session, state, store, fs, process, clock, http, tool, command, model, ...
// e このイベントの入力(プレーンなデータ)
// next イベントを次のプラグインとClaude Code本体に渡す
return next(e);
});
フックはミドルウェア的なチェーンを形成する。一つのフックでできることは3種類だ。
| 操作 | 方法 | 用途例 |
|---|---|---|
| 観察(Observe) | next(e)を呼び、結果を見る |
ファイル編集の記録、ターン後の数値取得 |
| 書き換え(Rewrite) | 変更したデータでnext(e)を呼ぶ |
より安全なコマンドへの差し替え |
| 代替応答(Answer) | nextを呼ばず結果を返す |
ツール呼び出しの拒否、自前のコマンド実装 |
設定ファイルで使う「settings hooks」との大きな違いは、Modsはセッションに1回ロードされて常駐する点だ。状態を保持し、UIをリアルタイムに更新し、Claude Code本体のペインを開いたり、モデルが呼べるツールを登録したりできる。settings hooksはあくまでイベントごとに外部プロセスを呼び出す仕組みであり、セッションをまたいだ状態管理やUI描画は担えない。
最初のMod:Token Weather
記事が最初の実例として取り上げているのがToken Weatherだ。コンテキストウィンドウの使用率をターンごとに読み取り、プロンプト上部に1行のバンドとして表示する。約80行のモジュールで動作する。コンテキスト枯渇による突然のセッション中断は多くの開発者が経験する問題であり、使用率を「天気」として視覚化するこのアイデアは実用性とユーモアを兼ね備えている。
表示内容は次のとおり。
| 使用率 | 天気 |
|---|---|
| 25%未満 | ☀ Clear(黄) |
| 25〜49% | ☁ Cloudy(シアン) |
| 50〜74% | ☂ Showers(青) |
| 75〜89% | ☇ Storm(マゼンタ) |
| 90%以上 | ↯ Compact soon(赤) |
加えて、使用トークン数(例: 134.4k / 200k)、直近12ターンのスパークライン(▁▂▃▄▅▆▇█)、最後のターンで増えたトークン数(例: ▲ +98.3k last turn)も表示される。
最速の始め方:Claudeに作らせる
手順を全部スキップする方法が最初に紹介されている。Claude Codeはモジュールの書き方を知っているため、以下のプロンプトを貼り付けるだけでToken Weatherを生成できる。
Make me a Claude Code mod called token-weather: a live forecast of my context window, shown in the band above the prompt.
(以下、表示内容の仕様を記述)
セッションでホットリロードを許可すると、ターンが終わるたびに即座にバンドが更新される。変更も「Stormは70%から始めて」と伝えれば即反映される。
自分で書く場合の要点
自分で実装する場合、記事は6ステップで構成を説明している。エンジニアとして特に押さえておくべきポイントを以下に整理する。
フォルダ構成と必須ファイル
token-weather/
├── .claude-plugin/
│ ├── plugin.json # プラグインマニフェスト
│ └── types/ # Claude Codeがロード時に生成
├── hooks/
│ ├── hooks.json # モジュールを指定
│ └── token-weather.mjs
├── types/
│ └── index.d.ts # 型コントラクト(省略不可)
└── tests/
└── token-weather.test.ts
起動はclaude --plugin-dir ./token-weather。フォルダが監視されているため、ファイルを保存するたびにモジュールが再ロードされ、再起動不要でフィードバックを得られる。
状態の持ち方:$.stateを使う理由
モジュール変数(let readings = [])は一見自然だが、ホットリロード時にリセットされてしまう。履歴などセッションをまたいで保持したいデータは$.stateに置くのが正しい。$.stateの値はホスト側が保持するため、リロードを越えて生き残る。
また、レンダーフック内で$.state.getを呼ぶと自動的にサブスクリプションが張られ、$.state.setを呼ぶたびにUIが自動再描画される。**$.ui.invalidateを手動で呼ぶ必要はない。**
型コントラクトの宣言
$.stateに値を格納するには、types/index.d.tsでその型をPluginStateインターフェースに宣言しなければならない。省略するとclaude plugin validateがエラーで止まり、修正箇所を具体的に示してくれる。
UIの描画
プロンプト上部のバンドはAbovePromptコンポーネントに対してui.renderイベントをフックして描画する。要素の構築には$.ui.resolve(e)で取得したコンストラクタを使う。JSXもhファクトリ経由でサポートされている。
より高度な実装例
記事はToken Weatherに続いて、Blast Radius(Bashコマンドの実行前にどのファイルが影響を受けるかを表示するガード)とReplay Theater(セッション全体の変更履歴を振り返るレビュービュー)という2つの大規模なModも紹介している。これらはAPIがどこまでできるかの参考として示されており、「観察」「書き換え」「代替応答」の3操作を組み合わせれば、単純なUIウィジェットから実行ガードやセッション分析ツールまで幅広く実装できることがわかる。
動作にはClaude Code 2.1.287以降が必要。Modsはデフォルト有効で、追加設定は不要だ。型定義はロード時にmod側の.claude-plugin/types/へ自動生成されるため、常にそのバージョンのAPIが正の情報源となる。
詳細はGetting started with Claude Code mods / claude.dev Blogを参照していただきたい。