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

# CLI and packages

> The commands Avocado Studio ships, every flag each one takes, and what each of the twelve published packages is for.

This page is for developers looking a command up: seven commands and twelve
packages, in one list. Every command needs Node 22 or later.

## `npm create avocado-site`

Bootstraps a project. This is the first command almost everyone runs.

```bash theme={null}
npm create avocado-site@latest my-site
```

It takes one positional argument, the directory, and a few flags:

| Option | |
| - | - |
| `-y`, `--yes` | Never ask. Implied whenever stdin is not a terminal. |
| `--no-install` | Write the files and skip `npm install`, for callers that install their own way |
| `--api-key KEY` | Write `KEY` to `.env.local`. The variable is chosen from the key's prefix. Also read from `AVOCADO_SETUP_API_KEY`. |
| `-h`, `--help` | Print the usage |

A key is written only when it is **named**, with the flag or with
`AVOCADO_SETUP_API_KEY`. An `ANTHROPIC_API_KEY` exported in your shell is left
alone, because the scaffold is about to become a git repository. Unattended runs
never start the dev server; they print the command instead. A run with no
terminal and no directory name exits 1 and names the flag that fixes the call.

```bash theme={null}
npm create avocado-site@latest my-demo -- --yes --no-install
```

**With a directory name** it goes straight to the demo: a runnable Next.js
project with the Avocado Hub's nine pages in it, the orchestrator mounted inside
the app in library mode, and the editor served alongside by one `npm run dev`.
Somebody who has typed a name has already answered the only question that
mattered.

**With no argument** it asks which of two jobs you want first, then the
directory name:

| Mode | What it does |
| - | - |
| **See the demo site** | Creates a new project and installs it |
| **Wire Avocado into this project** | Writes the wiring into a Next.js app that already exists, then tells you what is left to do. Both modes also write the agent skills below |

Interactive setup offers to take an API key, and Enter skips it — worth taking
then rather than later, because keys are read at startup, so one pasted during setup is live
immediately while one added afterwards needs a file edit *and* a restart.

Ports are chosen at scaffold time from what is actually free on your machine,
starting at 3000 for the site and 4100 for the editor.

→ [Try the demo](/first-run)

## `npx @avocadostudio-ai/skills`

The package's command is `avocado-skills`.

Installs Avocado's agent skills into a project that already exists, and nothing
else — no routes, no config, no dependencies, no prompts.

```bash theme={null}
npx @avocadostudio-ai/skills
```

This is the fastest way to start an integration: your coding agent reads
instructions that match the version you are installing, instead of a prompt
pasted from a page that cannot be versioned against npm.

| Written | |
| - | - |
| `.claude/skills/` | For Claude Code |
| `.agents/skills/` | For the cross-agent `skills` CLI — Cursor, Codex, Gemini |
| `AGENTS.md` | Only if absent. Yours is never overwritten |
| `CLAUDE.md` | Only if absent |

Five skills land: `avocado` routes, and `avocado-integrate`, `avocado-demo`,
`avocado-blocks` and `avocado-cms` do the work.

| Option | |
| - | - |
| `[directory]` | Where to write. Defaults to the current directory |
| `--dry-run` | Print what would be written, write nothing |
| `-h`, `--help` | Print the usage |

**Skill files are replaced on re-run.** That is how an upgrade delivers new
instructions — never clobbering them would leave 0.13's guidance on disk under
an 0.14 install, with nothing saying so. Every file's outcome is reported, so a
skill you had edited shows as `updated` rather than changing silently.
`AGENTS.md` and `CLAUDE.md` are yours and are only ever created.

→ [Hand it to your own coding agent](/sites/coding-agent)

## `avocado-scope`

Reads a live page and reports what it would become as Avocado blocks, before
you install anything.

```bash theme={null}
npx -y -p @avocadostudio-ai/migration-sdk avocado-scope https://example.com/about
```

The command lives in `@avocadostudio-ai/migration-sdk`, so `npx` needs the
`-p` to know where to find it: there is no package called `avocado-scope`, and a
bare `npx avocado-scope` answers with a 404 from the registry. Only inside a
project that already has `migration-sdk` installed is `npx avocado-scope <url>`
enough.

