MCP vs CLI - なぜ今CLIツールを作るのか
AIエージェント時代にRedmineと連携する方法として、MCPサーバーではなくCLIツールを選んだ理由。GitHub CLIの成功から学んだこと、そしてMCPとCLIそれぞれの適材適所について。
はじめに
AIエージェントと外部システムを連携させたい。 そう考えたとき、あなたはどんな方法を選びますか?
私は最初、素直にMCP(Model Context Protocol)サーバーを作りました。 Claude Codeから直接Redmineを操作できるようにしたかったのです。
しかし、実際に使ってみて気づいたことがありました。 「これ、本当に使いやすいだろうか?」
その後、GitHub CLIを使うAIエージェントの様子を見て、考え方が180度変わりました。 今回は、なぜMCPからCLIへと方向転換したのか、その経緯と学びを共有します。
GitHub CLIとの出会い
Claude Codeを使い始めて最初に驚いたのは、GitHubの操作でした。
# Claude Codeが自然に使うコマンド
gh pr create --title "feat: 新機能の実装"
gh issue list --assignee @me
gh pr diff
私が「PRを作成して」とお願いすると、Claude Codeは迷わずgh
コマンドを使うのです。
GitHub APIを直接叩くわけでもなく、ブラウザを操作するわけでもない。
シンプルにCLIを使う。
その動作があまりにも自然で、効率的で、そして美しかった。
最初の試み:Redmine MCP
「RedmineでもAIエージェントから操作したい」
最初に思いついたのは、MCPサーバーの開発でした。 MCPはClaude Codeが外部システムと連携するための標準的な方法です。
// MCPの設定例
{
"mcpServers": {
"redmine": {
"command": "node",
"args": ["redmine-mcp-server.js"],
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your-api-key"
}
}
}
}
実装は比較的スムーズでした。 というのも、ClineやRoo CodeなどのAIエージェントを使えば、MCPの詳しい知識がなくても実装できたからです。
「Redmine用のMCPサーバーを作って」とお願いするだけで、AIエージェントが以下を実装してくれました。
- MCPプロトコルの仕様を理解し
- 必要なインターフェースを実装し
- RedmineのAPIをラップしてくれる
まさにAIエージェントの力を借りて、AIエージェント用のツールを作るという面白い体験でした。 技術的なハードルは、思ったより低かったのです。
MCPの限界
しかし、実際に使い始めて、いくつかの問題に直面しました。
デバッグの難しさ
MCPサーバーで何か問題が起きたとき、原因を特定するのが大変でした。
MCPサーバーは標準入出力を使って通信するため、通常のコンソール出力でデバッグ情報を確認することができません。 専用のログファイルに出力する必要があり、ログを確認するためには別のターミナルを開いてログファイルを監視する必要があります。
さらに、実際の通信内容を見るためにはデバッグモードを有効にし、サーバーを再起動する必要があります。 エラーが起きても、それがMCPサーバー側なのか、Claude Code側なのか、設定の問題なのか。 切り分けが難しい。
他のツールとの連携
MCPはClaude Code専用です。 他のAIエージェントや、普通のターミナルからは使えません。
# これはできない
$ redmine-mcp issue list # MCPはCLIツールではない
# シェルスクリプトに組み込めない
$ ./deploy.sh && redmine-mcp issue close 123 # 無理
ユーザーの学習コスト
MCPの設定自体はそれほど複雑ではありません。 しかし、問題が発生したときには話が別です。
「MCPサーバーが起動しない」 「Claude Codeから認識されない」 「エラーメッセージが意味不明」
こうなると、MCPの仕組みを理解する必要が出てきます。 標準入出力での通信方式、JSON-RPCプロトコル、エラーハンドリングの仕組み。 トラブルシューティングのために、結局は深い知識が必要になってしまうのです。
CLIという選択肢
GitHub CLIの成功を見て、気づきました。 「CLIでいいじゃないか」
CLIの利点
透明性
# 何が起きているか一目瞭然
$ redmine issue list --assignee @me
┌──────┬──────────┬──────────┬─────────┬─────────┬─────────┐
│ ID │ Subject │ Priority │ Status │ Project │ Updated │
├──────┼──────────┼──────────┼─────────┼─────────┼─────────┤
│ 123 │ ログイン │ 通常 │ 進行中 │ Web開発 │ 2 hours │
│ │ 機能実装 │ │ │ │ ago │
└──────┴──────────┴──────────┴─────────┴─────────┴─────────┘
# エラーが出たときも、何をすべきか明確
$ redmine issue list
Error: No API key found in active profile. Please run 'redmine auth login' first.
普遍性
# どこでも使える
$ redmine issue list # 手動実行
$ ./script.sh && redmine issue edit 123 --status closed # スクリプト内
$ claude-code "redmineのチケット一覧を表示" # AIから
馴染みやすさ
開発者なら誰でも知っているインターフェース。
# Gitと同じ感覚
git status
git commit -m "message"
# Redmineも同じ
redmine issue list
redmine issue create --title "新機能"
MCPとCLIの適材適所
とはいえ、MCPが悪いわけではありません。 それぞれに適した用途があります。
以下は、私がRedmineCLIを開発する過程で感じた、それぞれの技術の向き不向きです。 あくまで私の経験に基づく私観であることをご理解ください。
MCPが適している場合
-
技術文書などのリソースを参照
- ドキュメントの検索と取得
- コンテキストに応じた情報提供
- 例:Context7のようなドキュメント参照MCP
-
呼び出し方に型が必要
- 厳密な型定義が求められるAPI
- 複雑なデータ構造の受け渡し
- スキーマによる検証が必要な場合
-
外部のサーバーを利用したい
- 自分でサーバーを管理したくない
- SaaSとして提供されるMCPサーバー
- メンテナンスフリーな選択肢
CLIが適している場合
-
シンプルな操作
- CRUD操作
- 一覧表示、検索
-
既存ワークフローへの統合
- シェルスクリプト
- CI/CDパイプライン
-
幅広い利用者
- 開発者全般
- 複数のAIエージェント
RedmineCLIへの道
結局、私はCLIを選びました。
理由は単純です。 使いやすさと汎用性。
# 開発者が期待する動作
$ redmine issue list
$ redmine issue create
$ redmine issue edit 123
# AIエージェントも同じように使える
Claude: "redmine issue list --project web-dev を実行します"
MCPサーバーの開発経験は無駄ではありませんでした。 APIの理解が深まり、何が本当に必要な機能なのかが明確になりました。
まとめ
MCPからCLIへ。 この方向転換は、技術的な後退ではなく、ユーザビリティへの前進でした。
学んだこと
-
最新技術が常に最適解ではない
- MCPは素晴らしい技術
- でも、今回のケースではCLIの方が適していた
-
既存のパターンの力
- 開発者は既にCLIに慣れている
- 新しいことを学ぶ必要がない
-
シンプルさの価値
- 複雑な仕組みより、単純な解決策
- デバッグしやすく、理解しやすい
これから
RedmineCLIは、今も進化を続けています。 とはいえ、まだまだ至らない箇所がたくさんあります。
エラーメッセージがわかりにくい部分があったり、デバッグ機能が十分でなかったり。 「No API key found」と表示されても、なぜAPIキーが見つからないのか、設定ファイルのどこを確認すればいいのかまでは教えてくれません。
それでも、実際に使いながら改善を重ねています。 MCPの良さも取り入れながら、CLIツールとしての使いやすさを追求していく。
それぞれの技術には、それぞれの良さがある。 大切なのは、目的に応じて適切な技術を選ぶこと。
今回の経験が、同じような選択に直面している方の参考になれば幸いです。