株式会社ホコサキ

CLI-Anything で既存 CLI をエージェントから呼び出す

天京祐輔
天京祐輔
CLI-Anything で既存 CLI をエージェントから呼び出す

ffmpeg に新しいオプションが増えるたびに Function Calling のスキーマを更新して、ImageMagick のサブコマンドをラッパー関数に写経する——このサイクル、地味に消耗しますよね。
エージェントに CLI を使わせるたびに「人間がスキーマを書いて維持する」という工程が必ず発生していました。
CLI-Anything は、その翻訳作業ごと消してしまおうという発想のフレームワークです。
HKUDS グループが開発し、GitHub で公開されています。

発想の転換は一言で言えます。
LLM はすでに膨大なシェルスクリプトや CLI ドキュメントで訓練されていて、--help の構造を自力で読んで理解できます。
「AI に新しいツールを覚えさせる」のではなく、「AI がすでに知っているツールをそのまま呼ばせる」——この方向に設計を切り替えられる、というのが出発点です。

MCP や Function Calling との違いは「誰がスキーマを書くか」という一軸で整理できます。
Function Calling はエンジニアがスキーマを手書きして管理します。
MCP はサーバーとプロトコルを用意して、そこにツール定義を乗せます。
CLI-Anything は CLI 自身の --help 出力やソースから仕様を読み取って、エージェントが呼び出せる形を 自動生成 します。
人間が仲介者として定義を維持しつづけなくていい——それが最大の違いです。

「エージェントネイティブ化」というのは、このプロジェクトが使う言葉です。
ラッパーやスキーマという翻訳レイヤーを介さずに、エージェントが CLI を直接呼び出して結果を受け取れる状態——それがエージェントネイティブです。

CLI-Anything の仕組み——ハーネスが何をしているか

核心にあるのは ハーネス(HARNESS.md)の生成 です。
CLI ツールの --help 出力やソースコードから仕様を読み取り、エージェントが呼び出せる形に変換します。
この変換プロセスを「ビルド」と呼び、指示一発で実行できます。

ハーネスが持つ構成要素を整理します。

  • JSON 出力: CLI の実行結果をエージェントがパースしやすい構造化レスポンスとして返す
  • JSON プロジェクトファイル: エージェントが状態を検査できるワークスペースを提供する
  • セッションファイル: 現在のプロジェクトパスと変更状態を記録し、会話をまたいで継続できる
  • undo/redo スタック: エージェントの探索的な操作を安全に取り消せる
  • ドライランモード: 実際のミューテーション(副作用)が起きる前にプランを確認できる

この設計で特に注目したいのが「 ステートを一級市民にする 」という思想です。
ffmpeg や ImageMagick はファイルを書き換えたり生成したりという副作用を持ちます。
エージェントがそういった CLI を自律的に扱うには、「今どういう状態か」を常に把握できる仕組みが必要です。
人間なら画面を見て確認できますが、エージェントにはその感覚がない。
だから状態を JSON で明示的に扱い、undo で取り消せて、ドライランで確認できる構造を用意することで、エージェントが安全に副作用のある操作を扱えるようにしているわけです。

CLI-Anything の論文(arxiv: 2606.03854) には「ハーネスは実際のソフトウェアバイナリに依存することを前提とする」という記述があります。
Python で動作を模倣したラッパーではなく、本物の ffmpeg や ImageMagick を呼び出す。
GIMP バックエンドの実装例では、実際の GIMP 実行ファイルを見つけて Script-Fu をバッチモードで走らせ、期待する出力ファイルが存在しなければエラーを上げる、という設計が示されています。
「本物のソフトウェアを呼ぶ」という前提が、ハーネスの信頼性を担保しているのです。

MCP との位置づけをひとことで整理すると、MCP はエージェントとサービスを繋ぐ プロトコル で、CLI-Anything は既存 CLI をエージェントから呼べる形にする ハーネス生成の方法論 です。
競合するというより、使い分ける場面が異なります。

Docker + Claude Code でセットアップする

エージェントが CLI を自律実行する環境では、意図しないファイルの書き換えや権限の逸脱が起きやすいです。
Docker のコンテナ境界がそのままセーフティネットになるので、ローカル環境を汚染せずに試せます。

まず GitHub リポジトリをクローンして、インストールスクリプトを実行します。

git clone https://github.com/HKUDS/CLI-Anything.git
cd CLI-Anything
bash .pi-extension/cli-anything/install.sh

install.sh は拡張ファイル(HARNESS.md・コマンド定義・ガイドなど)を ~/.pi/agent/extensions/cli-anything/ にコピーします。
ここで Pi とは CLI-Anything が前提とするエージェントシェル環境のことで、VS Code が拡張機能ディレクトリを自動検出するのと同じように、このパスに置いたファイルを起動時に読み込みます。

拡張をアクティブにするには Pi セッションで /reload を実行するか Pi を再起動します。
その後は Pi セッション内でハーネスのビルドを指示できます。
指示はコマンドではなく自然言語で渡します。

# Pi への指示例(GIMP のハーネスをビルドする場合)
"Build a complete CLI harness for GIMP"

この指示を受けた Pi が対象ソフトウェアのヘルプ出力やソースを解析してハーネスを生成します。
ffmpeg や pandoc でも同じ流れになります。

Docker で隔離環境を作るなら、使いたい CLI ツールを含む Dockerfile を用意します。

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    ffmpeg imagemagick pandoc \
    curl git nodejs npm

WORKDIR /workspace

RUN git clone https://github.com/HKUDS/CLI-Anything.git /opt/cli-anything \
    && cd /opt/cli-anything \
    && bash .pi-extension/cli-anything/install.sh