```
https://example.com/about
9 sections found, 9 mapped to blocks.

section  becomes          note
0        CTA              was Hero — Hero needs an image with alt text
1        FeatureGrid
5        RichText         was FeatureGrid — needs two sub-headings each followed by a paragraph
7        FAQAccordion

Result: CTA×1, FeatureGrid×3, RichText×4, FAQAccordion×1
```

For a site on a local dev server, add `--allow-localhost`:

```bash theme={null}
npx -y -p @avocadostudio-ai/migration-sdk avocado-scope http://localhost:4321/ --allow-localhost
```

It answers the question every adopter asks first — *what would my site look
like in Avocado* — with no orchestrator, no session, no site, no API key and no
model. **Read-only and deterministic:** nothing is written, and the same page
always gives the same answer, so re-running it after a change is a diff rather
than a new opinion.

| Option | |
| - | - |
| `--allow-localhost` | Permit local and private addresses. Off by default, because this fetches whatever URL it is given |
| `--json` | Also print the proposed `PageDoc` |

A refusal explains itself in the page's terms rather than the schema's — *"Hero
needs a link to use as its call to action"* — because that is a fact about your
page, and it is more useful than either inventing a button or failing silently.

**If more than half the page comes back as `RichText`**, the report says so.
That means the structure did not survive, and it is usually a sign the page's
sections are worth declaring as [your own block
types](/integration/custom-blocks) rather than mapped onto the built-ins.

The `updatedAt` on the proposed page is a deliberate placeholder — stamp it when
you decide to keep the result. Scoping is a read, and a mapper that reads a
clock is not deterministic.

Ships inside `@avocadostudio-ai/migration-sdk`.

## `avocado-studio`

The self-host launcher for the editor UI, from `@avocadostudio-ai/cli`. It
serves a prebuilt editor bundle against a running orchestrator.

<Note>
  **`avocadostudio` is an alias and is not going away.** The command was renamed
  so that the commands share one `avocado-` prefix. It was the only one that did
  not.
  Both names install and point at the same entry.
</Note>

```bash theme={null}
npx @avocadostudio-ai/cli start \
  --orchestrator http://localhost:3000/api/avocado \
  --preview      http://localhost:3000
```

It has exactly one command, `start`. `avocado-studio --help`, and
`start --help`, print the options and the other Avocado commands.

| Flag | Environment variable | Default |
| - | - | - |
| `--orchestrator <url>` | `AVOCADO_ORCHESTRATOR_URL` | `http://localhost:4200` |
| `--preview <url>` | `AVOCADO_SITE_ORIGIN` | `http://localhost:3000` |
| `--publish-token <token>` | `AVOCADO_PUBLISH_TOKEN` | — |
| `--draft-secret <secret>` | `AVOCADO_SITE_DRAFT_SECRET`, then `DRAFT_MODE_SECRET` | — |
| `--port <n>` | `PORT` | `4100` |
| `--host <addr>` | `HOST` | `127.0.0.1` |

<Warning>
  **The default `--orchestrator` is the standalone server's address and is wrong
  for library mode.** If your orchestrator runs inside your Next.js app, pass
  `--orchestrator http://localhost:3000/api/avocado` explicitly. Forgetting it is
  the usual cause of "the preview shows the published page and never my edits".
</Warning>

<Warning>
  **`HOST` is read from the environment**, and container platforms set it for you.
  If the editor binds somewhere you did not ask for, that is why — pass `--host`
  explicitly to override it.
</Warning>

`--draft-secret` is required for editing a site running in production; it must
match the site's `DRAFT_MODE_SECRET`. It is written into the editor's page only
on a loopback `--host`. On a public bind the page is readable before sign-in, so
the CLI leaves the secret out, and the editor fetches it from the orchestrator's
`GET /editor/credentials` once signed in. To host the editor publicly, give the
orchestrator `DRAFT_MODE_SECRET` and an access password instead. On start the CLI probes the orchestrator's
`/health` and warns when the reported protocol version does not match the editor
build it ships.

