Blog

A backend for coding agents: one YAML file to review

Why coding agents do better when the whole backend is one YAML file: install the instancez skill, connect the MCP server, and review its change as one diff.

Coding agents do better with a backend that lives in one file. When tables, row-level security, auth, storage and functions are all in instancez.yaml, the agent reads one file, edits one file, and checks its work with inz validate and inz vet. You review one diff, and that diff is the whole change.

We built instancez with that loop in mind. This post covers what the agent needs (the skill, and the MCP server if you use instancez Cloud), what a real agent edit looks like, and what to look for when you review it.

Why is a backend hard for a coding agent?

An agent works with what it can read. If your schema lives in a pile of migration files, your access rules live in SQL somewhere else, and your auth settings live in a dashboard, the agent has to piece the current state together before it can change anything. It often guesses. You then review a change against a state neither of you can see in one place.

instancez keeps that state in one place. The whole backend is one YAML file. instancez diffs it against the live database and applies only the change. There are no migration files for the agent to write, number or keep in order.

So the agent can read the full description of the backend top to bottom. It can check its own work offline: inz validate checks syntax and references, and inz vet lints the file for open policies and other security problems, both without a database. And because its change touches one file, git diff shows all of it.

What goes in the one file?

KeyWhat it defines
tables:Columns, types, defaults, foreign keys, indexes, and each table’s RLS policies
auth:JWT expiry, sign-up settings, redirect URLs, OAuth providers
storage:Buckets, size and type limits, bucket policies
rpc:SQL functions, served at /rest/v1/rpc/<name>
functions:JavaScript handlers on Node.js, served at /functions/v1/<name>
server:, providers:Ports, CORS, the storage backend, the email provider

Clients talk to it with @supabase/supabase-js, unchanged. So the agent writes the backend in YAML and the frontend in normal Supabase client code. For a deeper tour of the file, see your whole backend in one YAML file.

How do I teach my agent instancez?

The instancez repo ships an agent skill: one Markdown file that teaches the YAML syntax, RLS patterns, the split between rpc: and functions:, and the inz CLI. Install it with the skills CLI, which detects the agents you have:

npx skills add instancez/instancez

Or target one agent:

npx skills add instancez/instancez -a claude-code   # -> .claude/skills/
npx skills add instancez/instancez -a codex         # -> .agents/skills/

Claude Code users can install it as a plugin instead:

/plugin marketplace add instancez/instancez
/plugin install instancez@instancez

For any other agent, download SKILL.md and point your AGENTS.md at it. The coding agents docs have the exact commands.

The skill also carries the rules agents tend to trip on. Nothing is auto-added, not even an id column. Removing a table from the YAML drops it. The auth and storage schemas are reserved. It ends with a checklist the agent runs before it says it’s done: inz validate passes, every table sets rls_enabled, every update policy sets using, and secrets are ${INSTANCEZ_ENV_*} references, not literals.

How do I connect the instancez MCP server?

If your backend runs on instancez Cloud, you can also connect your agent over MCP. In Claude Code it’s one line:

claude mcp add instancez --transport http https://my.instancez.ai/mcp

For Codex:

codex mcp add instancez --url https://my.instancez.ai/mcp

Cursor, Windsurf and Antigravity take a JSON entry with the same URL; the snippets are on the instancez.ai home page. Once connected, the agent reads the config docs, edits instancez.yaml for your hosted project, deploys it, and waits for deploy_done, all inside the session you’re already in.

The skill and the MCP server fit different loops:

Skill + inz CLIMCP server
Where the YAML livesIn your repoIn your instancez Cloud project
What the agent runsinz validate, inz vet, inz devMCP tools that read docs, update the app and check the deploy
How you reviewgit diff, then a pull requestInside the agent session
Databaseinz dev --embedded-pg locally, or your own PostgresManaged by instancez Cloud

Both work on the same file format. You can also use the skill for day-to-day work in the repo and deploy to Cloud with inz cloud deploy, which shows a diff of what would change and asks before writing. Pricing for Cloud is on /pricing.

What does an agent’s change look like?

Here’s a concrete case. The project is a small blog with a posts table: anyone can read, only the author can write. You give the agent this prompt:

Add comments to posts. Only the author can edit theirs.

A correct change is one diff to one file. This is the diff we ran and tested for this post:

