Claude Code plugin hintsで自作CLIに公式プラグインを推薦させる
Claude Codeはstderrに書かれた1行のマーカーを読み取り、CLIやSDKの利用者へ公式プラグインのインストールを提案します。実装手順と、提案が出ない条件までを扱います。
Claude Code plugin hintsで自作CLIに公式プラグインを推薦させる
CLIやSDKを保守していて、Anthropicの公式マーケットプレイスに自分のプラグインを持っているなら、そのツール自身からClaude Codeの利用者にインストールを提案できます。plugin hintsと呼ばれるこの仕組みは、CLIがstderrに1行のマーカーを書き出すだけで動きます。追加のコマンドは要らず、Claude Code以外の場所で実行したときの出力は変わりません。
plugin hintsは何をする仕組みか
plugin hintsは、CLIが自分の実行環境をClaude Code内だと検知したときに、<claude-code-hint />という自己閉じタグをstderrへ書き出すプロトコルです。Claude Codeはこの行をBashツールとPowerShellツールの出力から取り除き、モデルに見せる前に、ユーザーへ1回限りのインストール提案を出します。
対象になるのは、公式マーケットプレイスに載っているプラグインです。公式と数えられる名前はclaude-plugins-officialのほか、claude-code-marketplace、anthropic-marketplace、agent-skills、knowledge-work-pluginsなど十数個あります。コミュニティ向けのclaude-communityはこの一覧に入らず、ヒントを出しても提案にはなりません。
Claude Codeは、コマンド出力を受け取ると次の順で処理します。
ヒント行が提案になるまで
- 1
ヒント行を探して取り除く
Claude Codeはコマンド出力からタグの行を見つけ、モデルに渡す前に取り除きます。
vやtypeが未対応の値でも、行は取り除かれます。 - 2
プラグインを調べる
valueが指すプラグインを調べます。対象になる条件は、後の「提案が出ない条件」にまとめています。 - 3
表示してよい状況か判定する
対話セッションか、分析が有効か、頻度の上限に達していないかなどを調べます。条件は後の「提案が出ない条件」にまとめています。
- 4
発行元のコマンド名を添えて提案する
すべて通ると、ユーザーにインストール提案を表示します。Claude Codeがプラグインを自動で入れることはなく、入れるかどうかはユーザーが選びます。
この仕組みが埋めるのは、自分のCLIに対応プラグインがあることを利用者がそもそも知らないという発見のギャップです。CLIとプラグインを別々に案内していると、Claude Code内でツールを使っている最中の利用者には届きにくくなります。plugin hintsは、その案内を実行が生む出力に埋め込みます。
ヒントをstderrへ出力する
ヒントが効くのは公式マーケットプレイスに掲載済みのプラグインだけです。掲載の経路は後半の「公式マーケットプレイスへの掲載」で扱います。
出力は、環境変数でゲートを掛け、タグを単独の行としてstderrへ書きます。人間が直接CLIを実行したときにマーカーが出ないようにするための条件分岐です。ゲートに使える変数は2つあり、設定される範囲が違います。
どちらの環境変数でゲートするか
CLAUDECODE
すべてのClaude Codeバージョンで設定されます。Bash・PowerShellツール、tmuxセッション、hook・statuslineのコマンド、stdioのMCPサーバーのサブプロセスが対象です。IDE拡張の統合ターミナルでも設定されるため、人間が自分でCLIを実行した場面でもタグが出ます。
CLAUDE_CODE_CHILD_SESSION
Claude Codeが起動したサブプロセス(Bash・PowerShell・Monitorツール、hook、statuslineのコマンド)にだけ設定され、IDEの統合ターミナルには設定されません。stdioのMCPサーバーのサブプロセスにも設定されません。v2.1.172以降が必要で、それ以前のバージョンのセッションでは届きません。
CLAUDE_CODE_CHILD_SESSIONには癖もあります。screenのセッションや、Claude CodeのBashツールから最初に起動した常駐プロセスは、この値を引き継ぎます。そこで起動した通常のセッションが、入れ子のセッションと誤判定されることがあります。tmuxの場合はv2.1.178から自動で見分けられます。
次の例は、最も広く届くCLAUDECODEをゲートに使い、claude-plugins-officialにあるexample-cliというプラグインのヒントを出力します。
if (process.env.CLAUDECODE) {
process.stderr.write(
'<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',
)
}import os, sys
if os.environ.get("CLAUDECODE"):
print(
'<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />',
file=sys.stderr,
)if os.Getenv("CLAUDECODE") != "" {
fmt.Fprintln(os.Stderr,
`<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />`)
}if [ -n "$CLAUDECODE" ]; then
printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fiexample-cliの部分は、自分のプラグイン名に置き換えます。呼び出しのたびに出力して構いません。Claude Code側が、プラグインごとに1回だけ提案するためです。複数の経路(--help、ログイン成功時など)で出しても、同じプラグインの提案が2回出ることはありません。
ヒントの形式
ヒントは3つの必須属性を持つ自己閉じタグで、行全体を占める必要があります。行の途中に埋め込まれたタグは無視されます。
| 属性 | 説明 |
|---|---|
v | 説明プロトコルバージョン。サポートされる値は1のみ |
type | 説明ヒントの種類。サポートされる値はpluginのみ |
value | 説明name@marketplace形式のプラグイン識別子 |
属性値はダブルクォートで囲んでも、クォートなしでも構いません。クォートなしの値には空白を含められません。
stderrに書くので、example-cli deploy | jqのようにstdoutをパイプでつないでも、タグは混ざりません。
手元でゲートの動きを試す
Claude Codeを起動しなくても、ゲートの分岐は一時ディレクトリで試せます。次のスクリプトは、上のShellの例にdeploy okの出力を足したexample-cliです。
cat > example-cli <<'SCRIPT'
#!/bin/sh
if [ -n "$CLAUDECODE" ]; then
printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fi
echo "deploy ok"
SCRIPT
chmod +x example-cli
CLAUDECODE=1 ./example-cli 2>&1 >/dev/null | wc -c # タグだけをstderrから集計
env -u CLAUDECODE ./example-cli 2>&1 >/dev/null | wc -c
CLAUDECODE=1 ./example-cli 2>/dev/null # stdoutだけを見るClaude Code v2.1.287で実行すると、結果は次のようになります。
85
0
deploy ok変数を設定したときだけstderrに85バイト(タグ1行ぶん)が出て、設定しなければ0バイトです。stdoutはdeploy okだけで、パイプの先にタグは流れません。
Claude CodeのBashツール内で実行すると、タグの行はツールの出力から取り除かれ、ファイルへ書き出してcatしても画面には空行しか出ません。ヒント行が実際にstderrへ出ているかを目で見るには、Claude Codeの外の端末で実行します。Claude Code内では、wc -cのようにバイト数で見る方法が使えます。
提案が出ない条件
提案は対話的なターミナルセッションにだけ出ます。claude -pの実行、サブエージェントの実行、hookコマンドの出力では、タグは取り除かれるだけで提案は出ません。hookコマンドでCLIを呼んでも提案にはつながらず、サブエージェントや非対話モードの自動化でも同じです。
加えて、次の条件がすべて満たされる必要があります。
提案が出るための条件
公式で、入れられるプラグイン
valueが公式マーケットプレイスのローカルコピーにあるプラグインを指し、未インストールで、ポリシーでブロックされていないこと。分析が有効
DISABLE_TELEMETRY、DO_NOT_TRACK、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICのいずれかを設定したセッションでは出ません。Amazon Bedrockなど、テレメトリが自動でオフになるサードパーティ経由のセッションも同じです。頻度の上限
1セッションにつき1回、1プラグインにつき一度きり(回答に関わらず)です。そのマシンで100個のプラグインを提案した後は、新しい提案が出ません。
止められていない
ユーザーが「No, and don't show plugin installation hints again」を選んでいないこと。
手元で、人が見ているセッション
ワークスペースがローカルで、無人で動いていないこと。
--cloudで始めたセッション、Remote Controlで操作されているセッション、エージェントチームのチームメイトには出ません。
ユーザーに表示される内容
条件がすべて通ると、Claude Codeは次のような「Plugin recommendation」ダイアログを表示します。
─────────────────────────────────────────────────────────────
Plugin recommendation
The example-cli command suggests installing a plugin.
Plugin: example-cli
Marketplace: claude-plugins-official
Description: Official integration for example-cli deployments
Would you like to install it?
❯ 1. Yes, install
2. No
3. No, and don't show plugin installation hints again
─────────────────────────────────────────────────────────────ダイアログに出る「command」は、Claudeが実行したシェルコマンドの最初の単語です。ユーザーは、ツールと提案されたプラグインの組み合わせがおかしくないかを、そこで見分けられます。答えの効果は次のとおりです。
- 「Yes, install」を選ぶと、プラグインがuserスコープでインストールされる
- 「No, and don't show plugin installation hints again」を選ぶと、そのユーザーへの今後のヒント提案がすべて止まる
- 30秒応答がないと「No」と同じ扱いになる
公式マーケットプレイスへの掲載
ヒントが効くのは掲載済みのプラグインだけです。Anthropicのディレクトリ(claude.aiとCoworkで人が閲覧するカタログ)には開発者ポータルから申請できます。ただしclaude-plugins-officialは、このポータルでは申請を受け付けていません。掲載を望む場合は、Anthropicのパートナー窓口の担当者に相談する経路になります。
別の方法として、インストーラーやインストール完了後のメッセージで、claude plugin marketplace add <source>とclaude plugin install <name>@<marketplace>の2コマンドを出す案内もあります。こちらはユーザーが自分でコマンドを実行します。
手元のclaude pluginにも、公開前の検証に使えるサブコマンドがあります。v2.1.287のclaude plugin --helpには、次のコマンドが並びます。
install|i Install a plugin from available marketplaces
list List installed plugins
marketplace Manage Claude Code marketplaces
validate Validate a plugin or marketplace manifest, or the skills,
agents, and commands in a directory
tag Create a {name}--v{version} git tag for a plugin releaseclaude plugin marketplace listは、追加済みのマーケットプレイスの取得元を一覧します。マニフェストの検証はclaude plugin validate <path>です。tagはplugin.jsonと、それを含むマーケットプレイスのエントリが一致しているかを検証したうえで、リリース用のgitタグを作ります。プラグイン自体の作り方はClaude Codeプラグイン完全ガイドにあります。
まとめ
ヒントを出す側の実装は、環境変数で分岐して<claude-code-hint />をstderrへ1行書くだけです。提案は対話セッションで1プラグインにつき一度きりなので、導入の入口の1つと考え、claude -pやCIで動く利用者向けには別の案内を用意しておくと取りこぼしません。