AI agents
Claude Code, Cursor or Codex working in a project — AGENTS.md, the reference in .webmati/, naming and security, tools from the shell with --select, code mode and the slim MCP.
Open the project in your agent
Open the project folder (the one with webmati.toml) in your agent. clone
already wrote the instructions every coding agent reads — Claude Code, Cursor and
Codex each read the file nearest the code they touch:
AGENTS.md— a playbook, not a manual:- where the facts are: everything the agent needs is in
.webmati/; it reads.webmati/reference/index.mdbefore inventing a name, and tells you when something it needs is missing instead of guessing; - how to start a session:
webmati pull,webmati status,.webmati/reference/site.md, then the skill for the task, and asking you what "done" means when the task is vague; - a task table: for colours, a homepage section, a new section type, a page, the header, translations, redirects, images, a workflow, a table, a secret, a domain and a new website, it gives the files to touch, the skill section to read first, what never to do and how to check;
- the platform's tool names mapped to the folder;
- hard rules: it never publishes, pushes live changes or deletes anything unless you asked for exactly that; it validates to 0 errors before every push; it never weakens security to make something work; it works in small batches;
- a definition of done;
- four worked recipes: testimonials on the homepage, a contact workflow at POST /contact, the brand colour, a React app on a page.
- where the facts are: everything the agent needs is in
theme/AGENTS.md: the section and schema rules, the colour classes,settings_data.json, inheritance, a section skeleton, naming and security.backend/AGENTS.md: the workflow graph, code-node rules, tables and live changes, naming, a security checklist and testing with fixtures.- A
CLAUDE.mdnext to each, pointing Claude Code at the same file.
The platform's own playbooks (the skills its MCP serves) come with the project in
.webmati/skills/, with an index.md, so the agent follows the same rules the
platform's assistant does. webmati pull refreshes the ones that changed on the
server:
webmati skills # list them
webmati skills --refresh # fetch the server's current text now
webmati skills --update-instructions # offer this CLI's newer AGENTS.md files, with a diff
A clone never overwrites an AGENTS.md you edited. --update-instructions shows the
diff and replaces a file only when you say yes (--yes for scripts).
The facts: .webmati/reference
The skills say how to work; .webmati/reference/ says what exists, so the agent
does not guess a variable, a setting or a column. Every file is generated from the
platform's own tools and from the project, so it is true for this website:
| File | What it holds |
|---|---|
index.md | what each file is and when to read it |
site.md | commerce on or off, the languages, installed apps, content types, tables, routes, variables, secret names, workers, workflows |
sections.md | every section type, own or inherited, with its setting ids, types, defaults and blocks, and where it is placed |
templates.md | which templates and pages place which sections |
liquid.md | the Liquid objects and filters the storefront exposes |
nodes.md | every workflow node with its settings, the imports a code node may use, the limits |
wm.md | the wm package a code node calls, every function with its signature |
shop.md, webhooks.md | the website's own data and events; the webhook signature schemes |
jobs.md, wmjob.go | the background-job SDK |
webmati pull and webmati skills --refresh rewrite it. When a tool does not answer,
the older copy stays and the index says so. Like the skills, it belongs to your
machine and is left out of git.
Naming and security
Each nested AGENTS.md has a Naming section in two halves. The enforced half
is printed from the platform's own validators: the patterns for table, column,
workflow, route and variable codes, theme paths, section types, setting ids,
templates, content types and page slugs. The other half is conventions, marked as
such: plural snake_case tables, verb_noun workflow codes (create_order),
lowercase routes with one workflow each, kebab-case section types.
backend/AGENTS.md ends with a security checklist (auth modes, row ownership,
checking input, secrets, webhooks, outbound calls, SQL, files, realtime, keys), each
item pointing at the skill section that explains it. theme/AGENTS.md adds the
theme's: theme files are public, the storefront does not escape output, and no
third-party script goes in without your yes.
webmati validate warns about what the files show plainly, and never refuses for
it: a naming convention not followed, a public route that writes without checking
its input, a mail sent to an address taken from the request, a secret-looking
literal in a code node, a theme file or a variable, and visitor input printed in
Liquid without | escape.
Then just hand over the job: "change the button colour in the hero section, validate, push to the draft and give me the preview link". The agent tells you what changed, the preview link, and what still waits for your go-ahead (publishing, live changes).
The platform's tools from the shell
Every platform tool (products, pages, content, analytics, the backend…) can be called from the shell, JSON in and JSON out:
webmati tool list pages # search the tools
webmati tool describe list_pages # arguments, result type, examples
webmati tool call list_pages --json '{}' # call it
--select keeps only the part you need, before the result reaches the agent:
the single biggest token saver. It speaks a subset of jq:
webmati tool call list_pages --json '{}' --select '.storePages[] | {id, slug, title}'
webmati tool call list_pages --json '{}' --select '.storePages | length'
webmati tool call list_pages --json '{}' --select '.storePages[] | select(.status == "draft") | .slug'
webmati tool call list_backend_tables --json '{}' --select '.backendTables[] | {id, code, label}'
webmati tool call get_context --json '{}' --select '{store_id, theme_id}'
Supported: .a, ."odd key", .[0], .[-1], .[1:3], .[], .., ?, |,
,, {a, b: expr}, [expr], length, keys, first, map(…), and
select(…) with == != < <= > >=, and, or and parentheses.
Long arguments go in a file (--json @args.json) or on stdin (--json -). Every
call is logged to .webmati/logs/tools.jsonl.
Tool docs as files: .webmati/sdk
webmati sdk
writes .webmati/sdk/index.md plus one .md and one .d.ts per tool. An agent
reads the index first and then opens only the tool it needs, instead of loading
the whole tool list into its context. A project from the zip already has it.
Code mode: webmati exec
A TypeScript script calls several tools at once, and only the value it
returns is printed:
// draft-pages.ts — a script is the body of an async function: await, then return
const r = await webmati.list_pages({});
const drafts = r.storePages.filter((p) => p.status === "draft");
return drafts.map((p) => ({ id: p.id, slug: p.slug }));
webmati exec draft-pages.ts
Call a tool by name with await webmati.call("get_context", {}). The script runs
in a separate process, never sees the key, and has no fetch, import or
file system. By default it is read-only:
| Flag | Allows |
|---|---|
--allow-writes | tools that write (create a page, edit a product…) |
--allow-destructive | delete, publish, restore |
--allow-network | a read-only script calling fetch_url with an address it picks |
--allow-local-files | upload_image reading a file on this machine |
--max-calls N, --timeout 2m | limits on calls and time |
Each run is logged to .webmati/logs/exec-<time>.jsonl. Pipe a script in with
webmati exec -.
The slim MCP: webmati mcp
For an agent that wants MCP tools rather than a shell, webmati mcp serves an MCP
of just 8 tools on stdio:
search_tools describe_tool call_tool execute status pull push validate
Its tool list is 97.4% smaller than the full MCP's (182 tools); the agent
finds a tool when it needs one (search_tools, describe_tool) and calls it
(call_tool with a selector, or execute for a code-mode script). Measure it:
webmati mcp --measure
Add it to Claude Code, from the project folder:
claude mcp add webmati-local -- webmati mcp
Add it to Cursor with .cursor/mcp.json in the project folder:
{
"mcpServers": {
"webmati-local": { "command": "webmati", "args": ["mcp"] }
}
}
The MCP works on the project in its current folder; the four tools status,
pull, push and validate exist only when it runs inside a project. To pin one
project, use webmati --dir /path/to/my-shop mcp.
webmati mcp --fullserves every tool (like the platform's own MCP), through the CLI's key.- Delete, publish and restore calls are confirmed first;
--allow-destructivelets them through without asking.

