「毎回手で打っているこの作業、コマンド一発にできないかな」——そう思った瞬間が、CLIツールを作るベストタイミングです。ファイルをまとめてリネームする、ログを集計する、APIを叩いてCSVに吐く。こうした定型作業は、引数を受け取る小さなコマンドにしてしまえば、チームの誰でも同じ手順で再現できます。とはいえ、引数のパースやエラー処理、ヘルプの整備まで自前で書くのは地味に面倒です。ここをClaude Codeに任せると、設計の壁打ちから実装、テスト、配布まで一気に進みます。
この記事では、Claude Codeを使ってCLIツール(自作コマンド)を作る流れを、PythonのargparseとNode.jsのcommanderを例に、実際の指示文とコード付きで解説します。2026年6月時点のClaude Code公式ドキュメントを基準にしています。
結論:CLIツール作成は「設計→実装→テスト→配布」をClaude Codeで分割する
先に結論です。Claude Codeで自作コマンドを作るときは、いきなり「ツール作って」と丸投げせず、次の順で進めると失敗が減ります。
- 要点1:まず引数・サブコマンド・入出力を言語化してから書く。設計が曖昧なまま生成すると、後でインターフェースを作り直すことになります。
- 要点2:エラー処理・入力検証・ヘルプは最初から要求する。「正常系だけ動くツール」は本番で必ず事故ります。
- 要点3:生成コードは人がレビューする。とくにファイル削除・上書き・外部コマンド実行など破壊的操作は、自分の目で確認してから実行します。
対象読者:自分やチームの定型作業をコマンド化したい開発者・エンジニア・PM。今日できること:argparse / commander を使った最小CLIの設計とClaude Codeへの具体的な指示文、テストと配布までの考え方を持ち帰れます。

