Skip to content

AI エージェント向けガイド

スタート経路 A

このページは Agents(MCP) 経路の詳細です。全体の入口は クイックスタートAI Agents 概要 を参照してください。

このページでは、AI エージェント(Claude・GPT・Cursor など LLM ベースのシステム)が luno を使ってコンテンツを読み取り・作成・管理するための設定と API の使い方を説明します。

luno の AI 連携の概要

luno は以下の 3 つの方法で AI エージェントと連携できます。

方法認証用途
公開 API不要公開コンテンツの読み取り
MCP サーバーエージェント API キーClaude Code / Cursor / Codex での直接操作
エージェント APIエージェント API キー管理 API と同じルートをプログラムから呼び出し

MCP パッケージ: @luno-cms/mcpnpx -y @luno-cms/mcp

クライアント対応: Claude Code / Cursor / Codex はいずれも Verified(Golden Path E2E: テンプレ適用 → 作成・保存・公開 → ファネル計測)。

MCP サーバーのセットアップ

luno は Model Context Protocol(MCP) に対応しており、Claude Code / Cursor / Codex などから自然言語で CMS を操作できます。

パッケージ: @luno-cms/mcp — 手順の正本は npm の README です。

推奨: 既存サイト + Cursor / Claude Code / Codex

サイトリポジトリのルートで:

bash
cd my-existing-site
npx @luno-cms/mcp setup
# → 1) Claude Code  2) Cursor  3) Codex を選択
選択書き込まれるもの
Claude Code.claude/skills/luno/ + .mcp.json
Cursor.cursor/skills/luno/ + .cursor/mcp.json
Codex.agents/skills/luno/ + .codex/config.toml

キーの正本は .agents/luno/(gitignore。コミットされるのは *.example のみ):