## `avocado-register`

Registers a site with an orchestrator so it appears in the editor's **Sites**
list, rather than relying on defaults. Ships inside `@avocadostudio-ai/site-sdk`.

```bash theme={null}
npx avocado-register --name "Marketing Site" \
  --orchestrator http://localhost:3000/api/avocado
```

Run it from the project directory. Most of what it needs it can work out:

| Flag | Default |
| - | - |
| `--name <string>` | the project's `package.json` name |
| `--id <kebab-case>` | kebab-case of `--name` |
| `--port <number>` | parsed from `scripts.dev` in `package.json`, or Astro's `server.port`, else `4321` on Astro and `3000` otherwise |
| `--orchestrator <url>` (alias `--orchestrator-url`) | `$ORCHESTRATOR_URL`, then the env file's value |
| `--secret <string>` | read from `.env` or `.env.local`, or generated — and checked against the orchestrator either way |
| `--session <string>` | `dev` |
| `--preview-url <url>` | `http://localhost:<port>` |
| `--purpose <string>` | — (a one-line site description, used as AI context) |
| `--token <string>` (alias `--access-token`) | `$ORCHESTRATOR_ACCESS_TOKEN` |
| `--cwd <path>` | the current directory |

It works out the framework and writes the file that framework reads: on Next,
`.env.local` with `DRAFT_MODE_SECRET`, `ORCHESTRATOR_URL` and the
`NEXT_PUBLIC_*` names the scaffolds use; on Astro and anything else, `.env` with
`DRAFT_MODE_SECRET`, `ORCHESTRATOR_URL` and `AVOCADO_SITE_ID`. Only missing keys
are added. Its next steps use the project's own package manager, from the
`packageManager` field or the nearest lockfile.

That file holds the draft secret, so the command also checks that git will
leave it out of a commit — with `git check-ignore` inside a repository, and
against the project's `.gitignore` outside one — and prints the line to add
when it would not. A starter kit's `.gitignore` often lists `.env` and not
`.env.local`, or neither.

**The secret is checked before it is written.** `POST /sites/register` answers
whether the secret it was sent matches the orchestrator's `DRAFT_MODE_SECRET` —
`match`, `mismatch` or `unset`, never the value. On a mismatch the command
writes nothing and exits 1, because a site holding a secret the editor will
never send shows published content in the preview — the single most common
integration failure, and one that degrades to *"the preview shows published
content"* rather than an error. The fix it prints is `--secret <value>`, with
the value from `DRAFT_MODE_SECRET` in the orchestrator's `.env`, which the
editor reads as `VITE_SITE_DRAFT_SECRET`. An explicit `--secret` replaces a
different value already in the env file. An orchestrator it cannot reach
leaves the env file written, the secret unchecked, and the exit code 0.

The same command is `npx avocado register`, or
`npx @avocadostudio-ai/site-sdk register` from outside the project.

## `avocado qa`

Checks an integration the way the editor will use it, and exits non-zero when
any check fails. Ships inside `@avocadostudio-ai/site-sdk` as the `avocado` bin.
Run it from the site's directory with the site's dev server up.

```bash theme={null}
npx avocado qa
# or, from anywhere:
npx @avocadostudio-ai/site-sdk qa
```

The unscoped `avocado` name on npm belongs to an unrelated package, so
`npx avocado qa` finds this command only where the SDK is installed. The scoped
form works anywhere.

It renders every page in a frame on the editor's origin, from a throwaway
`qa-<timestamp>` session seeded with the site's pages, never your own session.
Exit codes: 0 when nothing failed, 1 when a check failed, 2 for a usage error.
Warnings do not fail it. The common options:

