Movable Type Data API v7 / 226 endpoints
Movable Type の構築を
AI エージェントに任せる
管理画面から設定を入力し、データを投入し、テンプレートをコーディングする。 Movable Type のサイト構築で人間が一つずつ進めてきたこの流れを、まるごと AI エージェントに任せるための CLI とスキルが mtb です。
macOS / Linux / Windows・単一バイナリ・依存なし。設定は ~/.config/mtb に入ります。
> design-doc.md の設計で、Movable Type にサイトを組んでください。 # エージェントが打ったもの(チュートリアル 3-2 の記録から抜粋) mtb sites create --website '{"name":"Five United",…}' mtb sites categories create 2 --category '{"label":"お知らせ","basename":"info"}' mtb sites content-types create 1 --content-type '{"name":"サービス"}' mtb sites templates create 1 --template '{"name":"メインページ(トップ)",…}' --set template.text=@templates/メインページ(トップ).mtml mtb publish entries --ids … --wait モックアップの47ページを公開しました。HTML は47ページとも一致しています。 詰まったところ7つと直し方は build-log.md にあります。
- 226
- Data API v7 のエンドポイント
- +23
- mtb-pro が足すエンドポイント
- 7
- 同梱スキル
- 614
- テンプレートタグの参照
公式定義から全部
管理画面でしかできなかった操作
Claude Code プラグイン(mtb-pro を含む)
モディファイア48も
DEMO
デザインの HTML から、CMS と運用マニュアルまで
架空の企業「ファイブユナイテッド」のコーポレートサイトを、Claude Code が mtb だけで Movable Type に構築しました。人間が書いたのは、各段の頼む文だけです。
1入力
デザインの HTML
デザイン会社から受け取った静的な HTML 48ページと原稿。見た目と URL はこれに合わせます。
2AI → 人間が確認
設計書
どのページをブログ・記事・コンテンツタイプのどれで管理するか、AI が設計書に起こします。人間はそれを読んで確認します。
3AI(mtb)
MT の構築
設計書に沿って、設定・テンプレート・データの投入まで。管理画面は一度も開きません。
4AI
運用マニュアル
構築した管理画面を撮影しながら、更新する担当者向けのマニュアルを書きます。



- サイト
- ウェブサイト1つ+ブログ3つ
- コンテンツタイプ
- 3(サービス・物件・メンバー)
- テンプレート
- 33件とアーカイブマッピング
- 利用者と権限
- 広報・編集部の2人(担当のブログだけ)
- 初期コンテンツ
- 記事20・データ14・ページ3、画像103点
- モックアップとの一致
- 47ページすべて
構築にかかった時間は約18分。設計書は約7分半、運用マニュアルは約37分でした (いずれも Claude Code の実行時間)。
途中で詰まったところ(API の項目名の取り違え、サイトの作成で既定のテンプレートが入る、など)は、 Claude Code が自分で原因を突き止めて直し、記録に残しました。分かった罠は mtb llm とスキルに追記してあるので、次の構築では最初から避けられます。
サイトを完成させるための CLI
名前のとおり、この道具の目的は Movable Type のサイトを組み立てることです。 API の形をそのまま見せず、サイトを作る作業に合わせた形にしています。
コマンドは公式定義から作られる
Movable Type が公開している Data API v7 の OpenAPI 定義から、226 のエンドポイントすべてにコマンドを用意しています。--help に出る説明文も公式のまま。手で書いたラッパーではないので、実装と仕様がずれません。
mtb sites entries list = GET /v7/sites/{site_id}/entries
API に無い機能を追加
ページ繰り、ディレクトリごとのアップロード、JSON を書かずに本体を組み立てる --set、1項目だけ取り出す --extract、テンプレートの往復。API の形のままでは、サイトを1つ完成させられないからです。
判断の基準は「サイトを1つ完成させられるか」
AI向けの知識を同梱している
mtb llm がエージェント向けの詳細リファレンスを出力します。認証・命名規則・ワークフロー・失敗モードまで入っていて、バイナリに埋め込まれているのでオフラインでも読めます。
mtb llm | 読ませるだけで前提が揃う
mtb を学ぶ
はじめてなら、チュートリアルで全体の流れをつかんでから、必要な作業のガイドを読むのが近道です。