実行時はマウントするディレクトリの範囲を絞ります。

docker run -it \
  -v $(pwd)/workspace:/workspace \
  cli-anything-env

Claude Code との接続は、Claude Code が走るシェル環境に Pi を同居させる形が基本です。
Claude Code はターミナル上で動いてシェルコマンドを直接実行できるので、Pi を介したハーネス呼び出しと相性がよいです。

CLAUDE.md(Claude Code がプロジェクトのコンテキストとして読み込む設定ファイル)に、利用可能なハーネスと用途を記述しておくと、Claude Code がタスクに応じて適切な CLI を選択して呼び出します。

## 利用可能な CLI ハーネス(Pi 経由)

- ffmpeg: 動画・音声のエンコード・変換
- pandoc: ドキュメント形式変換(Markdown → PDF など)
- imagemagick: 画像のリサイズ・加工

ファイル変換が必要なタスクでは、これらのハーネスを優先して使うこと。

CLI-Anything は Claude Code のほか OpenClaw・Codex・GitHub Copilot CLI など複数のエージェント環境に対応しています。
どのエージェントから呼び出す場合も、Pi 上にロードされたハーネスを介して CLI にアクセスする構造は共通です。

ffmpeg を自然言語で動かす——実行フローを追う

「この動画を 720p にリサイズして」という指示が ffmpeg コマンドに変換されるまでの流れを、エージェント視点で順番に追います。

まずユーザーが自然言語で指示を入れます。

User: input.mp4 を 720p にリサイズして output_720p.mp4 として保存して

エージェントはいきなり実行せず、ドライランでプランを提示します。
ファイルに触る前に「これをやろうとしている」を確認できる仕組みです。

[Dry-run] 実行予定コマンド:
ffmpeg -i input.mp4 -vf scale=-1:720 -c:v libx264 -preset fast output_720p.mp4

このコマンドを実行しますか?

承認すると本番実行に移り、ハーネスが結果を JSON で返します。
論文の記述では「期待する出力ファイルが存在しなければエラーを上げる」という設計が明示されています。
出力ファイルの存在確認が成功判定に組み込まれているため、ffmpeg がサイレントに失敗してエージェントが誤判定するリスクをハーネス側が防ぎます。

{
  "status": "success",
  "command": "ffmpeg -i input.mp4 -vf scale=-1:720 -c:v libx264 -preset fast output_720p.mp4",
  "output_file": "output_720p.mp4",
  "exists": true
}

エラーハンドリングをエージェント任せにせず、ハーネスが担保している点がポイントです。

実務上で特に注意したいのが、ファイルを 上書きする操作 です。
undo スタックがあるとはいえ、上書き系の副作用はドライランで内容を確認してから実行するフローを先に決めておくほうが安全です。
エージェントが自律実行する環境では、人間が「あ、違う」と止めるタイミングがないので、このプロセスが歯止めになります。

pandoc との相性も一言添えておきます。
「この Markdown を PDF に変換して」という指示であれば、pandoc のハーネスが変換コマンドを組み立てて実行します。
テキスト変換系の CLI は入出力が明確で副作用の範囲も予測しやすく、エージェントとの組み合わせで一番扱いやすいジャンルです。

どの CLI に向いていて、どの CLI には向かないか

向き・不向きを判断するときに最初に確認したい問いがあります。
「エージェントがテキストを読んで判断し、テキストで操作を完結させられるか」——これが通るなら CLI-Anything のスコープに入ります。

ffmpeg・pandoc・ImageMagick・kubectl・gh CLI のような長年の実績があるツールはこの条件を満たしています。
--help が体系的に整備されていて、入出力がファイルやテキストで完結していて、副作用の範囲が予測できます。
ハーネス生成は CLI のドキュメントに大きく依存するため、ヘルプが充実しているほど品質が上がる関係があります。

逆に向かないのは、htop や vim のような「人間がリアルタイムに操作する」設計の TUI ツールです。
エージェントは標準出力と構造化データを読んで判断を下すので、インタラクティブな画面描画を前提とした設計とは根本的にかみ合いません。
認証フローが複雑なツールも要注意で、OAuth のコールバック待ちや MFA のインタラクティブ入力が必要なものはバッチ実行の前提を満たせません。

副作用の不可逆性も別の判断軸になります。
クラウドリソースを削除するような操作は undo スタックで取り戻せる範囲を超えます。
こういった CLI は CLI-Anything のスコープから切り離すか、実行前に必ず人間の確認を挟む設計を組み合わせるほうが現実的です。

MCP・Function Calling との使い分けは「何が手元にあるか」で考えると判断しやすいです。
すでに現場で使っている CLI ツールがあれば CLI-Anything が最初の選択肢です。
外部 API サービスや独自プロトコルを繋ぎたいなら MCP、特定の関数をピンポイントで呼ばせたい・スキーマの細かい制御が必要なら Function Calling、という使い分けになります。

一つ見落としがちな観点として、「自分で書いたスクリプト」も対象に入ることがあります。
bash スクリプトや Python スクリプトも --help を実装していれば、CLI-Anything のスコープに入ってきます。
新しいツールを覚えさせるより、すでに動いている自動化資産をそのままエージェントに渡す——この方向のほうが実務では即効性があることが多いです。


株式会社ホコサキは山口県宇部市を拠点とする IT 企業です。
CLI-Anything のような OSS を活用したエージェント連携の実装に興味があれば、お問い合わせページ からご連絡ください。

    CLI-Anything で既存 CLI をエージェントから呼び出す | 株式会社ホコサキ