mcpField
G
ghost

ghost

github.com/magnus919マーケティング・グロース15757 回インストール今日更新
リポジトリ

ghost について

稼働中の Ghost CMS サイトを Admin API 経由で管理するコマンドラインスキルです。投稿、ページ、タグの作成や公開、編集、エクスポートに加え、下書きや予約投稿も確認できます。

主な機能

  1. 01投稿、ページ、タグの閲覧
  2. 02下書きと予約投稿の確認
  3. 03コンテンツの作成、公開、予約
  4. 04投稿の編集と削除
  5. 05JSON 出力とドライラン計画

活用シーン

  1. 01下書きや予約投稿の確認
  2. 02Ghost の投稿やページの作成・公開
  3. 03投稿データのページ分割エクスポート
  4. 04スクリプトからのタグ管理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/magnus919/agent-skills --skill ghost

インストール後、Claude Code で/ghostを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
evals/
evals.json
references/
admin-auth-and-basics.md
content-vs-admin-api.md
gotchas-field-guide.md
posts-pages-tags-endpoints.md
worked-recipes.md
scripts/
ghost
test_ghost.py

詳細

ghost — ターミナルから Ghost CMS のコンテンツを操作

Ghost CMS サイトの Admin API(v5/v6、Accept-Version: v6.0)を操作します。ステータス別の投稿一覧表示(下書きを含む)、固定ページや投稿の作成・公開、タグの管理、サイト情報の確認ができます。リクエストごとに id:secret のインテグレーションキーから Admin JWT を生成して認証するため、下書き、予約投稿、公開済みコンテンツをすべて確認できます。

セットアップ

export GHOST_URL="https://your-ghost-site.com"
export GHOST_ADMIN_KEY="<RECORD_KEY>"   # id:secret from Ghost Admin → Integrations
  1. Ghost Admin → Settings → Integrations で、カスタムインテグレーションを作成(または開き)ます。
  2. Admin API Key をコピーします。これはコロンで区切られた 2 つの 16 進数部分(id:secret)からなる 1 つの文字列です。同じ画面にある別の Content API key では下書きを確認できません。詳しくは「既知の注意点」を参照してください。
  3. リクエスト時に、CLI は呼び出しごとに有効期間の短い JWT に署名します。署名には、secret 部分を 16 進数から生バイト列にデコードした後、HS256 で使用します。kid ヘッダーには id 部分を設定し、audience は /admin/、exp は iat の 5 分後とし、Authorization: Ghost <token> として送信します。トークンを自分で扱う必要はありません。
  4. --help と --dry-run は、認証情報なしで実行できます(認証は遅延実行されます)。

基本コマンド

確認
ghost site                       # title, url, description, version
ghost get-post POST_ID           # full record incl. exact updated_at for edits
閲覧(目的:コンテンツを探す)
ghost posts                                   # latest 20
ghost posts --status draft                    # unpublished work queue
ghost posts --status scheduled                # what publishes next
ghost posts --limit 100 --page 2              # paginate (max page size 100)
ghost posts --order "updated_at desc"         # SQL-style ordering
ghost pages                                   # static pages
ghost tags                                    # tags with usage counts
作成と公開
ghost create-post --title "Notes"                              # safe default: draft
ghost create-post --title "Hello" --html "<p>Hi</p>"
ghost create-post --title "Launch" --status published --html "<p>We're live</p>"
ghost create-post --title "Later" --status scheduled \
  --published-at "2026-09-01T09:00:00.000Z"                    # future ISO-8601 required together
ghost create-page --title "About" --html "<p>…</p>" --slug about
ghost create-tag --name "Engineering" --description "Technical posts"
編集と削除
ghost update-post POST_ID --title "New title" \
  --updated-at "<RECORD_UPDATED_AT>"          # REQUIRED: latest updated_at, re-read first
ghost update-post POST_ID --status published --updated-at "<RECORD_UPDATED_AT>"
ghost delete-post POST_ID                     # permanent, 204-style removal

パイプラインのレシピ

まず下書きし、レビュー後に公開する
ghost --json create-post --title "Release notes" > /tmp/post.json
id=$(jq -r '.post.id // .post_id // empty' /tmp/post.json)
ghost get-post "$id"                          # read fresh updated_at
ghost update-post "$id" --status published \
  --updated-at "<exact string from get-post output>"

updated_at を捏造しないでください。直近の読み取り結果からそのままコピーしてください。そうしないと、Ghost は HTTP 409 UpdateCollisionError を返して編集を拒否します。

ステータス横断のレビューキュー
for s in draft scheduled; do
  ghost posts --status "$s" --json | jq -r '.posts[] | "\(.status)\t\(.title)\t\(.slug)"'
done
完全なエクスポート

合計数を鵜呑みにせず、meta.pagination.next(.page.next として取得可能)を使ってページを繰り返し処理します。

page=1
while :; do
  ghost posts --limit 100 --page "$page" --json > "/tmp/posts-$page.json"
  jq -r '.posts[].id' "/tmp/posts-$page.json"
  next=$(jq -r '.page.next // empty' "/tmp/posts-$page.json")
  [ -z "$next" ] && break
  page=$next; sleep 0.2
done

JSON 出力と jq

--json はサブコマンドの前後どちらにも指定できます。

ghost --json posts        # same as: ghost posts --json

