Building with AI agents
Xeer is designed so that a program can drive it as competently as a person: the app's entire shape lives in one declarative file, the API surface is small enough to describe exhaustively, and every failure carries a stable code and a suggested repair.
If you are pairing with an agent, this page is what to give it.
#Zero-config discovery
Every xeer new project includes a concise AGENTS.md, the canonical portable skill under
.agents/skills/xeer/, a generated Claude-compatible projection, and a project-confined .mcp.json.
Codex and compatible agents can discover the build loop from the checkout without a pasted link or a
global install. The MCP command is pinned to the same version as the CLI that wrote the project and
sets XEER_MCP_ROOT to ., so tools cannot escape the project.
Add or verify the same files in an existing project with:
xeer agent setup
xeer agent setup --check --json
xeer agent setup --target cursor--check is non-writing and reports an exact create, update, keep, or conflict plan. Setup
updates only files carrying Xeer's generated format and content hash. If any selected path is owned by
the user or another tool, the whole write is refused; no partial setup is left behind. Targets are
auto, agents, claude, codex, cursor, vscode, and mcp.
#Every command speaks JSON
Start discovery with one bounded read:
xeer agent context . --jsonThe xeer.agent-context.v0 result contains normalized manifest facts, client/server/shared source zones,
operations, current diagnostics, test files, safe next actions, version-matched resource URIs, and a stable
content hash. It is deterministic across checkout roots and does not create .xeer/generated.
xeer check --json
xeer build --json
xeer deploy --jsoncheck, build, new, doctor, deploy, promote, rollback, link, env, deployments, and the
rest print exactly one envelope:
{
"protocol": "xeer.command.v0",
"command": "check",
"ok": false,
"diagnostics": [
{
"code": "XE1002",
"severity": "error",
"message": "…",
"file": "xeer.app.json",
"span": { "line": 12, "column": 9, "length": 6 },
"hint": "…"
}
]
}dev, preview, and test are long-lived, so they stream newline-delimited xeer.dev.v0 events
instead. Wait for preview.ready rather than sleeping. After an edit, the URLs on server.restarted
replace the discovery URLs: port-0 automation can move to another free port during a guarded restart,
including a rollback. test.case.fail carries a Diagnostic-shaped failure.
#Diagnostics are the interface
interface Diagnostic {
code: string; // XE####, stable
severity: 'error' | 'warning' | 'info';
message: string; // human wording, free to change
file?: string; // project-relative POSIX path, never absolute
span?: { line: number; column: number; length?: number }; // 1-based
hint?: string; // suggested edit
primary?: true; // this broke the generated contract — repair it first
causedBy?: string; // a consequence of that code, not an independent error
}Dispatch on code, never on message. Codes are stable; wording is not. file and span locate the
problem precisely enough to edit without searching, and hint is the platform's own suggestion for
closing it.
Repair primary: true first, and leave causedBy alone until it is gone. A failure that invalidates
the generated contract — a defineServer the compiler cannot read statically, a duplicate operation name,
a handler result the platform cannot encode — makes every type derived from those operations wrong, so the
files that consume the contract fill with XE1205 type errors their authors never caused. The compiler
marks the failure primary and stamps each consequence with the causedBy code, so the repair is the one
edit that broke it rather than the twenty files it poisoned. Such a run also prints its primaries first,
so the diagnostic worth reading is the one at the top. Both fields are optional and appear only where the
link is established; their absence means nothing was attributed.
Every code is catalogued in the diagnostics reference, generated from the same catalogue the compiler emits from.
xeer doctor --json reports the environment (Node version, platform, resolvable dependencies, generated
config, local state) as structured checks — how an agent tells "your code is wrong" from "this machine is
not set up".
#The MCP server
@impetik/xeer-mcp exposes the whole loop as
Model Context Protocol tools:
// .mcp.json, or your harness's MCP configuration
{
"mcpServers": {
"xeer": {
"command": "npx",
"args": ["--package=@impetik/xeer-mcp@<XEER_VERSION>", "--", "xeer-mcp"],
"env": { "XEER_MCP_ROOT": "." }
}
}
}xeer agent setup --target mcp substitutes the installed CLI's exact version for
<XEER_VERSION>; the placeholder is shown here so this page cannot become a stale compatibility pin.
Resource-capable clients can read xeer://project/context, xeer://project/manifest,
xeer://project/operations, xeer://project/tests, and xeer://docs/index. Markdown pages are loaded
on demand through xeer://docs/{+path}, and diagnostics through xeer://diagnostics/{code}. Clients
without resource support use the equivalent xeer_agent_context and xeer_docs_search tools.
That configuration starts the safe author profile. xeer_deploy_preview always passes the preview
environment, even if a caller invents another input, and the server registers no production-changing
tool. Only a human-controlled server configuration can add "XEER_MCP_PROFILE": "operator"; that
profile exposes xeer_promote, which requires an exact review receiptId. No tool argument can elevate
the profile, and MCP has no artifact-id or current-preview bypass.
The registry-generated table is the complete MCP tool and exclusion surface:
MCP tools (15 total; 14 author, 15 operator). Inputs ending in ? are optional.
| Tool | Action | Profiles | Summary | Inputs | Effects | Safety | Path policy | Output | Human prerequisite |
|---|---|---|---|---|---|---|---|---|---|
xeer_check | check | author / operator | Validate a project and report structured diagnostics. | directory?: string | read-sourcewrite-generated | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | none |
xeer_build | build | author / operator | Build and verify a content-addressed project artifact. | directory?: string | read-sourcewrite-generatedrun-local | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | none |
xeer_test | test | author / operator | Run the project test suite and record review evidence. | directory?: stringtimeoutMilliseconds?: integer [1000..1800000] | read-sourcewrite-generatedrun-localwrite-state | writes; idempotent; reversible; non-destructive | project-relative | xeer.dev.v0 | none |
xeer_new | new | author / operator | Create a new project from a supported scaffold. | directory: stringtemplate?: stringframework?: sveltekitui?: preact / react | write-sourcenetwork-read | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | none |
xeer_agent_context | agent.context | author / operator | Read normalized project facts, operations, diagnostics, tests, and safe next actions. | directory?: string | read-source | read-only; idempotent; reversible; non-destructive | project-relative | xeer.agent-context.v0 | none |
xeer_docs_search | docs.search | author / operator | Search the installed-version Xeer documentation index. | query: stringlimit?: integer [1..20]; default 5 | none | read-only; idempotent; reversible; non-destructive | none | xeer.docs-search.v0 | none |
xeer_doctor | doctor | author / operator | Diagnose the toolchain and generated project state. | directory?: string | read-sourcewrite-generated | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | none |
xeer_deploy_preview | deploy.preview | author / operator | Build and deploy an artifact to preview only. | directory?: stringcontrolUrl?: string | read-sourcewrite-generatedrun-localnetwork-readnetwork-write | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | A human must establish the builder credential with xeer auth login, or issue the service token supplied in XEER_SERVICE_TOKEN. |
xeer_promote | promote.operator | operator | Promote an exact review receipt in operator mode. | directory?: stringreceiptId: stringcontrolUrl?: string | network-readnetwork-writeproduction-change | writes; non-idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | A human must review the exact artifact and start xeer-mcp with XEER_MCP_PROFILE=operator. |
xeer_auth_status | auth.status | author / operator | Report builder credential metadata. | controlUrl?: string | network-readsecret-metadata | read-only; idempotent; reversible; non-destructive | none | xeer.command.v0 | none |
xeer_inspect | inspect | author / operator | Read a running application manifest. | previewUrl: stringview?: manifest / state / logs / export; default manifestafter?: string | network-readread-state | read-only; idempotent; reversible; non-destructive | app-or-url | xeer.command.v0 | none |
xeer_dev_start | dev.start | author / operator | Start a local development session. | directory?: stringhost?: stringport?: integer [0..65535]share?: booleantimeoutMilliseconds?: integer [1000..600000] | read-sourcewrite-generatedrun-localwrite-statenetwork-readnetwork-write | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.dev.v0 | none |
xeer_dev_status | dev.status | author / operator | Read new events from a local development session. | sessionId?: stringcursor?: integer [0..9007199254740991]; default 0waitMilliseconds?: integer [0..600000]; default 0limit?: integer [1..1000]; default 200 | none | read-only; idempotent; reversible; non-destructive | none | xeer.dev.v0 | none |
xeer_dev_stop | dev.stop | author / operator | Stop a local development session and release its lease. | sessionId?: stringcursor?: integer [0..9007199254740991]; default 0 | run-local | writes; idempotent; reversible; non-destructive | none | xeer.dev.v0 | none |
xeer_diagnostics | diagnostics | author / operator | Explain one emitted diagnostic code. | code: string | none | read-only; idempotent; reversible; non-destructive | none | xeer.command.v0 | none |
CLI actions intentionally excluded from MCP (36).
| CLI action | Action | Summary | Effects | Safety | Path policy | Output | Why no MCP tool |
|---|---|---|---|---|---|---|---|
xeer init | init | Initialize Xeer in an existing SvelteKit project. | read-sourcewrite-sourcerun-localnetwork-read | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer agent setup | agent.setup | Install or verify project-confined agent adapters. | read-sourcewrite-source | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer deploy | deploy | Build and deploy a project artifact. | read-sourcewrite-generatedrun-localnetwork-readnetwork-writeproduction-change | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | MCP exposes a separate preview-only deploy action; direct production deploy stays CLI-only. |
xeer promote | promote | Promote a preview artifact to production. | network-readnetwork-writeproduction-change | writes; non-idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | MCP promotion is a separate action available only when the server starts in operator profile. |
xeer tunnel | tunnel.start | Expose a loopback HTTP server through an authenticated tunnel. | run-localnetwork-readnetwork-write | writes; non-idempotent; reversible; non-destructive | none | xeer.tunnel.cli.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer link | link | Link a checkout to an application the builder owns. | read-sourcewrite-sourcenetwork-readnetwork-write | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Human identity and project ownership decisions are not delegated through MCP. |
xeer deployments | deployments | List deployment history for an application. | network-readread-statesecret-metadata | read-only; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer rollback | rollback | Redeploy a previously deployed artifact. | network-readnetwork-writeproduction-change | writes; non-idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer disable | disable | Take an application offline without deleting its data. | network-readnetwork-writeproduction-change | writes; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer enable | enable | Restore a disabled application to service. | network-readnetwork-writeproduction-change | writes; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer delete | delete | Permanently delete an application and all of its data. | network-readnetwork-writewrite-stateproduction-change | writes; non-idempotent; irreversible; destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer domains add | domains.add | Attach a customer-owned hostname to an application. | network-readnetwork-writeproduction-change | writes; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer domains ls | domains.ls | List an application's platform and custom domains. | network-read | read-only; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer domains status | domains.status | Refresh hostname and certificate validation. | network-readnetwork-writeproduction-change | writes; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer domains remove | domains.remove | Detach a custom hostname and delete its provider certificate. | network-readnetwork-writeproduction-change | writes; idempotent; reversible; destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer preview | preview | Run a verified artifact in a local preview server. | read-sourcewrite-generatedrun-localwrite-state | writes; non-idempotent; reversible; non-destructive | project-relative | xeer.dev.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer state | state.read | Read record counts from a running application. | network-readread-state | read-only; idempotent; reversible; non-destructive | app-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer state reset | state.reset | Permanently reset local environment state. | read-sourcewrite-state | writes; non-idempotent; irreversible; destructive | project-relative | xeer.command.v0 | Destructive state replacement requires an explicit CLI invocation. |
xeer logs | logs | Read the bounded log ring of a running application. | network-readread-state | read-only; idempotent; reversible; non-destructive | app-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer export | export | Export application state to a document. | network-readread-statewrite-file | writes; idempotent; reversible; non-destructive | project-or-url | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer import | import | Replace local or preview state from an export document. | read-sourcenetwork-writewrite-state | writes; non-idempotent; irreversible; destructive | project-or-url | xeer.command.v0 | Destructive state replacement requires an explicit CLI invocation. |
xeer auth login | auth.login | Establish a human builder credential. | network-readnetwork-writesecret-write | writes; non-idempotent; reversible; non-destructive | none | xeer.command.v0 | Human identity and project ownership decisions are not delegated through MCP. |
xeer auth logout | auth.logout | Remove the local builder credential. | network-writesecret-write | writes; idempotent; reversible; non-destructive | none | xeer.command.v0 | Human identity and project ownership decisions are not delegated through MCP. |
xeer auth as | auth.as | Select a deterministic local development persona. | write-state | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer auth clear | auth.clear | Reset the local development persona. | write-state | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer env set | env.set | Set an environment value or secret. | network-writewrite-statesecret-write | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Secret values are intentionally unreachable through MCP; env pull returns plaintext. |
xeer env ls | env.ls | List environment variable names and metadata. | network-readsecret-metadata | read-only; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Secret values are intentionally unreachable through MCP; env pull returns plaintext. |
xeer env rm | env.rm | Remove an environment value or secret. | network-writewrite-statesecret-write | writes; idempotent; irreversible; destructive | project-relative | xeer.command.v0 | Secret values are intentionally unreachable through MCP; env pull returns plaintext. |
xeer env pull | env.pull | Write development secrets to a local file. | network-readwrite-filesecret-read | writes; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Secret values are intentionally unreachable through MCP; env pull returns plaintext. |
xeer token create | token.create | Issue a service builder token. | network-writesecret-write | writes; non-idempotent; reversible; non-destructive | none | xeer.command.v0 | Service credential issuance and revocation are intentionally CLI-only. |
xeer token ls | token.ls | List service token metadata. | network-readsecret-metadata | read-only; idempotent; reversible; non-destructive | none | xeer.command.v0 | Service credential issuance and revocation are intentionally CLI-only. |
xeer token revoke | token.revoke | Revoke a service builder token. | network-writesecret-write | writes; idempotent; irreversible; destructive | none | xeer.command.v0 | Service credential issuance and revocation are intentionally CLI-only. |
xeer actions | actions | Print the machine-readable action and safety catalogue. | none | read-only; idempotent; reversible; non-destructive | none | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer db tables | db.tables | List the tables of a running application database. | read-state | read-only; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer db schema | db.schema | Print the declared schema of a running application database. | read-state | read-only; idempotent; reversible; non-destructive | project-relative | xeer.command.v0 | Not exposed through MCP v0; use the CLI deliberately. |
xeer db exec | db.exec | Run one SQL statement against a running application database. | read-statewrite-state | writes; non-idempotent; irreversible; non-destructive | project-relative | xeer.command.v0 | Destructive state replacement requires an explicit CLI invocation. |
Every tool returns { protocol: "xeer.mcp-result.v0", action, ok, result?, error? } as both structured
content and a JSON text block. Command tools preserve the CLI's xeer.command.v0 envelope at
result.envelope; host argv, raw stderr, and absolute directories are omitted. When the CLI crashes
without printing an envelope the server synthesizes XE0000. Tool-level refusals use a stable
error.code without becoming MCP transport errors.
XEER_MCP_ROOT is a confinement root: a directory argument that escapes it is refused.
For the complete policy surface, xeer actions --json returns xeer.actions.v0: every CLI
and MCP action's effects, safety properties, human prerequisites, path policy, and any MCP
exclusion reason. Use it instead of inferring approval needs from prose.
#Why dev is three tools
A tool call is request/response; xeer dev is a long-lived stream. So the session is owned by the server
and addressed by a sessionId, with the protocol's own sequence number as a resumable cursor:
xeer_dev_start → { result: { sessionId, cursor, status: 'ready', preview: { url, … }, events } }
edit a file
xeer_dev_status → { result: { events: [compile.start, compile.diagnostic?, compile.ready?], openDiagnostics } }
xeer_dev_stop → { result: { status: 'stopped' } }No event is summarised away — the agent reads the same stream a terminal would show. Repairing diagnostics
needs none of this, because xeer_check runs the same compiler; the session exists for when the running
app matters.
Always stop a session you started: local state is leased per project, so a leaked session makes the next
run fail with XE1812.
#The loop that works
xeer new → edit → xeer check → edit → xeer test → xeer build → xeer deploy
↑___________| ↑____________|Two things make this reliable rather than hopeful:
xeer checkis fast and complete. It validates the manifest and analyses both source graphs without running anything, so the edit-check loop is tight and every failure is located.xeer testproves behaviour, not compilation. An agent that only checks has proved the code parses. An agent that tests has proved the app does what the tests say — including who is allowed to do what, because tests run as three different users.
The step most worth insisting on is the second one. Xeer ships a test runner precisely so that "it compiles" is never mistaken for "it works", and an agent with no human reviewing every diff needs that distinction more than a person does.
#Why the framework's shape helps
- One declarative manifest. An agent can read what an app is — its tables, its indexes, its capabilities — without inferring it from code. And it can change what an app is by editing one file, which the compiler then validates.
- Deny by default.
ctxhas three properties. There is no ambient resource an agent can reach for by accident, and no credential lying around to misuse. - A closed, small API. Seven database methods, six input types, four matchers. It fits in a context window, which means an agent is choosing between options it can actually enumerate rather than guessing at an API surface.
- Authorization in the data layer. A table policy holds for every read and write of that table, so a handler an agent wrote cannot leak rows by forgetting a filter.
- Content-addressed builds. The same source produces the same artifact id, and promote and rollback act on that id — so "ship exactly what was reviewed" is mechanical rather than a matter of trust.
#These docs, as plain text
This site is not the only form the documentation comes in. Every page is also served as Markdown, so an agent never has to scrape HTML to read it:
/llms.txt | The index: what Xeer is, and every page with its purpose and its Markdown URL. |
/llms-full.txt | The entire documentation in one request. |
<page>.md | Any page on its own — /guides/server.md, /reference/cli.md, and so on. |
The diagnostics reference in there is generated from the compiler's own catalogue, so the codes an agent reads cannot drift from the codes the platform emits.
/docs.json is the compact, versioned registry: every page's title, description, headings,
Markdown URL, canonical URL, framework compatibility range, and SHA-256 content hash. The website,
per-page Markdown, llms.txt, installed offline bundle, search, and MCP resources all derive from one
page registry.
#Provider-specific projections
The repository keeps its canonical portable skill under
.agents/skills/xeer/ and generates provider projections, including
the generated diagnostics catalogue. Use xeer agent setup --target claude for the
Claude-compatible project files; use the corresponding codex, cursor, or vscode target for
those harnesses. The generated copies carry their source hash and should not be edited independently.
#Next
- Diagnostics reference — every code, what it means, how to repair it.
- CLI reference — every command and its
--jsonshape. - Testing — the step to insist on.