@@ -34,3 +34,35 @@ tables:
         with_check: "auth.uid() = user_id"
       - operations: [delete]
         using: "auth.uid() = user_id"
+
+  comments:
+    rls_enabled: true
+    fields:
+      - name: id
+        type: bigserial
+        primary_key: true
+      - name: post_id
+        foreign_key:
+          references: posts.id
+          on_delete: cascade
+      - name: user_id
+        foreign_key:
+          references: auth.users.id
+          on_delete: cascade
+      - name: body
+        type: text
+        required: true
+      - name: created_at
+        type: timestamptz
+        required: true
+        default: now()
+    rls:
+      - operations: [select]
+        using: "true"
+      - operations: [insert]
+        with_check: "auth.uid() = user_id"
+      - operations: [update]
+        using: "auth.uid() = user_id"
+        with_check: "auth.uid() = user_id"
+      - operations: [delete]
+        using: "auth.uid() = user_id"

That’s 32 added lines for the table, its foreign keys and its access rules. There’s no migration file to write and no dashboard step.

Before it hands the change back, the agent runs the two offline checks:

$ inz validate
  ✓ Schema valid

$ inz vet --fail-on medium
inz vet  instancez.yaml

 ● LOW       signup-unverified-email          instancez.yaml:9
 ● LOW       policy-open-read                 instancez.yaml:61
   tables.comments.rls[0].using
   This policy lets any caller, signed in or not, read all rows in comments.
   Fix: Scope it to the caller, or keep it only if the table is truly public.
 ● LOW       policy-open-read                 instancez.yaml:29

 0 critical · 0 high · 0 medium · 3 low · 0 info
 19 of 21 checks passed
 ✓ passed

We trimmed the detail under two of the low findings. The policy-open-read findings are expected here: the prompt asked for public comments on a public blog. vet tells you the read is open and leaves it to you to say whether that’s intended.

If inz dev is running, it picks up the saved file and re-applies the schema on its own. In our run the log showed config reloaded successfully tables=2 and GET /rest/v1/comments started returning 200 instead of 404, with no restart.

How should I review the agent’s diff?

The diff is small, so review it like any other code change. We read these lines closely:

  1. Every rls: block. Look for using: "true" or with_check: "true" on insert, update or delete. That means anyone can write. inz vet flags these as critical, but read them yourself too.
  2. rls_enabled on every new table. true with no policies means deny-all for the publishable key, which is the safe default.
  3. Every update policy sets using. An update policy needs using to pick which rows it applies to.
  4. Removed lines. A removed table or column in the YAML becomes a drop. inz dev applies drops with a logged warning. inz serve refuses to drop a table or column unless you start it with --allow-destructive, and the error names what would be lost.
  5. Literal secrets. API keys and OAuth secrets should be ${INSTANCEZ_ENV_*} references.

Then check runtime behavior, not just the file. inz dev --embedded-pg runs the whole backend locally with no Postgres install and no Docker (more on that here). Sign up two users with supabase-js and try to edit each other’s rows. We walk through that script, and what inz vet catches when an agent writes a bad policy, in RLS policies in YAML.

Finally, put inz vet in CI so a merge fails when a policy opens up:

- run: inz vet --fail-on medium

What doesn’t the agent need to handle?

Some backend features aren’t in instancez, so the agent won’t find them in the file. There’s no Realtime or websockets; poll or refetch instead. Phone and SMS login aren’t supported. OAuth covers Google, GitHub and Apple. Functions run on Node.js, so Supabase Edge Functions written for Deno need porting. The full list is on /compare. If you’re moving an existing Supabase project, start with migrating from Supabase.

FAQ

Does the agent need a running database to check its work? No. inz validate and inz vet both read only the YAML file. Use inz dev --embedded-pg when you want to run the backend and test real requests.

Which agents does the skill support? The skills CLI installs it for Claude Code, Codex, Cursor, OpenCode, Gemini CLI and GitHub Copilot. For anything else, the skill is one Markdown file you can reference from AGENTS.md.

Is the MCP server part of the open source binary? No. The MCP server at https://my.instancez.ai/mcp works with projects on instancez Cloud. For self-hosted projects, use the skill and the inz CLI; the agent edits instancez.yaml in your repo.

Can the agent delete my data by removing a table from the YAML? Under inz dev, yes: removals apply as drops, with a warning in the log. inz serve refuses destructive changes unless started with --allow-destructive. Review removed lines in every diff.