| Option | Default |
| - | - |
| `--site <url>` | the port in `package.json`'s dev script, else `:3000` for Next and `:4321` for Astro |
| `--orchestrator <url>` | `ORCHESTRATOR_URL` from the env files, else `http://localhost:4200` |
| `--editor-origin <url>` | `NEXT_PUBLIC_EDITOR_ORIGIN` or `AVOCADO_EDITOR_ORIGINS`, else `http://localhost:4100` |
| `--site-id <id>` | `NEXT_PUBLIC_DEFAULT_SITE_ID` or `AVOCADO_SITE_ID`, else the package name |
| `--secret <value>` | `DRAFT_MODE_SECRET` from the env files |
| `--token <value>` | `$ORCHESTRATOR_ACCESS_TOKEN` |
| `--skip <stages>` | — |
| `--build` | also run the site's typecheck and build |
| `--no-browser` | server HTML only, even when Playwright is available |
| `--json` | print the JSON report instead of the summary |

`npx avocado qa --help` lists the rest. It writes `.avocado/qa-report.json`,
which you should not commit, and `.avocado/manifest.lock`, which you should.
Playwright is used when it can be found and is not a dependency. See
[QA](/integration/qa).

## `avocado-mcp` and `avocado-mcp-http`

The [MCP server](/integration/mcp-server), over stdio and streamable HTTP
respectively, from `@avocadostudio-ai/mcp-server`:

```bash theme={null}
npx -p @avocadostudio-ai/mcp-server avocado-mcp
```

| Variable | Default |
| - | - |
| `AVOCADO_SITE_ID` | **required** |
| `ORCHESTRATOR_URL` | `http://localhost:4200` |
| `AVOCADO_SESSION` | `dev` |
| `AVOCADO_PUBLISH_TOKEN` | — |
| `AVOCADO_MCP_PORT` (HTTP only) | `4300` |
| `AVOCADO_MCP_BEARER_TOKEN` (HTTP only) | — |

## The packages

Twelve packages publish to npm, all versioned together.

| Package | What it is |
| - | - |
| `@avocadostudio-ai/site-sdk` | **The integration surface.** Routes, the page factory, markers, publishing, block registration, library mode. The one you install. Ships `avocado-register` and `avocado qa`. |
| `@avocadostudio-ai/orchestrator-core` | The brain — session state, AI planning, the operations engine, publishing. An **optional peer** of the SDK, so it is not installed for you; library mode needs it. |
| `@avocadostudio-ai/blocks` | The built-in React block renderers and their stylesheet |
| `@avocadostudio-ai/shared` | Zod schemas — `PageDoc`, `BlockInstance`, `Operation` — and the block registry |
| `@avocadostudio-ai/preview-adapter` | The preview bridge and the editor overlay |
| `@avocadostudio-ai/richtext` | The rich-text grammar, and converters for four CMSes |
| `@avocadostudio-ai/astro` | The [Astro integration](/integration/astro-integration) |
| `@avocadostudio-ai/cli` | The `avocado-studio` launcher above, with the prebuilt editor |
| `@avocadostudio-ai/mcp-server` | The [MCP server](/integration/mcp-server) |
| `@avocadostudio-ai/migration-sdk` | Utilities for migrating existing content into `PageDoc` shape, and `avocado-scope` |
| `@avocadostudio-ai/skills` | The agent skills above. Also the source `create-avocado-site` writes them from |
| `create-avocado-site` | The scaffolder above |

**Import from the published specifier, never a deep path into `dist` or `src`.**
Anything deeper than a documented subpath is internal and will not resolve. If
you find yourself needing one, that is a gap in the contract worth reporting
rather than routing around.

### Native dependencies

`orchestrator-core` carries `better-sqlite3` and `sharp`. A bundler has to be
told to leave them alone, and `serverExternalPackages` on its own is not enough
because `transpilePackages` overrides it for a transitive dependency. Wrapping
your Next config sets all of it together:

```ts theme={null}
import { withAvocado } from "@avocadostudio-ai/site-sdk/next-config"
export default withAvocado({ /* your config */ })
```

Prebuilt `better-sqlite3` binaries ship for linux-x64 (glibc 2.28+), darwin-arm64
and darwin-x64 on Node 22. A custom Dockerfile needs `python3`, `make` and `g++`
on the build stage only when no prebuild matches your target.


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