> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# mods API を使用する

> Claude Code mod から mods API を呼び出して、コマンドとツールを追加し、モデルを呼び出し、タイマーで作業を実行し、他のセッションにメッセージを送信し、ファイルとネットワークにアクセスします。

mods API は、mod が動作するために呼び出すメソッドのセットです。コマンドとツールを追加し、モデルを呼び出し、イベント間で作業を実行し、ファイルシステム、プロセス、ネットワークにアクセスします。すべてのフックは、最初の引数として `$` を受け取り、メソッドは `$.ui` や `$.fs` などの名前空間でグループ化されています。[Events](/docs/ja/plugins/mods/events) はフックが実行されるタイミングを決定し、mods API はフックが実行されたときに呼び出すものです。

[最初の mod を作成](/docs/ja/plugins/mods/create) してからここを開始してください。すべてのメソッドについては、[mods API メソッド](/docs/ja/plugins/mods/reference#mods-api-methods) を参照するか、[ビルド用の型](/docs/ja/plugins/mods/create#get-the-types-for-your-build) を読んでください。

<h2 id="add-a-command-or-a-tool">
  コマンドまたはツールを追加する
</h2>

mod はユーザーが実行するコマンドと Claude が呼び出すツールを追加できます。両方を [`session.start`](/docs/ja/plugins/mods/reference#session) フックに登録します。Claude Code はそのフックを最初のプロンプトの前に待つため、登録したものは最初のターンから利用可能です。

<h3 id="add-a-command">
  コマンドを追加する
</h3>

コマンドはユーザー向けです。登録してから、その名前の [`command.run`](/docs/ja/plugins/mods/reference#commands-and-configuration) を処理します。この例は、オプションの日数を取る `/standup` コマンドを追加します。

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // /standup をコマンドリストに追加し、ユーザーがそこで見る説明を付ける
  await $.command.register({ name: 'standup', description: 'Summarize what changed today', argumentHint: '[days]' })
  return next(e)
})

// マッチャーはフックを /standup に制限するため、他のコマンドは到達しない
on('command.run', { command: 'standup' }, async ($, e) => {
  // e.args はコマンド名の後に入力されたテキスト、または空の文字列
  return { text: 'Summary for the last ' + (e.args || '1') + ' day(s): ...' }
})
```

セッションが開始した後、`/standup` はその説明とともに `/` を入力したときに表示されるリストに表示されます。`argumentHint` は、コマンドを入力してスペースを入力した後、プロンプトに `/standup [days]` として表示されます。`/standup 3` を実行すると、2 番目のフックは `Summary for the last 3 day(s): ...` を返し、トランスクリプトはプラグイン名の後にそのテキストを表示します。フックは `next` を呼び出しません。コマンドはあなたのもの以外に動作がないためです。

返す `text` はトランスクリプトに出力され、Claude がそれを読みます。何も出力しない場合、[ペイン](/docs/ja/plugins/mods/interface#pick-where-to-draw) を開くだけのコマンドの場合は、`{}` を返します。Claude が作業中にコマンドを実行できるようにするには、登録に `immediate: true` を追加します。

組み込みコマンドが使用していない名前を選択してください。セッションで `/` を入力して、それらを確認してください。`$.command.register` は、`"/focus" refused: it is the built-in /focus` などのメッセージで、取得された名前に対してスローします。スローするフックはスキップされるため、その `session.start` フックの残りも実行されません。そのフックの最後にコマンドを登録するか、呼び出しを `try` と `catch` でラップします。

<h3 id="add-a-tool">
  ツールを追加する
</h3>

ツールは Claude 向けです。名前、Claude が読む説明、入力用の JSON Schema で登録します。Claude は、`mcp__`、プラグイン名、2 つのアンダースコア、登録した名前で構成される長い名前の下にそれを見ます。その呼び出しを、その完全な名前にフィルタリングされた [`tool.call`](/docs/ja/plugins/mods/events#guard-or-change-a-tool-call) フックで処理します。この例は、`my-mod` という名前のプラグインから、`ticket` を登録するため、完全な名前は `mcp__my-mod__ticket` です。Claude に問題追跡ツールでチケットを検索するツールを提供します。

```javascript theme={null}
on('session.start', async ($, e, next) => {
  await $.tool.register({
    name: 'ticket',
    // Claude はこの説明からツールを呼び出すタイミングを決定する
    description: 'Look up a ticket by its id and return its title and status',
    // Claude が送信する必要がある引数：id という名前の 1 つの必須文字列
    inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
  })
  return next(e)
})

// 完全なツール名は mcp__、プラグイン名、登録された名前
on('tool.call', { tool: 'mcp__my-mod__ticket' }, async ($, e) => {
  // ツールの引数は e のフィールドなので、id は e.id
  const response = await $.http.fetch('https://tickets.example.com/api/' + encodeURIComponent(e.id))
  // どちらの場合でも結果を返すため、Claude は検索が失敗したときに学習する
  return { result: response.ok ? response.text : 'Lookup failed with status ' + response.status }
})
```

チケットについて質問すると、Claude は `mcp__my-mod__ticket` をその id で呼び出すことができます。2 番目のフックはチケットを取得し、応答本文を返します。Claude はそれをツールの結果として読みます。サーバーがエラーステータスで応答すると、Claude は `Lookup failed with status` と数字を読みます。

<h2 id="call-a-model">
  モデルを呼び出す
</h2>

mod は、テキストの並べ替えや要約などの小さなジョブのために、会話の外で独自にモデルに質問を尋ねることができます。`$.model.complete` はセッションの認証情報を使用して 1 つのプロンプトをモデルに送信し、返信に解決します。会話履歴はありません。

このフックは、[コマンドとして登録された](#add-a-command) `/triage` コマンドに答え、小さなモデルに、その後に入力されたテキストにラベルを付けるよう尋ねます。

```javascript theme={null}
on('command.run', { command: 'triage' }, async ($, e) => {
  const r = await $.model.complete({
    model: 'haiku',
    // システムプロンプトはジョブを設定し、プロンプトはラベル付けするテキストを運ぶ
    system: 'Reply with one word: bug, feature, or question.',
    prompt: e.args,
    // 1 語は少数のトークンが必要で、呼び出しは 15 秒後にあきらめる
    maxTokens: 20,
    timeoutMs: 15000,
  })
  // r.text は、モデルが応答したときのみ存在するため、最初に r.isAnswered をチェック
  const label = r.isAnswered ? r.text.trim() : 'unknown'
  return { text: 'Label: ' + label }
})
```

`/triage the export button does nothing` を実行すると、mod はそのテキストをモデルに送信し、その答え（`Label: bug` など）を出力します。Claude の会話は要求の一部ではありません。モデルが応答しない場合、ラベルは `unknown` です。

Claude API の失敗は呼び出しを拒否しないため、`r.isAnswered` をチェックし、それが `false` の場合は `r.reason` を読んでください。呼び出しは、Claude Code が送信しない要求（組織がブロックするモデルなど）に対してのみ拒否します。[ビルド用の型](/docs/ja/plugins/mods/create#get-the-types-for-your-build) は、`effort` などの他のオプションをリストし、[制限](/docs/ja/plugins/mods/reference#limits) は `maxTokens` のデフォルトを示します。

`$.model.fork({ prompt })` は、代わりに現在の会話に 1 つの質問を尋ね、同じモデルとシステムプロンプトを使用するため、Claude API はプロンプトキャッシュからほとんどを提供します。

これらの呼び出しはユーザーのプランまたは API キーを使用します。

<h2 id="run-work-in-the-background">
  バックグラウンドで作業を実行する
</h2>

1 つのイベントを超える作業（1 分ごとに何かをチェックするなど）は、`session.start` から開始するタイマーで実行されます。フック自体は 1 つのイベントに対して実行され、独自の実行時間の 10 秒の時間制限があります。`next` または mods API 呼び出しで費やされた時間はカウントされません。ただし、`$.clock.sleep` は例外です。`$.clock.every` と `$.clock.after` は `setInterval` と `setTimeout` の代わりになり、遅延はミリ秒で最初に来ます。`$.clock.after(5000, fn)` は `fn` を 1 回呼び出し、今から 5 秒後です。各々はタイマーを返し、`cancel()` メソッドを持ち、`await $.clock.now()` はミリ秒単位の時間を与えます。

このフックはプルリクエストのチェックを 1 分ごとに検索し、プロンプトの下に結果を表示します。`summarize` はコマンドの JSON 出力を数語に変換する独自の関数です。

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // 60,000 ミリ秒ごとに関数を呼び出し、今から 1 分後に開始
  $.clock.every(60_000, async () => {
    const status = await $.process.run(['gh', 'pr', 'checks', '--json', 'state'])
    // プロンプトの下の行を最新の要約に置き換える
    $.ui.status('checks: ' + summarize(status.stdout))
  })
  // タイマーを待たずに戻るため、セッションはすぐに開始される
  return next(e)
})
```

セッションは通常どおり開始されます。1 分後、プロンプトの下に `⚠`、mod の名前、その後 `checks:` とあなたの要約を含む行が表示されます。その後、1 分ごとに置き換えられます。タイマーのコールバックはイベント外で実行されるため、ターン間で実行され続け、ターンを開始しません。コールバックがスローする場合、エラーは [デバッグログ](/docs/ja/plugins/mods/troubleshoot#read-the-debug-log) に移動し、タイマーは次の間隔で再度実行されます。

<h3 id="show-something-without-starting-a-turn">
  ターンを開始せずに何かを表示する
</h3>

バックグラウンドジョブは、ターンを開始せずにユーザーに何かを表示できます。これらの各呼び出しは、異なる場所にテキストを配置します。

| 呼び出し | ユーザーが見るもの |
| :- | :- |
| `$.ui.status(text)` | プロンプトの下の 1 行で、変更するまで残ります。`⚠` と mod の名前で始まります。`⚠ my-mod: checks: 3 passing` など。 |
| `$.ui.toast(text)` | 右上の小さなボックスで、mod の名前がテキストの上にあり、数秒後に消えます |
| `$.ui.log(text)` | Claude が読まない、トランスクリプト内の薄い行。`●` と mod の名前で始まります。`● my-mod: build finished` など。 |

<h3 id="start-a-turn-from-a-background-job">
  バックグラウンドジョブからターンを開始する
</h3>

バックグラウンドジョブが Claude の注意が必要なものを見つけた場合、`$.prompt.submit({ text })` でプロンプトを送信してターンを開始できます。Claude は、送信者として mod に名前を付ける文の後にテキストを読みます。ユーザー自身の言葉として送信するには、その文なしで、`asUser: true` を追加します。呼び出しはセッションがアイドル状態になるまで待機してから、新しいターンを開始します。そのターンが開始されたときに解決するため、Claude が作業中に実行されるハンドラーで `await` しないでください。

<h3 id="stop-background-work">
  バックグラウンド作業を停止する
</h3>

バックグラウンド作業は 2 つの方法で停止します。モジュールが再読み込みされるとタイマーが停止します。フック内の長時間実行作業の場合、[`next.signal`](/docs/ja/plugins/mods/reference#the-hook-function) は `AbortSignal` で、フックが処理しているイベントが放棄されたときに中止されます。たとえば、ユーザーが割り込むと、長時間実行されるものに渡します。

<h2 id="send-and-receive-messages-between-sessions">
  セッション間でメッセージを送受信する
</h2>

mod は、別のセッションまたはこのセッションのサブエージェントの 1 つにプレーンテキストメッセージを送信し、到着して離れるメッセージを観察できます。`$.session.send({ to, text })` は 1 つを送信し、SendMessage ツールが行う配信と同じです。`to` は、セッションの場合は `{ sessionId }`、`$.agent.list()` からのサブエージェントの場合は `{ agentId }`、または受信したメッセージが来たアドレスです。呼び出しはメッセージがキューに入ったら解決し、`{ isDelivered: true }` で解決します。何も配信されなかった場合、`{ isDelivered: false, reason }` で解決し、`reason` は理由を述べます。

このフックは、[コマンドとして登録された](#add-a-command) `/ping` コマンドに答え、その後に入力したセッション ID のセッションにステータスを尋ねます。

```javascript theme={null}
on('command.run', { command: 'ping' }, async ($, e) => {
  // e.args は /ping の後に入力されたセッション ID
  const sent = await $.session.send({ to: { sessionId: e.args }, text: 'Status? One line.' })
  // 呼び出しはどちらの場合でも解決するため、isDelivered をチェックして何が起こったかを学習
  if (!sent.isDelivered) $.ui.toast('Not delivered: ' + sent.reason)
  // 空の結果はこのセッションのトランスクリプトに何も出力しない
  return {}
})
```

メッセージがキューに入ると、セッションに何も表示されず、他のセッションの Claude は `Status? One line.` を読みます。何も配信されなかった場合、右上の小さなボックスが理由を示し、数秒後に消えます。

2 つのイベントにより、mod はメッセージを観察できます。両方から `next(e)` を返して、各メッセージを変更されずに渡します。

| イベント | 発火するタイミング | 有用なフィールド |
| :- | :- | :- |
| `session.receive` | メッセージがこのセッションに到着し、Claude がそれを読む前 | `e.text`、および `e.origin.kind`（別のセッションまたはエージェント、`task-notification`、または `scheduled-trigger` の場合は `peer` または `peer-send-message` など）。`{ consumed: reason }` を返して Claude から保持します。 |
| `session.send` | メッセージが SendMessage ツールまたは mod から離れようとしている | `e.to`、`e.text`、および `e.origin.kind`（`model` または `plugin`） |

[インバウンドメッセージを拒否](/docs/ja/cross-session-messaging#control-inbound-messages) するように設定されたセッションは、`session.receive` が発火する前にメッセージを拒否するため、フックはそれを見ません。承認待ちのメッセージはフックに最初に到達するため、mod はまだ承認していないメッセージを読むことができます。フックの `next(e)` はメッセージが配信されないときに拒否します。

受信したメッセージの送信者の名前は、送信者が書いたものなので、それに基づいて決定しないでください。

<h2 id="reach-files-processes-and-the-network">
  ファイル、プロセス、ネットワークにアクセスする
</h2>

mod は、Claude Code を実行しているユーザーと同じ権限で、mods API を通じてファイルシステム、プロセス、ネットワークにアクセスします。フックモジュール自体には Node.js API、`setTimeout` などのタイマーグローバル、独自のネットワークまたはファイルアクセスはありません。`URL`、`TextEncoder`、`AbortController`、`crypto.subtle` などの標準 JavaScript および Web API が利用可能です。以下の各名前空間は、1 種類のアクセスをカバーしています。

| 名前空間 | 何をするか |
| :- | :- |
| `$.fs` | `read(path)`、`write(path, text)`、`exists(path)`、`stat(path)`、`list(path)` はファイルとディレクトリで動作 |
| `$.process` | `run(['git', 'status'])` はコマンドを開始し、終了時に解決。`spawn` は長時間実行コマンドの出力をストリーム。 |
| `$.http` | `http` または `https` 上の `fetch(url, init)`。本文が読み込まれたら `{ status, ok, headers, text }` に解決。 |
| `$.store` | プラグイン独自の JSON キー値ストア、セッション間で保持 |
| `$.env` | 環境変数を `get` および `set`。名前をリテラル文字列として記述。 |
| `$.settings` | 設定ファイルと管理ポリシーが保持するものを `read` |
| `$.session` | `messages()` はトランスクリプトを `{ role, text, toolUses }` のリストとして返す。また、作業ディレクトリ、モデルなど。[`usage()`](/docs/ja/plugins/mods/reference#mods-api-methods) はコンテキストウィンドウの使用とプラン制限を返す。 |
| `$.mcp` | 接続された MCP サーバーのツールを `call` |

ファイルとプロセスには、独自のいくつかのルールがあります。

* **パス**：相対パスはセッションの作業ディレクトリの下
* **`$.fs.list`**：1 つのディレクトリのエントリを `{ name, kind, size, isLink }` として返し、サブディレクトリに下降しない
* **`$.process.run`**：引数リストを取り、シェルを使用しない。終了コードに関係なく `{ exitCode, stdout, stderr }` に解決。プログラムが開始できないか、タイムアウト時にまだ実行中の場合は拒否します。デフォルトは 30 秒なので、`try` と `catch` でラップします。

これらの呼び出しのそれぞれは、それ自体がイベントであり、`$.fs.read` の場合は `fs.read` など、`$.` なしで名前空間とメソッドに対して名前が付けられています。[チェーンの前にある](/docs/ja/plugins/mods/events#the-order-mods-run-in) mod は、呼び出しを観察、書き直し、または拒否できます。これは、組織が mod が到達するものを制限する方法です。

<h2 id="next-steps">
  次のステップ
</h2>

* [イベントに反応する](/docs/ja/plugins/mods/events)：ツール呼び出し、プロンプト、ターンをフック
* [インターフェイスに描画する](/docs/ja/plugins/mods/interface)：mod が収集するものをペインまたはプロンプトの上に表示
* [mod をテストする](/docs/ja/plugins/mods/test)：テストでこれらの呼び出しのいずれかをスタブ
* [Mods リファレンス](/docs/ja/plugins/mods/reference)：すべてのイベント、すべての mods API メソッド、制限