まずはここから
チュートリアル
モックアップと原稿を受け取ったところから、Claude Code に設計書・サイト・運用マニュアルを作らせるまでを、実際の頼む文と結果で追います。
準備 → 設計書 → 構築 → 運用マニュアル
ガイド
インストールとサインインから、記事・テンプレート・テーマの扱い、公開、環境の移行まで。mtb の機能を作業ごとに説明します。
インストール・認証・データ・テンプレート・公開
ユースケース
サイトの新規構築、記事の一括修正、ステージングから本番への反映、棚卸し。仕事ごとに、どう頼み、どう確かめるかをまとめています。
構築・一括処理・移行・監査
リファレンス
コマンドの体系、共通のフラグ、環境変数、終了コードの一覧です。個々のパラメータは、各コマンドのヘルプで確かめます。
コマンド・フラグ・環境変数・終了コード
mtb Pro
管理画面でしかできなかった操作を、MT プラグインと拡張で mtb から行えるようにする商用版です。導入と運用の手順を載せています。
MT プラグイン+mtb の拡張
何を任せられるか
管理画面を人間が繰り返し触っていた仕事のうち、数が多いもの・環境をまたぐもの・ 取り違えると戻せないものから順に向いています。
サイトを一から組み立てる
要件を渡すと、サイト・カテゴリ・カスタムフィールド・テンプレートまで作ります。設計の考え方はスキルに入っています。
詳しく見る →
記事とページを一括で扱う
数百件の投入、書式を保ったままの一括修正、棚卸し。人間が管理画面で1件ずつ開く仕事ではありません。
詳しく見る →
ステージングを本番へ反映する
両方をダンプして diff で読める形にします。時間がかかるのは反映ではなく「どこが違うのかを突き止めること」です。
詳しく見る →
デザインを Git と CI で管理する
テンプレートをディレクトリへ書き出し、編集して戻す。変わったものだけを送るので、更新履歴を読めば何が変わったか分かります。
詳しく見る →
既存サイトを棚卸しする
引き継いだ MT に何が入っているのか。テンプレート・カスタムフィールド・プラグインまで、機械が読める形で書き出します。
詳しく見る →
日々の運用をエージェントに任せる
公開予約の点検、リンク切れの修正、画像の差し替え。終了コードで分岐できるので、自動化に組み込めます。
詳しく見る →
MTB-PRO
管理画面だけの操作も
コマンドで
Data API には、テーマを入れる・カスタムブロックを作る・新しい利用者を API で使えるようにする、 といったエンドポイントがありません。エージェントの作業はそこで止まり、人間が管理画面で操作することになります。
mtb-pro は MT プラグイン MtbPro が足すエンドポイントに mtb のコマンドを追加する拡張です。2つで1組で、MT サーバにプラグインを、 手元の mtb に拡張を入れます。上のデモは mtb だけで組んだので、管理画面での作業が人間に4つ残りました。mtb Pro があれば、その多くも任せられます。
運用に入ったら、危険なエンドポイントは MT の管理画面で無効にできます。Data API から有効に戻すことはできません。 MTB_AUDIT_NOTE を入れておけば、全リクエストが「何の作業か」付きで監査ログに残ります。
mtb-pro と MtbPro は商用です。
| できるようになること | コマンド |
|---|---|
| テーマをディレクトリごと MT に入れる | mtb themes files upload |
| ブロックエディタのカスタムブロックを作る | mtb sites block-editor blocks |
| Webサービスパスワードを発行する | mtb users api-password issue |
| 記事・ページの作成者を変える | mtb sites entries author update |
| アセットの中身を差し替える(ID と URL はそのまま) | mtb sites assets replace |
| .js や .html をサイトに置く | mtb sites files upload |
| サイトの Data API を許可する | mtb sites data-api update |
| 利用者の一括取り込み・LDAP の同期(MTA) | mtb users bulk / directory |
mtb extensions install ./mtb-plugin-pro mtb extensions check mtb-pro # MT 側にプラグインが入っているか export MTB_AUDIT_NOTE="リニューアル: テーマの差し替え" mtb audit-logs list --note リニューアル
CLAUDE CODE PLUGIN
CMS 設計の知識ごと入るプラグイン
プラグインを入れると、CLI の使い方だけでなく Movable Type で CMS を作る知識も入っています。 オブジェクトの選び分け、権限、アーカイブの設計、614 のテンプレートタグ。 タグの仕様は本文に書かず、必要なものだけを読み込む形にしています。
/plugin marketplace add ideamans/claude-public-plugins /plugin install mtb@ideamans-plugins
同じスキルは Copilot や Cursor など Agent Skills 対応ホストでも使えます。
プラグインの使い方 →| /mtb-install | mtb を PATH に用意する |
| /mtb-usage | CLI で MT を読み書きする手順 |
| /mtb-theme | テーマを Git のファイルとして開発し、サイトを起こす |
| /mtb-migrate | ある MT から別の MT へ、器を同期する |
| /mt-cms-design | 要件からサイトを設計して組み立てる |
| /mt-template-tags | テンプレートを書く(614タグ・48モディファイア) |
| /mtb-pro | 管理画面でしかできなかった操作と、監査ログ (mtb-pro に同梱) |
CLI の側で防いでいる落とし穴
Movable Type には「エラーにならないのに何も起きていない」という失敗の仕方が いくつもあります。エージェントは気づかないまま間違えるので、そこを CLI の側で対処しています。 デモを組む途中で見つけたものも、ここに足しています。
保存できた ≠ サイトに出た
MT は保存時に同期で再構築しますが、そこで失敗しても API は 200 を返します。--verify-publish はログを見比べ、書き出せていなければ終了コード 8 で止まります。
取得した本文で更新すると原稿が置き換わる
get が返す body は変換後の HTML です。Markdown やブロックエディタの記事に書き戻すと原稿が置き換わり、しかも見た目は正常なので誰も気づきません。編集のために取り出すなら --no-text-filter 1。
テーマは最初に適用する
テーマを適用すると、そのサイトのテンプレートは全件 backup 型にされ、アーカイブマッピングは消えます。作り込んだ後に適用すると URL 設計からやり直しです。mtb は --confirm でサイト名を入力させます。
再構築は1回では終わらない
Rebuilding は「受け付けた」という意味でしかありません。しかも startTime を返さないと restIds が永久に減りません。--wait は再構築が終わるまで続けます。
ページの更新でフォルダが外れる
状態だけ、タイトルだけの更新でも、folder を送らないとページはフォルダから外れます。basename が index なら、公開した瞬間にサイトのトップページを上書きします。mtb は警告を出し、スキルは毎回 folder を添えます。
success は「変わった」ではない
LDAP の同期は、設定が足りなくても success を返して何も変えません。失敗は MT のログにだけ残ります。mtb-pro の directory synchronize は変わったものとログの失敗を一緒に返します。
はじめる
バイナリを1つ置いて、接続先を登録して、サインインするだけです。 Claude Code から使うなら、インストールもスキルに任せられます。 /mtb-install が、入っていなければ mtb を入れます。
$ mtb profile add prod \ --base-url https://example.com/cgi-bin/mt/mt-data-api.cgi プロファイル prod を追加しました このままサインインしますか? (Y/n): $ mtb sites list --fields id,name,url { "items": [ { "id": "1", "name": "コーポレート", … }, { "id": "4", "name": "ブログ", … } ] }