> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livlive.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> This is livlive's documentation. An agent reaches livlive from outside through the `livlive` CLI or the livlive MCP server (see /developers/install, /developers/cli and /developers/mcp). The person links it to livlive once, in the browser: `livlive login`, the local MCP's `livlive_login` tool, or the remote MCP at https://backstage.livlive.ai/api/mcp signing in by OAuth; a personal token made in livlive's settings is for CI. Pages marked 準備中 describe parts not decided yet: do not guess their behaviour.

# livlive-cli

> How an agent works on livlive from outside — the `livlive` CLI and the livlive MCP server. Link to livlive in the browser, list the ops, open or read a production room, check a 構成表 draft, then save it. Read when you must act on a livlive content (not just write one).

> [!NOTE]
>
> このページは、エージェントが読む skill「livlive-cli」の本文です。

> [!WARNING]
>
> いまは招待制βの準備中です。CLI と MCP は npm から入れられますが、使うには livlive のアカウント(招待制)が要ります。スキル(`npx skills add`)は、livlive-kit の公開とともに使えるようになります。

The backstage has one outside door: `GET /api/ops` lists the ops an outside agent may run, `POST /api/ops/<op>` runs one as the token's
person. The CLI and the MCP server map that list one to one — nothing is hand-written, so `livlive ops` (or the MCP tool list) is always
the truth. Paid ops are not offered yet.
Two commands are not ops and never reach livlive: `livlive picture make` (a reference picture, by gpt-image) and `livlive model make` (a
model, by Tripo) use the person's own keys from a stage folder's `.env`, billed to their own accounts with those services (`stage-art`).

## Log in

```
livlive login            # opens livlive in the person's browser for one press; the token is checked with GET /api/ops and kept in ~/.config/livlive/config.json
livlive login --device   # where no browser can be opened: prints an address and a code the person types in any browser
livlive login --paste    # for CI: paste a token the person made on the backstage page /settings/tokens (shown once, starts lvl_)
livlive logout           # revokes this PC's token at livlive and removes it from the file
```

The address is [https://backstage.livlive.ai](https://backstage.livlive.ai) unless `--base <url>` or `LIVLIVE_BASE` names another livlive. The local MCP uses the same link: with
none it offers one tool, `livlive_login`, which opens the same page. For CI, set `LIVLIVE_TOKEN` (and `LIVLIVE_BASE` for another address).
Never print or log the token.

## Run ops

```
livlive ops                                          # name, label, what it does; --project <id> when it needs a project
livlive room.open --json '{"title":"…"}'             # a new room → data.project
livlive room.read --project <id>                     # data.versions, data.current, data.structure (the current 構成表), data.choices
livlive script.check --project <id> --file draft.json   # input.structure: the 構成表; ok when script.save would take it
livlive script.save --project <id> --file draft.json    # keep it as the next version
livlive skills.read --json '{"staff":"tsuzuri"}'      # no project; each skill's id, version, body and words
```

A skill for the person (a カスタムスキル) is written by you, the agent, and sent — never typed by the person:

```
livlive skills.add --file skill.json
    # {"staff":"tsuzuri","name":"…(one line ≤ 40)","description":"when to read it (≤ 120)","body":"# …(Markdown ≤ 9600)",
    #  "words":{"title":"≤ 16","summary":"one plain sentence ≤ 60","guide":["1–3 plain lines, each ≤ 50"]}}   → data.skill { id, version }
livlive skills.edit --file skill.json   # the same fields + "id" and "version" from skills.read; a newer version is never overwritten
livlive skills.publish --json '{"id":"…","version":3,"price":0}'   # to the market's review; the first publish is made on the page
```

`words` are what people see on the staff page and in the room — required, in plain words, no 【】 or ids. Their names on the screen: 表示名 = `title`, 概要 = `summary`, 説明 = `guide` — a refusal names them in Japanese only. A refusal says why in `left[].say`.

`skills.publish` sends a new version of a skill already in the market to its review; the person sets the price and agrees to the terms on the page (`/market/publish`), and a buyer never sees the body.

The preparation road's ops (the order and what each needs: the entry skill `livlive`, 「The preparation road」):

```
livlive room.read --project <id>                     # data.choices: cast / forms / channels ids to pick; data.recent: the work records
livlive desk.pick --project <id> --json '{"cast":["<choices.cast id>"],"channels":["youtube"]}'
livlive desk.pick --project <id> --json '{"form":"monologue"}'          # a choices.forms id, or "planned"
livlive request.write --project <id> --json '{"memo":"## 概要\n…","proposals":[]}'
    # the 要望, before script.first (it waits for it); no proposals = answered at once; a proposal waits for the person in the room
livlive request.edit --project <id> --json '{"bring":"<made.asset>"}'   # one change: take / section + words / memo / bring / drop
livlive pitch.put --project <id> --file pitch.json
    # {"title":"…","doc":"## 企画意図\n…","answers":[{"to":"概要","section":"企画意図","how":"…"}],"research":["<made.research>"]} — the 企画書, before script.first
livlive research.bring --project <id> --file research.json
    # {"title":"…","purpose":"…","claims":[{"text":"…","source":"https://…","confidence":"unverified"}]} → made.research
livlive asset.bring --project <id> --json '{"kind":"markdown","title":"メモ","text":"# …","use":"memo"}'   # → made.asset
livlive asset.bring --project <id> --json '{"kind":"markdown","title":"…","text":"# …","use":"memo","from":["<made.research>"]}'
    # written from the room's own research / 構成表 versions / 素材: name their ids in from (at most 6) — the room keeps what it was made from
livlive script.first --project <id> --file first.json
    # {"title":"…","structure":{…},"cast":["<id>"],"form":"monologue","research":["<made.research>"],"requestId":"<uuid>"}
    # → made.version (only on a room with no content)
livlive asset.shelve --project <id> --json '{"asset":"<made.asset>"}'   # later: the next version with that asset on its 参照アセット
```

Every op answers an OpResult: `{ ok, done: Step[], left: Step[], made?, data? }`. `left` says what is still missing and why (`why`) — fix
that and run again. The CLI exits 1 when `ok` is false.

## The usual order

1. `room.open` (or a project id the person gives you) → `room.read` to see the room and its `choices`.
2. Read `livlive-core` for the 構成表 shape and the staff's skills (`skills.read`) for the craft.
3. Draft, then `script.check` until `ok`; then `script.first` on a room with no content, `script.save` after that. Use the `script.*` and `asset.*` edit
   ops for small changes; `script.undo` takes one back.

## MCP

`livlive-mcp` (stdio) offers the same ops as tools — dots become underscores (`room.read` → `room_read`), and ops that need a project take
a required `project` argument. The result is the OpResult as JSON text; `isError` is true when `ok` is false. The skills are resources:
`livlive://skills/<name>`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.