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/mcp(npx -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
サイトリポジトリのルートで:
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.env | staging(https://stg-api.luno.rest/admin) |
.agents/luno/prod.env | production(https://api.luno.rest/admin) |
.agents/luno/env | いま有効な環境(env switch で更新) |
各 *.env の中身:
LUNO_API_URL=https://api.luno.rest/admin
LUNO_AGENT_KEY=sk-agent-xxxxxxxxその後:
- 管理画面 設定 → エージェント API キー でキーを発行
- エージェントで
/lunoに貼るか、非対話で:
npx @luno-cms/mcp env set-key stg 'sk-agent-…'
npx @luno-cms/mcp env switch stg
npx @luno-cms/mcp env statusMCP サーバー名: luno-dev / luno-stg / luno-prod
(npx @luno-cms/mcp run stg は .agents/luno/stg.env を読みます)
TIP
.agents/luno/*.env は Git に入れないでください。環境・サイトごとにキーを分けるのが安全です。
セットアップ後 — クライアント別メモ
| クライアント | env set-key / env switch のあと |
|---|---|
| Claude Code | ツールが出ないときは MCP 再接続(/mcp) |
| Cursor | Settings → MCP で luno-stg を Enabled(緑)。既存チャットにツールが無いときは 新しい Agent チャット。キー未設定の luno-dev / luno-prod は Disabled のままでよい |
| Codex | プロジェクト .codex/config.toml(cwd 付き)に加え、Codex は ~/.codex を優先する。npx @luno-cms/mcp setup --agent codex は codex mcp add luno-<env> --env LUNO_PROJECT_ROOT="<siteRoot>" -- npx -y @luno-cms/mcp run <env> を表示し、対話時は ~/.codex 登録を案内(--yes は表示のみ)。確認: codex mcp list(luno-stg 等)。初回 MCP ツール呼び出しは 承認 が必要な場合あり。普段は luno-stg を優先 |
環境変数(MCP プロセスが読む値)
| 変数 | 例 | 説明 |
|---|---|---|
LUNO_API_URL | https://api.luno.rest/admin | 管理 API のベース(/admin まで含む、末尾スラッシュなし) |
LUNO_AGENT_KEY | sk-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
{
"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(+ hint) | Form Set slug 衝突 | list_form_sets か別 slug | No |
Slug already exists for this form set | エントリ slug 衝突 | list_entries か別 slug | No |
REVISION_CONFLICT / revision mismatch | 古い revision / revisionRowId | list_revisions;save_revision の id と revision を publish_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 キーが必要です。
- 管理画面 設定 → エージェント API キー → 新規作成
- 名前(例:
Claude Agent)を入力 - スコープを選択(下表参照)
- 表示されたキー(
sk-agent-…)を必ずコピー(再表示不可)
キーの管理
GitHub・フロントエンドのコード・チャットに貼り付けないでください。環境変数またはシークレット管理ツールで保管してください。
キーのスコープ
各キーには scope があり、操作可能な API が決まります。キーは発行したプロジェクトに固定され、X-Project-Id は不要です。
| スコープ | 用途 | できること |
|---|---|---|
full(推奨) | 記事 + スキーマ設定 | エントリ・メディア・Form Set / Contact / Blueprint |
content | 記事のみ | スキーマ読み取り、エントリ作成・更新、リビジョン保存・公開、メディア一覧 |
schema | 互換エイリアス | full と同権限 |
推奨フロー
- 普段は
fullキー(記事だけに絞るならcontent) - 必要なら Blueprint / テンプレ適用用に短期キーを使い、終わったら revoke
エージェントキーでは不可(スコープ問わず)
- Form Set / Contact Form の削除
- フォームブロック / フィールド定義の削除
- 他 API キーの発行、メンバー招待、課金・SNS 設定の変更
content キーで Blueprint 適用などを呼ぶと 403 Forbidden になります。
レート制限
エージェント API キー(sk-agent-…)で認証した Admin API リクエストに per-key のレート制限があります。JWT コンソールセッションは対象外です。
| プラン | 有効キー数 | リクエスト / ウィンドウ(キーごと) |
|---|---|---|
| Free / Solo | 1 | 60 / 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):
既存プロジェクトを再開するとき
get_project_overview— 何があるかの要約(推奨・最初)- 必要なら
get_form_set_schema/list_entries - 新規サイト作成の 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_schema | Form Set 一覧・フィールド定義(select 等の masterEntityKey / sampleValues 含む) |
get_public_api_info | projectId と公開 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_locales | AI ロケール一括翻訳(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_blueprint | POST /admin/v1/form-blueprints/apply |
validate_master_blueprint / apply_master_blueprint | マスタ Blueprint の検証・適用 |
apply_builtin_form_template | POST /admin/v1/form-set-templates/:id/apply |
create_contact_form / update_contact_form | Contact Form 作成・更新(autoreply_* 可) |
dryRun(スキーマ適用のプレビュー)
apply_form_blueprint・apply_master_blueprint・apply_builtin_form_template は dryRun: true を渡せます。DB に書き込まずプレビューが返ります。
CLI: hcms form apply --dry-run / hcms template apply --dry-run
llms.txt
各サイトは llms.txt 仕様 に沿ったエンドポイントで、公開済みコンテンツの一覧を返します。
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
コンテンツ構造の把握
curl https://your-domain.com/public/v1/llms.txt
curl https://your-domain.com/public/v1/sitemap.xmlエントリ一覧の取得
curl "https://api.luno.rest/public/p/{projectId}/v1/form-sets/blog/entries?include_snapshot=true&limit=10"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()npx @luno-cms/mcp setup
# エージェント例: 「blog の公開エントリを 10 件、本文付きで一覧して」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-…
フォームセット一覧
curl https://api.luno.rest/admin/v1/form-sets \
-H "Authorization: Bearer sk-agent-xxxxxxxx"エントリの作成
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 を直接呼びます。
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_templateとcreate_contact_formを実行] セットアップ完了しました
フィールド値の型リファレンス
| フィールドタイプ | 値の型 | 例 |
|---|---|---|
text / url | string | "タイトルです" / "https://…" |
textarea | string | "複数行\nテキスト" |
tiptap | Tiptap doc(JSON) または string | "<p>本文</p>" |
number | number | 42 |
boolean | boolean | true |
date | string または { from, to } | "2025-01-15" |
select / radio | string(マスタの value) | "news" |
multiselect | string[] | ["tag1", "tag2"] |
image / file | string(asset UUID) | "550e8400-..." |
image_gallery | UUID 文字列、または { assetId, caption? }[] | [{ "assetId": "…" }] |
video_embed | string(URL) | "https://youtube.com/..." |
entry_ref | string(参照エントリ UUID) | "7c9e6679-..." |
エラーハンドリング
| HTTP ステータス | コード | 対処方法 |
|---|---|---|
| 400 | VALIDATION_ERROR | パラメータを確認して修正 |
| 401 | UNAUTHORIZED | キーが無効・失効・未設定 |
| 429 | RATE_LIMITED | Retry-After 秒待って再試行。並列ツール呼び出しを減らす |
| 403 | FORBIDDEN | スコープ不足(例: content キーで Blueprint 適用) |
| 403 | PLAN_REQUIRED | 全文検索(q)は Business プラン以上 |
| 404 | NOT_FOUND | slug が正しいか確認 |
| 301 | — | slug 変更。Location へ再リクエスト |
| 304 | — | 未変更。ETag キャッシュを使用 |
ベストプラクティス
llms.txtで公開コンテンツの全体像を把握する- 普段は
full— 記事だけに絞るならcontent。短期のセットアップキーは終わったら revoke include_snapshot=trueで一覧取得し、個別 GET を減らす- 301 リダイレクトに従う(slug 変更時)
ETag/If-None-Matchでリクエスト数を節約する- 公開前に人間がレビュー — draft → pending_review → published を推奨
次のステップ
- AI アシスト — 管理画面での AI 機能
- 公開 API リファレンス — 全エンドポイントの仕様
- API 概要 — 認証・エラーコードの詳細
- npm: @luno-cms/mcp — MCP サーバーパッケージ