MorphDB
// a backend for vibe-coded sites

Schema fluid.
API stable.

A coding agent reshapes your data model as fast as it changes the UI — no migrations — while the site keeps hitting the same frozen endpoints. And one instance hosts every site you build, each a fully isolated tenant. The demo below isn't a mockup — it's wired to the live database. Try it:

demo app · demo one shared demo tenant on the live database — isolated from every other app's data
schema · the agent edits this
task
  • titlestring
  • doneboolean
your site · what your users see
No tasks yet.
Persist one and your site renders it right here — like a real app would.
rendered from GET /objects/task · same URL forever, however the schema morphs
//Step 1. Type a task and persist it — it saves to a real database and renders on the right.
01 the problem

When you vibe-code, the data model never sits still.

Add a field, split a type, link two things — every change normally means rewriting a database schema and migrating every existing row. So the design churn that makes building fun becomes the thing that slows you down.

MorphDB makes a schema edit free and instant, and keeps the HTTP API frozen while the shape underneath changes. The agent stops fighting the database and just builds.

02 the mental model

Apps → types → objects.

Three nested ideas. The outermost one — the app — is the other half of the story: it's what makes MorphDB multi-tenant. Every site you ship is its own app, and they all live in one process behind one set of URLs.

appone per website · a hard isolation boundary
A single MorphDB process hosts thousands of apps (tenants). Each request carries an X-App-Key; that key — and nothing else — decides whose data you touch. No data, schema, or type name leaks across apps. One deploy backs every site you build.
typefields + relations
Your data model inside an app — like task, user. Just a set of fields (raw values) and relations (links to other types). The agent reshapes these constantly. Two different apps can both own a task type with totally different shapes.
objectthe instances · each has a _guid
The actual rows — one task, one user. Written and read by the site over generic endpoints. Relations ride along as fields on the object body.
demo appdemo
Persist an object in the demo above — it lands in the shared demo app and shows up right here.
someone else's appacme_store
loading a different tenant…
both panels call the exact same path — GET /objects/task — only the X-App-Key header differs

That's multi-tenancy, live. Same process, same URL, two apps that have never heard of each other. The key on the request is the only thing that picks a universe — which is exactly why a coding agent can spin up a fresh backend per project without standing up new infrastructure. Schema-fluid is how fast you build one site; multi-tenant is how one MorphDB backs all of them.

03 the big idea

Two audiences, one database.

MorphDB cleanly separates who changes the shape from who moves the data — and that separation is why the API can stay frozen.

you · the coding agent

Reshape the schema

Call tools to add a field, declare a relation, retype something. Instant, O(1), no rows rewritten.

acts on the schema, via the morphdb CLI
schema add-fieldschema add-relationschema showschema set
the site · your frontend

Read & write data

Plain fetch against generic object endpoints. These URLs never change when the schema morphs.

acts on the data, over stable http
POST /objects/taskGET /objects/task?done=falsePATCH /objects/task/{id}
both meet at one SQLite-backed process — schema edits never touch the endpoints the site calls.
04 why it doesn't break

Lazy invalidation: rows are never migrated.

How can the shape change under live data without breaking it? Every object is stored as raw JSON and projected through the current schema on every read.

Add a field → old rows simply read it as empty (or its default). Drop a field → it vanishes from the view, the bytes stay put. Retype a field → a value that no longer fits reads as unset until rewritten. A schema edit is one tiny metadata write — zero row rewrites, whether you have ten objects or ten million.

05 relations

Declared once. Inverse for free. Filterable like a foreign key.

A relation is declared on one side; the inverse appears automatically on the other. Under the hood each link is a single row in an indexed edge table — so you can traverse both ways in one read, and filter a list by it like an ORM foreign key.

business name · score stage status · label stages ▸ ◂ business one business · many stages
filter a list by a relation
GET /objects/stage?business=<guid>&status=build
"All of this business's stages that are in build." The relation filter is resolved through the indexed edge table and composes with field filters, sort, and pagination — so you model a link as a relation, never a guid-bearing string field.
06 how claude plugs in

The agent reshapes schema by running the morphdb CLI.

Claude Code edits the data model with ordinary shell commands — morphdb schema add-field, morphdb schema add-relation, … — against the backend it already started with morphdb start. No extra server, no MCP wiring, no restart: pip install morphdb and the agent has them.

the agent edits the model — ordinary shell commands
morphdb app register my-site
morphdb schema add-field task done boolean --index
morphdb schema add-relation task assignee --to user --cardinality many_to_one --inverse tasks
morphdb query task 'done=false&sort=priority'
11 commands under morphdb app · morphdb schema · morphdb query, all talking to the one backend morphdb start runs (or a hosted one via $MORPHDB_HOST) — so there's always a single writer.
07 under the hood

Two files from the standard library. Nothing else.

MorphDB is deliberately tiny and dependency-free, so a coding agent can install and reason about all of it.

0 dependencies — just Python's http.server + sqlite3
Daemon
morphdb start — the HTTP backend, backgrounded.
CLI
start · stop · status · logs · dashboard
Schema CLI
morphdb app · schema · query — the agent edits the model, no curl.
Claude skill
teaches the agent the whole workflow.
Dashboard
read-only ER view of every app + type.