Skip to content

クイックスタート

LUNO は free な AI 時代の backend platform(Headless CMS・フォーム・secure API)です。Cloudflare Workers 上で、目的に合わせて次のどれかから始めてください。

経路を選ぶ

経路向いている人所要完成形 → 入口
A. Agents(MCP)Cursor / Claude Code / Codex で触りたい約 5 分完成形概要
B. Console管理画面で作成・承認・公開を理解したい約 10 分完成形手順
C. API only公開コンテンツを読む・サイトに繋ぐだけ約 3 分完成形公開 API
bash
# 経路 A(推奨・最短)
npx @luno-cms/mcp setup

経路 B の手順は以下です。経路 A / C は上のリンク先へ進んでください。

Console で始める

管理画面にログインし、最初のエントリを公開して公開 API から取得できる状態にします。

ステップ 1:管理画面にログイン

luno の管理画面 URL(例: https://cms.example.com)にアクセスします。

ログイン方法はプロジェクトの設定によって異なります:

方法説明
メール + パスワード管理者から届いた招待メールのリンクからパスワードを設定してログイン
Google アカウント「Google でログイン」ボタンをクリックして OAuth 認証

招待メールが届いていない場合

プロジェクトの管理者に連絡して、あなたのメールアドレスへの招待を送ってもらってください。

ステップ 2:画面構成を確認する

ログイン後、左のサイドバーにナビゲーションが表示されます。

メニュー説明
ダッシュボード公開数・下書き数・最近の更新サマリー
フォームセット名各コンテンツ種別のエントリ一覧(例:ブログ、お知らせ)
メディア画像・ファイルのアップロード管理
マスタデータカテゴリ・タグなど共通参照データの管理
お問い合わせコンタクトフォームの受信管理
メンバープロジェクトメンバーの招待・ロール設定
ウィジェット外部サイト埋め込みコンテンツの設定
設定フォームセット・Webhook・API キーなどの設定

ステップ 3:最初のエントリを作成する

フォームセットを選ぶ

サイドバーから目的のフォームセット(例:「ブログ」「お知らせ」)をクリックします。フォームセットはコンテンツの型定義です。管理者が事前に作成してあります。

エントリを新規作成する

「新規エントリ」ボタンをクリックして各フィールドに値を入力します。

  • テキストフィールド:タイトルや説明文を入力
  • リッチテキスト(tiptap):見出し・箇条書き・リンクを含む本文を編集
  • メディアフィールド:画像をアップロードしてコンテンツに紐付け

入力が完了したら「保存」をクリックします。エントリは 下書き(draft) として保存されます。

レビュー申請 → 承認 → 公開

保存後、右上のステータスボタンから公開フローを進めます:

下書き → レビュー申請 → 承認 → 公開済み
  1. レビュー申請(submit_for_review):担当レビュアーに確認を依頼します。
  2. 承認(approve):レビュアーがコンテンツを確認して承認します。
    • 「今すぐ公開」→ ステータスが 公開済み(published) になります
    • 「スケジュール公開」→ 指定日時に自動公開されます
  3. 公開済み:公開 API からコンテンツが取得できるようになります。

ロールについて

tenant_admin(管理者)はすべての操作が可能です。tenant_user(一般ユーザー)はレビュー申請まで操作できます。詳細はコンテンツ管理を参照してください。

ステップ 4:公開 API でデータを取得する

公開後すぐに、認証なしで公開 API からコンテンツを取得できます。本番では /public/p/{projectId}/v1 を推奨します。

エントリ一覧を取得する

bash
# 推奨: projectId 固定ベース
curl "https://api.luno.rest/public/p/{projectId}/v1/form-sets/blog/entries?include_snapshot=true"

# Host 解決(公開ホストがある場合)
curl "https://cms.example.com/public/v1/form-sets/blog/entries?include_snapshot=true"
ts
const BASE = 'https://api.luno.rest/public/p/{projectId}/v1'

const res = await fetch(
  `${BASE}/form-sets/blog/entries?include_snapshot=true`
)
if (!res.ok) throw new Error(`API error: ${res.status}`)
const { items } = await res.json()
bash
# サイトリポジトリで一度だけ
npx @luno-cms/mcp setup

# エージェントに例:
# 「blog フォームセットの公開エントリを一覧して」
# MCP が Public API / Admin API 経由で取得します

レスポンス例:

json
{
  "formSet": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "slug": "blog",
    "name": "ブログ"
  },
  "total": 1,
  "limit": 20,
  "offset": 0,
  "items": [
    {
      "entry": {
        "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "slug": "my-first-post"
      },
      "published": {
        "revisionId": "a2f3d4e5-...",
        "revision": 1,
        "updatedAt": "2025-01-15T10:00:00Z"
      }
    }
  ]
}

特定エントリを全フィールド付きで取得する

bash
curl "https://api.luno.rest/public/p/{projectId}/v1/form-sets/blog/entries/my-first-post?include_snapshot=true"
ts
const BASE = 'https://api.luno.rest/public/p/{projectId}/v1'

async function getPost(slug: string) {
  const res = await fetch(
    `${BASE}/form-sets/blog/entries/${slug}?include_snapshot=true`
  )
  if (!res.ok) {
    if (res.status === 404) throw new Error('記事が見つかりません')
    throw new Error(`API error: ${res.status}`)
  }
  return res.json()
}
bash
# エージェントに例:
# 「slug my-first-post の公開本文を取得して」

レスポンス例:

json
{
  "formSet": { "slug": "blog", "name": "ブログ" },
  "entry": { "id": "...", "slug": "my-first-post" },
  "revision": { "revision": 1, "updatedAt": "2025-01-15T10:00:00Z" },
  "data": {
    "title": "はじめての投稿",
    "body": "<p>こんにちは、世界!</p>",
    "cover": "asset-uuid-here",
    "published_date": "2025-01-15"
  },
  "mediaUrls": {
    "cover": "https://cms.example.com/public/v1/media/asset-uuid-here"
  }
}

data のキーはフォームセットのフィールド key と対応します。mediaUrls に画像の完全 URL が入ります。

フレームワーク別レシピ

Next.js / Astro / Nuxt の一覧・詳細の貼り付け例は フレームワーク別レシピ を参照してください。

トラブルシューティング

症状原因対処
エントリ一覧が空まだ公開済みエントリがない下書きを承認・公開してください
404 NOT_FOUNDフォームセットの slug が違う管理画面のフォームセット設定で slug を確認
フィールド値が返らないinclude_snapshot=true を忘れたクエリパラメータを追加してください
画像 URL が返らないmediaUrls を確認していないmediaUrls[fieldKey] が完全な URL です

次のステップ