ステップ1:設計を固める(引数・サブコマンド・入出力の整理)
CLIツールでいちばん大事なのは、コードより先に「インターフェース設計」です。後から引数の名前や形を変えると、使う側のスクリプトも全部直すことになります。Claude Codeに実装させる前に、最低限この4つを言語化しておきます。
- コマンド名と目的:何をする道具か(例:複数画像を一括リサイズする
imgresize)。 - サブコマンドの有無:単機能なら不要。
gitのように複数動作があるならtool add/tool listのようにサブコマンドへ分割。 - 引数とオプション:必須の位置引数(入力パスなど)と、任意のフラグ(
--dry-run、--outputなど)を分ける。 - 入出力と終了コード:標準入力/ファイルどちらを受けるか、結果は標準出力かファイルか、成功は
0・失敗は1以上を返すか。
この4点を箇条書きにしてClaude Codeへ渡すと、いきなり「いい感じに作って」と頼むより圧倒的に精度が上がります。Claude CodeはPlan Modeで先に計画だけ立てさせることもできるので、大きめのツールなら設計案を出してもらってから実装に入ると安全です。
設計を相談するときの指示文の例
あなたはCLI設計のレビュアーです。次のツールのインターフェース案を出してください。
- 目的: 指定フォルダ内の画像(jpg/png)を一括で長辺指定リサイズする
- 入力: フォルダパス(必須)、長辺px(--max-edge, デフォルト1280)
- オプション: --dry-run(変換せず対象だけ表示), --output(出力先, 省略時は上書きしない別フォルダ)
- 出力: 処理件数のサマリを標準出力に、エラーは標準エラーに
- 終了コード: 成功0 / 入力不正2 / 実行時エラー1
実装はまだしないでください。引数表・ヘルプ文・想定エッジケースだけ先に列挙してください。
このように「まだ実装しないで」と明示するのがコツです。設計を確定させてから書かせることで、手戻りを大幅に減らせます。
ステップ2:実装の進め方(ライブラリ選び・エラー処理・ヘルプ)
設計が固まったら実装です。ライブラリは「標準ライブラリで足りるか」をまず考えます。Pythonなら追加インストール不要の argparse、Node.jsなら定番の commander が無難です。凝ったTUIや色付き出力が要らないうちは、軽い構成を選ぶほうが配布も楽になります。
Python:argparse での最小実装
Claude Codeに次のように頼むと、引数定義・ヘルプ・基本のエラー処理まで含んだ雛形を出してくれます。
ステップ1で決めた設計に沿って、Python標準ライブラリのargparseだけで実装してください。
要件:
- 位置引数 folder(必須), オプション --max-edge(int, default 1280), --dry-run(flag), --output(str)
- folderが存在しない/ディレクトリでない場合は終了コード2でエラーメッセージ
- --dry-run時はファイルを書き換えず対象一覧だけ表示
- 例外はキャッチして標準エラーに出し、終了コード1で抜ける
- if __name__ == "__main__": でエントリポイントを用意
生成される雛形は、おおむね次のような骨格になります(処理本体は要件に合わせて差し替えます)。
import argparse
import sys
from pathlib import Path
def build_parser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(
prog="imgresize",
description="フォルダ内の画像を長辺指定で一括リサイズする",
)
p.add_argument("folder", help="対象フォルダのパス")
p.add_argument("--max-edge", type=int, default=1280, help="長辺の最大px (default: 1280)")
p.add_argument("--dry-run", action="store_true", help="変換せず対象だけ表示")
p.add_argument("--output", help="出力先フォルダ (省略時は別名で保存)")
return p
def main() -> int:
args = build_parser().parse_args()
target = Path(args.folder)
if not target.is_dir():
print(f"error: フォルダが見つかりません: {target}", file=sys.stderr)
return 2
try:
files = [f for f in target.iterdir() if f.suffix.lower() in (".jpg", ".png")]
if args.dry_run:
for f in files:
print(f"[dry-run] {f.name}")
print(f"対象 {len(files)} 件")
return 0
# ここに実際のリサイズ処理を書く
print(f"完了: {len(files)} 件を処理しました")
return 0
except Exception as e:
print(f"error: {e}", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())
ポイントは3つです。引数定義を build_parser() に分離するとテストしやすくなります。異常時に sys.stderr へ出して終了コードを返すことで、後続のスクリプトやcronから成否を判定できます。--dry-run を最初から用意しておくと、破壊的操作の前に安全確認ができます。
Node.js:commander での最小実装
JavaScript/TypeScript圏ならcommanderが定番です。サブコマンド構造を作りやすいのが利点で、Claude Codeにも「commanderでサブコマンド resize と list を作って」と頼めます。
#!/usr/bin/env node
import { Command } from "commander";
const program = new Command();
program
.name("imgtool")
.description("画像まわりの小道具")
.version("1.0.0");
program
.command("resize")
.description("長辺指定で一括リサイズ")
.argument("<folder>", "対象フォルダ")
.option("--max-edge <px>", "長辺の最大px", "1280")
.option("--dry-run", "変換せず対象だけ表示")
.action((folder, opts) => {
// 入力検証・処理本体はここに
console.log(`resize: ${folder} (maxEdge=${opts.maxEdge}, dryRun=${!!opts.dryRun})`);
});
program.parseAsync(process.argv).catch((e) => {
console.error(`error: ${e.message}`);
process.exit(1);
});
commanderは --help や --version を自動で生成してくれるので、ヘルプ文を自分で書く手間が減ります。先頭の #!/usr/bin/env node(シバン)を付けて実行権限を与えれば、そのままコマンドとして起動できます。
エラー処理とヘルプは「後回しにしない」
生成AIに任せると、つい正常系だけ整った状態で満足しがちです。ですが実運用で効いてくるのは、むしろ次のような地味な部分です。Claude Codeへの指示に最初から含めておきましょう。
- 入力検証:パスが存在するか、数値オプションが負でないか、想定外の値を弾く。
- わかりやすいエラーメッセージ:「何がダメで、どう直せばいいか」を1行で。
- ヘルプ:引数の説明・デフォルト値・使用例。argparse/commanderはほぼ自動生成できる。
- 終了コードの一貫性:成功は0、入力不正と実行時エラーで番号を分けると自動化しやすい。
Claude Codeはこのあたりの定石を持っているので、「入力検証とヘルプも漏れなく付けて」と一言添えるだけで網羅性が上がります。逆に何も言わないと省略されることがあるので、明示が大事です。Claude Codeの基本操作や指示の出し方そのものに不安があれば、Python開発をClaude Codeで効率化する実践ガイドもあわせて読むと土台が固まります。
ステップ3:テストと動作確認
CLIツールは「引数の組み合わせ」が多く、手で全パターンを試すのは現実的ではありません。引数パース部分を関数に切り出しておけば、テストが書きやすくなります。Claude Codeに「pytestでテストを書いて」と頼めば、正常系・異常系の両方を出してくれます。
import pytest
from imgresize import build_parser
def test_defaults():
args = build_parser().parse_args(["./photos"])
assert args.folder == "./photos"
assert args.max_edge == 1280
assert args.dry_run is False
def test_flags():
args = build_parser().parse_args(["./photos", "--max-edge", "800", "--dry-run"])
assert args.max_edge == 800
assert args.dry_run is True
def test_missing_required_arg():
with pytest.raises(SystemExit):
build_parser().parse_args([]) # folder必須なのでSystemExit
テストを書く流れは、いわゆるテスト駆動でも進められます。動作確認では、必ず --dry-run から試す習慣をつけてください。本番フォルダでいきなり書き換えると、ミスが即被害になります。テストやデバッグで詰まったときは、Claude Codeでデバッグ・障害調査を効率化する実践ガイドの手順が役立ちます。
ステップ4:配布・インストールの考え方
作ったツールを自分だけでなくチームで使うには、配布方法を決めます。規模に応じて段階的に考えると無理がありません。
- 個人利用:スクリプトに実行権限(
chmod +x)を付け、~/binなどPATHの通った場所に置くだけで十分です。 - チーム配布(Python):
pyproject.tomlに[project.scripts]でエントリポイントを定義し、pip install .でコマンドとして入るようにします。 - チーム配布(Node.js):
package.jsonのbinフィールドにコマンド名と実行ファイルを書けば、npm install -gでグローバルコマンドになります。 - 環境を固定したい場合:Dockerにまとめる、もしくはPythonなら
pipxで隔離インストールする選択肢もあります。
「どの配布形態が今回の規模に合うか」もClaude Codeに相談できます。pyproject.toml や package.json の bin 設定は定型なので、要件を伝えれば設定ファイルごと書いてくれます。READMEの雛形(使い方・例・オプション一覧)も同時に頼むと、配布物として一気に整います。
ステップ5:よくある改善(拡張・運用しやすくする工夫)
最小版が動いたら、運用しやすくする改善を少しずつ足します。これも一気にやらず、必要になったタイミングでClaude Codeに依頼するのが効率的です。
- 設定ファイル対応:毎回同じオプションを打つのが面倒なら、
.toolrcやYAMLから既定値を読み込む。 - 進捗表示・ログ:処理件数が多いツールは進捗を出し、
--verboseで詳細ログを切り替えられるようにする。 - サブコマンド分割:機能が増えたら単一コマンドを
tool sub形式に再構成する。argparse/commanderどちらもサブコマンドに対応。 - 非対話・自動実行:cronやCIから無人で回すなら、対話的な確認を挟まない設計にする。
ツール作りに慣れてきたら、Claude Code自体の使い方も底上げしておくと作業が速くなります。設定の整え方はClaude Code settings.json設定完全ガイド、よく使うテクニックの全体像はClaude Code 実践テクニック完全ガイドにまとまっています。
補足:自分専用コマンドを「Claude Code内」に作る選択肢
なお「CLIツール」とは別に、Claude Code側に定型作業を登録する方法もあります。よく使う依頼を /コマンド名 で呼び出せるカスタムスラッシュコマンドです。OSのコマンドとして配布するほどでもない、Claude Codeでの作業手順を短縮したいだけなら、こちらが手軽です。両者は用途が違うので、配布対象(人が直接叩くか、Claude Codeに作業させるか)で使い分けてください。
落とし穴:生成コードを鵜呑みにしない(破壊的操作と入力検証)
最後に、CLIツールづくりでいちばん事故が起きやすいポイントを整理します。便利なツールほど「一発で大量のファイルを触る」ので、ミスの被害も大きくなります。
- ❌ 破壊的操作を確認なしで実行する → ⭕ 削除・上書き・移動は
--dry-runを先に走らせ、結果を見てから本実行する。生成コードにrm -rf相当やワイルドカード削除が含まれていないか、必ず目視する。 - ❌ 入力検証を省く → ⭕ パス・数値・形式を検証し、想定外なら処理前に止める。とくに外部から渡る引数(ユーザー入力・ファイル名)をそのままシェルやSQLに流すのは危険。
- ❌ 生成されたコードをレビューせずマージする → ⭕ コード差分は人がレビューする。AIが書いた箇所も、自分が書いたのと同じ基準でチェックする。Claude Codeにはコードを実行する前に権限を確認する仕組みがあるが、最終判断は人が持つ。
- ❌ エラーを握りつぶす → ⭕ 例外は標準エラーに出し、終了コードで成否を返す。無言で失敗するツールは、自動化に組み込んだとき気づけない。
Claude Codeは、ファイル変更やコマンド実行の前に許可を求める権限モードを持っています。自動化のために --dangerously-skip-permissions のような確認スキップを使う場面もありますが、これは「何が起きても自己責任」になる設定です。検証していないツールや、破壊的操作を含むスクリプトでは安易に使わないでください。まずは権限確認ありで動作を見て、安全だと確認できてから自動化に進めるのが鉄則です。
まとめ:小さく作って、人がレビューして、配布する
CLIツール・自作コマンドづくりは、Claude Codeと相性のいい題材です。設計を言語化し、argparse/commanderで最小版を書き、テストと --dry-run で安全を確かめ、配布形態を決める——この流れを分割して進めれば、生成AIの速さを活かしつつ事故を避けられます。大事なのは「全部任せる」ではなく「設計と検証は人が握る」こと。今日はまず、手で繰り返している作業を1つだけコマンド化してみてください。
佐藤傑(さとう・すぐる)。株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』(SBクリエイティブ)。