知っておくと便利な JSON の形式:

  • 一覧は {"total", "page": {pagination}, "posts": [...]} を出力します。詳細取得/作成では、リソースはその名詞(post、page、tag、site)の下に格納されます。
  • ページネーションは API と同じ形式です。.page = {"page", "limit", "pages", "total", "next", "prev"} となり、next/prev は数値または null です。
  • --dry-run --json は結果の代わりに、実行予定の内容を出力します。{"dry_run": true, "method", "url", "params"/"json"} の形式で、実行前に正確なリクエストを確認できます。
  • エラーが発生すると、API 独自のメッセージとコードを標準エラーに出力し、ゼロ以外の終了コードで終了します。JSON モードでも、エラーを標準出力の JSON でラップすることはありません。

グローバルフラグ

フラグ効果
--json機械可読な JSON(指定位置に依存しません)
--dry-run実行せずに、予定されている API 呼び出し(メソッド、URL、ペイロード)を表示します
--quiet診断メッセージを抑制します
--verboseデバッグログを出力します

既知の注意点

  • 下書きにはAdminプレーンが必要です。 公開Content API(キーをクエリパラメーターとして渡すAPI)が返すのは公開済みの投稿だけで、下書きは通知なしに除外されます。有効なキーを使っていても、エラーではなく単に結果に含まれません。status:draft などのフィルターも拒否されず、無視されます。このCLIの処理がすべてAdmin API経由なのは、下書きや予約投稿にも確実にアクセスできるようにするためです。
  • 同じ連携画面に2種類のキーがあります。 Contentキーはブラウザーで安全に使えますが、公開データの読み取り専用です。Adminキー(GHOST_ADMIN_KEY)は変更操作の署名に使われ、下書きにもアクセスできます。下書きが見えることを期待して、スクリプトにContentキーを指定しないでください。
  • トークンの有効期間は5分です。 各JWTの有効期間は最大300秒(exp ≤ iat + 300)で、検証側でもトークンの経過時間に上限があるため、長時間のバッチジョブではリクエストごとに再署名する必要があります(CLIがこれを行います)。時計がずれていると署名可能な期間に支障が出るため、NTPを正常に保ってください。
  • HS256のみ対応し、キーにはデコード済みシークレットを使います。 HS512で署名したトークンは拒否されます(「invalid algorithm」)。シークレットを先に16進デコードせずに署名すると、「一見有効そうな」不正な値となり、401が返されます。CLIはどちらのルールにも対応しています。
  • Authorization: Ghostを使い、Bearerは使いません。 Bearerスキームでは401 INVALID_AUTH_HEADERが返されます。
  • 編集には競合防止策が必要です。 投稿の現在のupdated_atを指定しないPUTは409で失敗します。関連配列(tags、authors)はマージではなく、全体が置き換えられます。
  • --htmlにはsource=htmlが必要で、変換時に情報が失われます。 htmlペイロードを含むすべての書き込み(create-post、update-post、create-page)では、?source=htmlクエリーフラグを送信する必要があります。CLIは自動的に付与し、ドライランのプランではparamsに表示されます。指定しないと、Ghostは本文をmobiledoc/lexicalとして解析します。フラグを指定しても変換時に情報が失われるため、適切なLexicalを送信するか、固定のマークアップをHTMLカードコメントで囲んでください。
  • Ghost 6ではlimit=allが削除されたため、ページネーションの上限は100です。 上限を超える値を指定しても、エラーなしで最大100行が返されます。必ずnextを使ってループしてください。
  • 削除は取り消せず、公開サイトにも即座に反映されます。

使用する場面

稼働中のGhostサイトでコンテンツのワークフローを実行するタスクでは、このスキルを使用してください。投稿の閲覧やエクスポート、下書きの作成、公開、予約、タグの管理、ページの作成、これらの処理に関する問題(認証エラー、ページネーション、下書きが表示されないなど)の診断が対象です。

使用しない場面

Ghostサーバーのインストール、ホスティング、運用(ghost install、nginx/SSL/systemdの設定、アップグレード、バックアップ)には使用しないでください。これらはGhost公式のnpm製サイト管理ツールであるghost-cliの対象であり、名前が共通しているだけで無関係です。ほかの公開プラットフォーム(WordPressやHugoには独自のツールがあります)、テーマ開発、Adminダッシュボードで一度設定すればよいサイト設定(スタッフアカウント、メンバーシップの階層)にも使用しないでください。

参考ファイル

ファイル用途
references/admin-auth-and-basics.mdJWT署名の詳細な手順、キー形式、audience/有効期限のルール、認証エラー一覧
references/content-vs-admin-api.mdどちらのプレーンを選ぶか、下書きが表示されない落とし穴、診断チェックリスト
references/posts-pages-tags-endpoints.mdエンドポイント一覧、フィールドの意味、ページネーションのループ、エラー形式
references/worked-recipes.mdコピーして使えるワークフロー:下書き→公開、エクスポート、予約、トリアージ
references/gotchas-field-guide.md認証、編集、件数に関する問題を症状から検索できるインシデントガイド

スクリプトと前提条件

  • scripts/ghost — 実行可能なPython CLI(標準ライブラリとrequestsのみ)。上記のフラグに対応し、認証は必要時に行い、構造化ログを出力します。
  • scripts/test_ghost.py — オフラインのテストスイート(HTTPをモックし、ネットワークアクセスは不要)。
  • Python 3.8以降、requests。待ち受け処理やインストールはなく、対象はGHOST_URLで設定した1つのサイトに限られます。

コメント