管理画面を開かなくてもいい場面が増えてきた。
デプロイスクリプトの中でコンテンツの存在確認をしたい、複数サービスのスキーマを横断的に把握したい、バックアップを cron で定期取得したい——どれも管理画面では完結しない。AI エージェントが microCMS を操作できる手段も欲しかった。人間がターミナルで叩く用途と、エージェントがツールとして呼び出す用途の両方を想定している。
そこで Go で microcms CLI を作った。
https://github.com/hsblabs/microcms-cli
何ができるか
サービスの登録・切り替え、コンテンツの取得、マネジメント API の呼び出し、全コンテンツのバックアップ、シェル補完スクリプトの生成まで、ターミナルから一通り操作できる。
microcms service add # サービス登録(対話式)microcms service scan # API スキーマをスキャン・キャッシュmicrocms content list <ep> # コンテンツ一覧取得microcms content get <ep> [id] # 単一コンテンツ取得microcms management api list # API 一覧(マネジメント API)microcms backup --out ./backup # 全コンテンツのバックアップmicrocms completion zsh # シェル補完スクリプト生成最初にやることは2つ。service add でサービスを登録し、service scan でスキーマをキャッシュする。これだけで補完が効いた状態でコンテンツ操作が始められる。
$ microcms service add? Service ID: my-blog? Content API Key: ********? Management API Key (optional): ********✓ Service "my-blog" added.
$ microcms service scanScanning service "my-blog"... ✓ blogs (list, 5 fields) ✓ categories (list, 2 fields) ✓ banner (object, 3 fields)✓ Found 3 APIs (2 list, 1 object)
$ microcms content list blogs --limit 3技術スタック
CLI フレームワークは cobra、対話式入力には charmbracelet/huh を使った。API キーの暗号化は AES-256-GCM で、暗号鍵は go-keyring を通じて OS のキーチェーンに格納する。出力は text/tabwriter、encoding/json、gopkg.in/yaml.v3 をフォーマットに応じて切り替える構成だ。
設計で決めたこと
複数サービスの管理
開発用・本番用など複数サービスを使い分けるのが前提で、git のブランチ切り替えに近い UX を意識した。
$ microcms service use production✓ Active service: "production"サービス定義は ~/.config/microcms/service/<id>.json に保存し、API キーは AES-256-GCM で暗号化する。暗号鍵は macOS Keychain / Linux Secret Service / Windows Credential Manager に格納されるので、ファイルを直接読んでもキーは取り出せない。
スキャンキャッシュによる動的補完
service scan がマネジメント API からスキーマを取得し ~/.cache/microcms/scan/my-blog.json にキャッシュする。このキャッシュがシェル補完とバリデーション両方を担う構造だ。
microcms content list の後で Tab を押すとエンドポイント名が候補に出る。存在しないエンドポイントを指定した場合は typo サジェスト付きでエラーになる。
$ microcms content list bloggsError: Endpoint "bloggs" not found in service.
Did you mean "blogs"?Run 'microcms management api list' to see all available endpoints.TTL はデフォルト 24h で自動リフレッシュされるため、普段は意識しなくていい。
設定の3層レイヤー
設定値の解決順序は「CLI フラグ > 環境変数 > config.json > ビルトインデフォルト」にした。
# config.json に保存$ microcms config set output.format json
# 環境変数で上書き$ MICROCMS_OUTPUT_FORMAT=yaml microcms content list blogs
# フラグが最優先$ microcms content list blogs --format table設定ファイルは XDG Base Directory 準拠($XDG_CONFIG_HOME/microcms/config.json)。
デフォルト出力を JSON にした理由
content コマンドのデフォルト出力は JSON だ。microCMS のレスポンスは繰り返しフィールドやコンテンツ参照でネストが深く、テーブル表示では情報が落ちる。jq とパイプで加工するケースが主なので、テーブルよりも JSON の方が都合がいい。
# jq と組み合わせる$ microcms content get blogs abc123 | jq '.title'
# 人の目で確認したいときは table$ microcms content get blogs abc123 --format tableKEY VALUEcreatedAt 2024-01-15T10:00:00.000Ztitle Hello Worldtags (array, 3 items)エラーメッセージの構造
すべてのエラーを「何が起きたか → なぜ → どうすればいいか」の3層構造にした。
$ microcms service scanError: Permission denied: Forbidden
Check that your API key has the required permissions enabled.For management API operations, enable permissions in the 'マネジメントAPI' tabof your API key settings.終了コードもエラー種別ごとに分けている。一般エラー(1)、使い方エラー(2)、設定エラー(3)、認証エラー(4)、権限エラー(5)、レート制限(6)、リモート API エラー(7)、ネットワークエラー(8)だ。スクリプトでの分岐判定に使える。
バックアップ
全 API のコンテンツを並列で取得してローカルに保存する。
$ microcms backup --out ./backup --parallel 8
backup/├── manifest.json├── apis.json├── schemas/│ ├── blogs.schema.json│ └── categories.schema.json└── contents/ ├── blogs/ │ ├── abc123.json │ └── def456.json └── categories/ └── news.json--dry-run で実行計画だけ確認できる。
実装で工夫した点
API キーのフォールバック
microCMS では1つの API キーにコンテンツ API とマネジメント API 両方の権限を付与できる。マネジメント API キーが未設定の場合、コンテンツ API キーをフォールバックとして使うようにした。
mgmtKey := svc.ManagementAPIKeyif mgmtKey == "" { mgmtKey = svc.ContentAPIKey}リトライとバックオフ
HTTP クライアントにエクスポネンシャルバックオフ + ジッターを実装した。429(レート制限)や 5xx エラーで自動リトライする。
interval := baseInterval * 2^attemptif jitter { interval *= (0.5 + rand * 0.5)}Atomic な設定ファイル書き込み
設定ファイルの更新は「一時ファイルへの書き込み → os.Rename」のパターンで原子的に行う。書き込み途中のクラッシュでファイルが壊れるのを防ぐためだ。
インストールとセットアップ
# Homebrewbrew install hsblabs/tap/microcms
# Gogo install github.com/hsblabs/microcms-cli@latest
# サービス登録microcms service add
# スキーマスキャン(補完を有効化)microcms service scan
# シェル補完(zsh の例)microcms completion zsh > "${fpath[1]}/_microcms"microCMS を日常的に使っていて、管理画面を開く手間が気になっている場面があれば試してみてほしい。フィードバックや PR は歓迎だ。
hsb.horse