Get a project
Clone a website, or download the zip an AI agent hands you; what a project holds and what never leaves the server.
webmati clone
webmati clone my-shop
my-shop is the website's slug (or its id). The CLI creates the folder my-shop/
and pulls everything into it. Another folder name:
webmati clone my-shop shop-local
The folder must not exist yet, or be empty. If you are signed in to several
platforms, add --platform webmati.
The zip from an AI agent
When you work with an AI over the MCP, say "I want to work on this website on my
machine". The agent calls the init_local_project tool and gives you:
- the install command for your system,
- the sign-in and
clonecommands, - a zip link of that very project, valid for one hour.
The zip holds exactly the tree clone writes (the sync state in .webmati/
included). Unzip it, then sign in once, inside the folder:
cd my-shop
webmati login --web
webmati status
login reads the platform and the website from webmati.toml. A status that
lists no change means the project matches the server.
The zip link is a key
Anyone with the link can download the project until it expires (one hour). The zip holds no key, no secret value and no media, but it does hold your theme and workflow code: do not paste the link anywhere public.
What a project holds
| Path | What it is | Editable |
|---|---|---|
theme/ | the theme's own files: layout, templates, sections, snippets, assets, config, locales | yes |
theme/config/settings_data.json | the theme's settings (what the customizer saves) | yes |
backend/workflows/<code>/workflow.json | a workflow's name and draft graph | yes |
backend/workflows/<code>/nodes/<id>.go | the Go source of one code node (keep its first two lines) | yes |
backend/tables/<code>.json, backend/routes.json, backend/variables.json | the backend's declarations | yes, live (push --live) |
backend/secrets.json, backend/workers.json | secret names, uploaded workers | read-only |
pages/<slug>.json | a page (title, meta, body, sections — the sections stay a draft until published) | yes |
content/types/<code>.json | a content type's definition | yes, live |
redirects.json | the website's redirects, one entry per from_path | yes, live |
wellknown/<name> (+ <name>.meta.json) | a file served at /.well-known/<name> | yes, live |
translations/<locale>.json | translated texts, keyed <resource_type>/<resource_id>/<field> | yes, live |
.webmati/inherited/ | files the theme inherits and does not own | reference only |
.webmati/conflicts/ | the server's side of a conflict | read, then webmati resolve |
.webmati/state.json, .webmati/objects/ | sync bookkeeping | never edit |
.webmati/sdk/ | one doc per tool, for agents (webmati sdk refreshes it) | generated |
.webmati/logs/ | logs of tool call and exec | generated |
AGENTS.md, CLAUDE.md (also in theme/ and backend/) | the playbook coding agents follow (each CLAUDE.md points to the AGENTS.md beside it) | yes |
.webmati/skills/ | the platform's own playbooks, with an index.md (webmati skills; pull refreshes them) | generated |
.webmati/reference/ | the facts: Liquid objects, workflow nodes, the wm package, and this website's sections, templates, content types, tables and routes (start at index.md) | generated |
webmati.toml | the platform, the website, where pushes land (draft) — no key | rarely |
everything else — app/, scripts/, docs/, backend/fixtures/, a README… | the project's own files: kept for your team, never served (see Your project's own files) | yes |
.webmatiignore, every .gitignore | what is not a project file (gitignore syntax): node_modules/, builds, logs, .env* | yes |
To change an inherited file, copy it from .webmati/inherited/<path> to
theme/<path> and edit the copy. Deleting your copy makes the inherited one apply
again.
File names on Windows
Names that are not valid on every system are encoded: : becomes ~3A (an app's
workflow stripe:pay lives in backend/workflows/stripe~3Apay/), and Windows'
reserved names such as con get a trailing ~. Two paths that differ only in
upper/lower case are refused when you clone.
Using git
A project is an ordinary folder: git init works right away. clone already
wrote a .gitignore (leaving out what belongs to your machine only:
.webmati/objects/, logs/, sdk/, skills/, reference/, conflicts/, and .webmati/secrets.json,
where you may keep real secret values for webmati test) and a .gitattributes
(* -text, so git never rewrites line endings), plus .webmatiignore. While
they hold the CLI's own default text they are not synced; once you change one, it
is a project file the whole team shares.
What is never downloaded
- Secret values.
backend/secrets.jsonholds names only. Set a value withwebmati tool call set_backend_secret --json '{"code":"STRIPE_KEY","value":"…"}'; it can never be read back. - API keys. Neither the CLI's own key nor the backend's API keys. The CLI's key
lives in
~/.config/webmati/, never in the project. - Media. Images and files stay in the media library; the theme refers to them by URL.
- Data in the backend's tables, and end users.
- Build output and dependencies —
node_modules/,dist/: they are never sent, so there is nothing to download.