ファイル用途
.agents/luno/dev.envローカル API(http://127.0.0.1:8787/admin
.agents/luno/stg.envstaging(https://stg-api.luno.rest/admin
.agents/luno/prod.envproduction(https://api.luno.rest/admin
.agents/luno/envいま有効な環境(env switch で更新)

*.env の中身:

bash
LUNO_API_URL=https://api.luno.rest/admin
LUNO_AGENT_KEY=sk-agent-xxxxxxxx

その後:

  1. 管理画面 設定 → エージェント API キー でキーを発行
  2. エージェントで /luno に貼るか、非対話で:
bash
npx @luno-cms/mcp env set-key stg 'sk-agent-…'
npx @luno-cms/mcp env switch stg
npx @luno-cms/mcp env status

MCP サーバー名: luno-dev / luno-stg / luno-prod
npx @luno-cms/mcp run stg.agents/luno/stg.env を読みます)

TIP

.agents/luno/*.envGit に入れないでください。環境・サイトごとにキーを分けるのが安全です。

セットアップ後 — クライアント別メモ

クライアントenv set-key / env switch のあと
Claude Codeツールが出ないときは MCP 再接続(/mcp
CursorSettings → MCPluno-stg を Enabled(緑)。既存チャットにツールが無いときは 新しい Agent チャット。キー未設定の luno-dev / luno-prod は Disabled のままでよい
Codexプロジェクト .codex/config.tomlcwd 付き)に加え、Codex は ~/.codex を優先する。npx @luno-cms/mcp setup --agent codexcodex mcp add luno-<env> --env LUNO_PROJECT_ROOT="<siteRoot>" -- npx -y @luno-cms/mcp run <env> を表示し、対話時は ~/.codex 登録を案内(--yes は表示のみ)。確認: codex mcp listluno-stg 等)。初回 MCP ツール呼び出しは 承認 が必要な場合あり。普段は luno-stg を優先

環境変数(MCP プロセスが読む値)

変数説明
LUNO_API_URLhttps://api.luno.rest/admin管理 API のベース(/admin まで含む、末尾スラッシュなし)
LUNO_AGENT_KEYsk-agent-…管理画面で発行したエージェント API キー

キーは MCP JSON に直書きせず、.agents/luno/{dev,stg,prod}.env に置くのを推奨します。ローカル API は http://127.0.0.1:8787/admin

代替: MCP 設定の env に直書き(Claude Desktop / 一時利用)

setup / .agents/luno/ を使わない場合は、クライアント設定に変数を直接書けます。

Claude Desktop — macOS: ~/Library/Application Support/Claude/claude_desktop_config.json / Windows: %APPDATA%\Claude\claude_desktop_config.json

json
{
  "mcpServers": {
    "luno": {
      "command": "npx",
      "args": ["-y", "@luno-cms/mcp"],
      "env": {
        "LUNO_API_URL": "https://api.luno.rest/admin",
        "LUNO_AGENT_KEY": "sk-agent-xxxxxxxx"
      }
    }
  }
}

Cursor — Settings → MCP、またはプロジェクトの .cursor/mcp.json に同様の形。キー発行後、管理画面 設定 → エージェント API キー にも貼り付け用スニペットが出ます。

日常のサイト開発では npx @luno-cms/mcp setup を使い、キーを .agents/luno/ に置いて dev / stg / prod を切り替えてください。

エージェント向けトラブルシュート

症状想定原因次の一手同入力で再試行?
slug / name 欠落・不正(ツール引数)必須引数不足ツール説明どおり必須を埋めるNo
Slug already exists for this tenant(+ hintForm Set slug 衝突list_form_sets か別 slugNo
Slug already exists for this form setエントリ slug 衝突list_entries か別 slugNo
REVISION_CONFLICT / revision mismatch古い revision / revisionRowIdlist_revisionssave_revisionidrevisionpublish_revision に渡すNo
401 / Invalid agent keyキー誤り・未設定npx @luno-cms/mcp env set-key … のあと MCP 再接続No
429 / RATE_LIMITEDキーごとのレート制限超過Retry-After 秒待って再試行。連続ツール呼び出しを間引くYes(待機後)
create 後のタイムアウトネットワーク / クライアント中断同じ idempotencyKey で再送Yes(キー付き create 系)

API エラーには任意で error.hint / error.retryable が付くことがあります(OpenAPI ApiError)。retryable: false のときは入力を変えてから再実行。

冪等キー(任意)

管理画面はキーを送りません。キーなしの挙動は従来どおりです。エージェントは主要 create に idempotencyKey(または Idempotency-Key ヘッダ)を付けられます。

MCP ツールキーなし同一キー再送
apply_form_blueprint / apply_builtin_form_template作成 / slug 衝突は 409同じ 201 本文
create_entry新規 / 409同じ entry id
save_revision常に新リビジョン同じ revision 行
create_contact_form新規 / 409同じ id
publish_revision既存の already_published + outbox 重複排除(追加キー不要)

エージェント API キーの発行

管理 API(MCP 含む)を呼ぶには エージェント API キーが必要です。

  1. 管理画面 設定 → エージェント API キー新規作成
  2. 名前(例: Claude Agent)を入力
  3. スコープを選択(下表参照)
  4. 表示されたキー(sk-agent-…)を必ずコピー(再表示不可)

キーの管理

GitHub・フロントエンドのコード・チャットに貼り付けないでください。環境変数またはシークレット管理ツールで保管してください。

キーのスコープ

各キーには scope があり、操作可能な API が決まります。キーは発行したプロジェクトに固定され、X-Project-Id は不要です。

スコープ用途できること
full(推奨)記事 + スキーマ設定エントリ・メディア・Form Set / Contact / Blueprint
content記事のみスキーマ読み取り、エントリ作成・更新、リビジョン保存・公開、メディア一覧
schema互換エイリアスfull と同権限

推奨フロー

  1. 普段は full キー(記事だけに絞るなら content
  2. 必要なら Blueprint / テンプレ適用用に短期キーを使い、終わったら revoke

エージェントキーでは不可(スコープ問わず)

  • Form Set / Contact Form の削除
  • フォームブロック / フィールド定義の削除
  • 他 API キーの発行、メンバー招待、課金・SNS 設定の変更

content キーで Blueprint 適用などを呼ぶと 403 Forbidden になります。

レート制限

エージェント API キー(sk-agent-…)で認証した Admin API リクエストに per-key のレート制限があります。JWT コンソールセッションは対象外です。

プラン有効キー数リクエスト / ウィンドウ(キーごと)
Free / Solo160 / 60 秒
Standard / Business / Enterprise複数可300 / 60 秒

超過時:

  • HTTP 429
  • エラーコード RATE_LIMITED
  • レスポンスヘッダ Retry-After(ウィンドウ残り秒数・best-effort)

Workers isolate 内の in-memory カウンタで適用(best-effort — isolate 間で厳密共有されない)。通常の MCP / Golden Path 利用では Free でも上限に達しにくい想定です。

429 の扱い

Retry-After 秒待ってから再試行してください。連続ツール呼び出しは間引き、get_project_overview やページング付き list_entries で読み取りをまとめると安全です。

MCP ツール一覧

@luno-cms/mcp が提供するツール(正本は npm README):

既存プロジェクトを再開するとき

  1. get_project_overview — 何があるかの要約(推奨・最初)
  2. 必要なら get_form_set_schema / list_entries
  3. 新規サイト作成の Golden Path(builtin template → entry → publish)とは別

コンテンツ(content / full

ツール説明
get_project_overviewプロジェクト要約(Form Sets / Contact / Masters / storage / ログイン見た目 / IP allowlist / locales / 公開 API)
get_tenant_schemaプロジェクト全体のスキーマ
list_form_sets / get_form_set_schemaForm Set 一覧・フィールド定義(select 等の masterEntityKey / sampleValues 含む)
get_public_api_infoprojectId と公開 API ベース URL(/public/p/{projectId}/v1
list_entries / get_entryエントリ一覧・詳細
create_entry / update_entryエントリ作成・slug 更新
list_revisions / save_revision / publish_revisionリビジョン操作
submit_entry_for_review承認申請
list_media / upload_mediaメディア一覧・アップロード(filePath / sourceUrl / base64
list_master_entities / get_master_entityマスタエンティティ
list_master_records / create_master_recordマスタレコード参照・作成
update_master_record / update_master_treeマスタ更新(エージェントキー不可 — ユーザ JWT が必要)
get_project_content_localesサイト多言語設定の取得
patch_project_content_locales多言語設定の更新(tenant_admin JWT のみ
translate_entry_localesAI ロケール一括翻訳(Standard+
search_admin_help / get_admin_help_article / ask_admin_help管理画面ヘルプ KB
get_login_branding / get_login_appearance / update_login_appearanceログイン見た目
list_console_login_ip_allowlists / add_… / delete_…ログイン IP 許可リスト(Business+

スキーマセットアップ(full / schema 必須

ツール管理 API
apply_form_blueprintPOST /admin/v1/form-blueprints/apply
validate_master_blueprint / apply_master_blueprintマスタ Blueprint の検証・適用
apply_builtin_form_templatePOST /admin/v1/form-set-templates/:id/apply
create_contact_form / update_contact_formContact Form 作成・更新(autoreply_* 可)

dryRun(スキーマ適用のプレビュー)

apply_form_blueprintapply_master_blueprintapply_builtin_form_templatedryRun: true を渡せます。DB に書き込まずプレビューが返ります。

CLI: hcms form apply --dry-run / hcms template apply --dry-run

llms.txt

各サイトは llms.txt 仕様 に沿ったエンドポイントで、公開済みコンテンツの一覧を返します。

bash
curl https://api.luno.rest/public/v1/llms.txt
# プロジェクトの公開ホストでも同様:
curl https://your-domain.com/public/v1/llms.txt

システムプロンプトに含めると、エージェントが利用可能なコンテンツを把握できます。

[システムプロンプト例]
あなたは luno CMS のコンテンツ管理を支援する AI アシスタントです。
以下が公開コンテンツの一覧です。

{llms.txt の内容}

公開 API で読み取り、MCP 経由で下書きを作成してください。

API の詳細仕様は 公開 API リファレンス および本ページを参照してください。

公開 API での読み取り(認証不要)

公開 API ベース: https://{your-domain}/public/v1

コンテンツ構造の把握

bash
curl https://your-domain.com/public/v1/llms.txt
curl https://your-domain.com/public/v1/sitemap.xml

エントリ一覧の取得

bash
curl "https://api.luno.rest/public/p/{projectId}/v1/form-sets/blog/entries?include_snapshot=true&limit=10"
ts
const BASE = 'https://api.luno.rest/public/p/{projectId}/v1'
const res = await fetch(
  `${BASE}/form-sets/blog/entries?include_snapshot=true&limit=10`
)
const data = await res.json()
bash
npx @luno-cms/mcp setup
# エージェント例: 「blog の公開エントリを 10 件、本文付きで一覧して」

Python でのページング処理

python
import httpx
import asyncio

BASE_URL = "https://your-domain.com/public/v1"

async def fetch_all_entries(form_set_slug: str) -> list[dict]:
    all_items = []
    page = 1
    limit = 100

    async with httpx.AsyncClient() as client:
        while True:
            res = await client.get(
                f"{BASE_URL}/form-sets/{form_set_slug}/entries",
                params={"page": page, "limit": limit, "include_snapshot": "true"},
            )
            res.raise_for_status()
            data = res.json()
            all_items.extend(data["items"])
            if data["offset"] + limit >= data["total"]:
                break
            page += 1

    return all_items

エージェント API でのコンテンツ操作

エージェント API ベース: https://{your-domain}/admin/v1
認証: Authorization: Bearer sk-agent-…

フォームセット一覧

bash
curl https://api.luno.rest/admin/v1/form-sets \
  -H "Authorization: Bearer sk-agent-xxxxxxxx"

エントリの作成

bash
curl -X POST https://api.luno.rest/admin/v1/form-sets/{formSetId}/entries \
  -H "Authorization: Bearer sk-agent-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "ai-generated-post-2025-01",
    "fields": {
      "title": "AI が自動生成した記事",
      "body": "<p>コンテンツ本文...</p>"
    }
  }'

公開

MCP の publish_revision を使うか、管理 API を直接呼びます。

bash
curl -X POST https://api.luno.rest/admin/v1/revisions/{revisionId}/publish \
  -H "Authorization: Bearer sk-agent-xxxxxxxx"

Claude との会話例

コンテンツの確認

ユーザー: luno のブログ記事を最新 5 件表示して
Claude: [MCP で取得] 以下が最新のブログ記事です…

コンテンツの作成

ユーザー: 「Cloudflare Workers の基本」というタイトルで下書きを作成して
Claude: [MCP でエントリ作成] 下書きを作成しました。slug: cloudflare-workers-basics

初期セットアップ(schema キー)

ユーザー: blog テンプレを適用して、お問い合わせフォームも作って
Claude: [apply_builtin_form_templatecreate_contact_form を実行] セットアップ完了しました

フィールド値の型リファレンス

フィールドタイプ値の型
text / urlstring"タイトルです" / "https://…"
textareastring"複数行\nテキスト"
tiptapTiptap doc(JSON) または string"<p>本文</p>"
numbernumber42
booleanbooleantrue
datestring または { from, to }"2025-01-15"
select / radiostring(マスタの value"news"
multiselectstring[]["tag1", "tag2"]
image / filestring(asset UUID)"550e8400-..."
image_galleryUUID 文字列、または { assetId, caption? }[][{ "assetId": "…" }]
video_embedstring(URL)"https://youtube.com/..."
entry_refstring(参照エントリ UUID"7c9e6679-..."

エラーハンドリング

HTTP ステータスコード対処方法
400VALIDATION_ERRORパラメータを確認して修正
401UNAUTHORIZEDキーが無効・失効・未設定
429RATE_LIMITEDRetry-After 秒待って再試行。並列ツール呼び出しを減らす
403FORBIDDENスコープ不足(例: content キーで Blueprint 適用)
403PLAN_REQUIRED全文検索(q)は Business プラン以上
404NOT_FOUNDslug が正しいか確認
301slug 変更。Location へ再リクエスト
304未変更。ETag キャッシュを使用

ベストプラクティス

  1. llms.txt で公開コンテンツの全体像を把握する
  2. 普段は full — 記事だけに絞るなら content。短期のセットアップキーは終わったら revoke
  3. include_snapshot=true で一覧取得し、個別 GET を減らす
  4. 301 リダイレクトに従う(slug 変更時)
  5. ETag / If-None-Match でリクエスト数を節約する
  6. 公開前に人間がレビュー — draft → pending_review → published を推奨

次のステップ