# CLI and projects `npm i -g @mozaik/cli` opens a store as a **file-tree project**: design as files an agent can read, diff and edit with ordinary tools, synced against the server draft under CAS. The full command table is generated at [/reference/cli](/reference/cli); this page is the working loop. ## The loop ``` mozaik login --token mzk_… # once per machine mozaik open st_mystore # Tree v1 + mozaik.json + AGENTS.md + .mcp.json # edit design/ with anything mozaik push # validate server-side, save as the workspace draft (CAS) mozaik preview # stable preview URL of the workspace draft mozaik propose --title "…" # agent tokens: submit the open proposal for review ``` [`open`](/reference/cli) is idempotent (≈ pull); [`dev`](/reference/cli) watches `design/`, pushes on change and keeps the preview URL live; [`status`](/reference/cli) and [`diff`](/reference/cli) compare the tree against the lock, the server draft or the live design. Catalog data has its own arm: `mozaik catalog export|plan|apply` ([`catalog`](/reference/cli)) round-trips `catalog/*.jsonl` as idempotent commands, and [`cmd`](/reference/cli) runs any single command through the bus — for an Ajan token, recorded as a proposal item like every mutation. ## Tree v1 ``` mozaik.json project manifest (format, store, workspace, pinned CLI) — no secrets .mozaik/base.lock last-sync state (platform build, draft rev/hash, file hashes) AGENTS.md how agents should work here (CLAUDE.md = @AGENTS.md) .mcp.json MCP wiring: hosted admin MCP + local dev-mcp, both pinned design/ the store design as files (assembled hash == server hash) catalog/*.jsonl optional catalog export media/manifest.json media inventory ``` The `design/` tree assembles to exactly the server draft — same hash — so "what would change" is always answerable locally. [`validate`](/reference/cli) runs the server-side bundle checks ([`validate.bundle`](/reference/routes/validate.bundle)) without saving anything. ## Credentials never live in the project The token sits in `~/.config/mozaik/credentials.json` (0600) or `MOZAIK_API_TOKEN` — never under the project root. `mozaik.json`, `.mozaik/` and `.mcp.json` contain zero secret material (the `.mcp.json` uses env substitution), so a project tree is always safe to commit, zip or hand to another agent. ## .mcp.json wiring [`open`](/reference/cli) writes an `.mcp.json` that gives any MCP-aware editor or agent two servers, both pinned to the project's CLI version: - **admin MCP** — `https://api.mozaik-dev.com/mcp` with the bearer from the environment: the store's [tools](/reference/mcp-tools), live. - **dev MCP** — `mozaik dev-mcp` ([`dev-mcp`](/reference/cli)) over stdio: docs search, schema introspection and validators for the current platform build. No auth, no store access. `AGENTS.md` in the tree carries the store-specific working notes; Claude Code reads it via `CLAUDE.md = @AGENTS.md`. ## Exit codes | code | meaning | |---|---| | 0 | ok | | 1 | error | | 2 | usage | | 3 | version/format refusal (HTTP 426) — `npm i -g @mozaik/cli`, then [`upgrade`](/reference/cli) | | 4 | conflict — the draft moved (HTTP 409); re-read, rebase your edit, push again. The server never merges. | Everything the CLI does is the public API — the same commands, [routes](/reference/routes) and version discipline as every other client; there is nothing the CLI can do that your own HTTP calls cannot.