scribase
Agent recipes

Ten one-prompt backends

Paste one of these into an agent already connected to the Scribase MCP server (https://api.scribase.com/mcp) and it builds the feature, not just a table. Each one names the exact tools the agent calls and how to tell it actually worked.

SaaS with teams and billing

Multi-tenant tables scoped by team membership, not a shared `team_id` column nobody checks.

Prompt
Create a Scribase backend for a multi-tenant SaaS. Add `teams` and `memberships` tables, then a `projects` table scoped to the caller's team through a membership check (not just a `team_id` filter). Enable row-level security on every table and prove it with policy.test before applying. List the billing products already on my connected payment account.
Tools called, in order
projects.create → migrations.apply → policy.test → schema.apply → billing.products
How to tell it worked
Sign in as two different users in two different teams and confirm each only ever sees their own team's `projects` rows.

Marketplace with file uploads

A private bucket per listing photo, readable by anyone, writable only by the listing's owner.

Prompt
Create a Scribase backend for a marketplace app. Add a `listings` table owned by the signed-in seller, and a storage bucket for listing photos where anyone can read but only the listing's owner can upload. Enable row-level security on `listings` and on `storage.objects` for that bucket.
Tools called, in order
projects.create → migrations.apply → storage.buckets.create → policy.test → schema.apply
How to tell it worked
Upload a photo as the listing owner, then confirm a different signed-in user can view it but a signed-out request to upload it is rejected.

Realtime chat

A `messages` table whose row changes stream to the right room only, because the subscription honors RLS.

Prompt
Create a Scribase backend for a chat app with `rooms`, `room_members` and `messages` tables. A message is only visible to members of its room — row-level security, not a client-side filter. Show me the supabase-js code that subscribes to new messages in a room over realtime.
Tools called, in order
projects.create → migrations.apply → policy.test → schema.apply
How to tell it worked
Open two browser sessions as two different room members and confirm a message posted in one appears live in the other, but never in a session for a non-member.

Mobile app with Apple/Google sign-in, push and OTA

signInWithIdToken for both providers, a push token table, and an update channel — in one pass.

Prompt
Set up native Apple and Google sign-in for my Expo app on Scribase (signInWithIdToken, no client secret on the device). Add a `profiles` table that is created on first sign-in. Turn on push notifications and over-the-air updates for this project and show me the client code for each.
Tools called, in order
auth.config.set → migrations.apply → capabilities.add (slot push) → capabilities.add (slot ota) → push.status → ota.status
How to tell it worked
Sign in on a real device with Apple or Google, confirm a `profiles` row was created for that user, then send a test push and ship an OTA update to it.

AI app with vector search

One call turns on pgvector and creates the embeddings table and match function together.

Prompt
Enable vector search on this Scribase project with a search table for document embeddings, and show me how to insert an embedding from the app and run a similarity search against it.
Tools called, in order
extensions.enable (name: vector, search_table: true) → ai.keys
How to tell it worked
Insert two embeddings for clearly different text and confirm a similarity query ranks the closer one first.

Scheduled jobs and digests

A pg_cron job that runs a function on a timer, with its own run log.

Prompt
Add a scheduled job on this Scribase project that runs a `weekly-digest` edge function every Monday at 08:00 UTC, and deploy a starter version of that function that just logs when it ran.
Tools called, in order
functions.deploy → schedule.create → schedule.runs
How to tell it worked
Run the job once with schedule.run outside its timer and confirm it shows up in schedule.runs with a succeeded status.

Background queues

pgmq as a durable queue, no separate message broker to run.

Prompt
Enable a background job queue on this Scribase project for processing uploaded images asynchronously, and show me how to send a job from the app and read/archive it from a worker.
Tools called, in order
extensions.enable (name: pgmq)
How to tell it worked
Send one message, read it back in a worker loop, and confirm archiving it removes it from the queue's pending count.

Transactional and broadcast email

Turn email on with one call; it sends through the built-in Mail Studio, no SMTP setup.

Prompt
Turn on email for this Scribase project and send a real test email to my own address to prove it works, then show me how to send a transactional "welcome" email from an edge function and how to create a broadcast list for a product update.
Tools called, in order
capabilities.add (slot email) → capabilities.status
How to tell it worked
The proof record from capabilities.status shows a sent email with a real message id, and the test address actually received it.

Preview branch per pull request

Every PR gets its own live copy-on-write database, linked, migrated, and torn down automatically.

Prompt
Give pull request #<number> on <owner>/<repo> its own Scribase branch with sanitized data, link it to the PR so GitHub shows a status comment, and apply the pending migrations to that branch only.
Tools called, in order
branches.create → branch.link_pull_request → migrate.run → branches.merge → branches.delete
How to tell it worked
The PR shows a status comment with the branch's URL, and a query against production from the same session still returns production's own data, unchanged.

Migrate from Supabase or Neon

Schema, data, auth users and storage move with their IDs intact — a dry run shows exactly what before anything does.

Prompt
I have an existing Supabase project at <project-ref>. Dry-run an import of it into a new Scribase project and show me exactly what would move (tables, auth users, storage objects, RLS policies) before actually doing it.
Tools called, in order
import.supabase (dry_run: true) → import.supabase → import.status
How to tell it worked
After the real import, sign in as an existing user with their original password and confirm the session succeeds without a reset — then repeat for a plain Postgres source (Neon, Render, RDS) with import.postgres, which needs only a connection string.