An AI agent can write every line of code in this build. It can't click "create project," hold your secret keys, or authorize a deploy. These five steps are the human half.
1. Project — create Supabase, get your keys
Create a project at supabase.com (free tier is fine). Once it's up, from Project Settings → API copy two things:
- Project URL —
https://<ref>.supabase.co - service-role key — the secret one, not the anon key. This is the key that bypasses RLS; treat it like a password.
Then get a Gemini API key from Google AI Studio. Three values in hand: Project URL, service-role key, Gemini key.
The anon key is public and you'll only need it later if you want to prove the RLS fence works. The service-role and Gemini keys are secrets — they go into Supabase, never into the browser or the repo.
2. Migration — link and push
Point the CLI at your project and run the migration from Step 2:
supabase link --project-ref <ref>
supabase db pushdb push applies init_rag_schema.sql: pgvector on, documents table, hnsw index, match_documents(), RLS enabled.
3. Secret — set the three server-side values
These live inside the Edge Functions and never touch the browser:
supabase secrets set \
PROJECT_URL=https://<ref>.supabase.co \
SERVICE_ROLE_KEY=<service-role-key> \
GEMINI_API_KEY=<your-gemini-key>Note the names deliberately avoid the SUPABASE_ prefix — that prefix is reserved by the Edge runtime, which injects its own values and refuses your overrides. Confirm they're set:
supabase secrets list # expect PROJECT_URL, SERVICE_ROLE_KEY, GEMINI_API_KEY4. Deploy — both functions, no JWT check
supabase functions deploy ingest query --no-verify-jwt--no-verify-jwt turns off Supabase's platform-level JWT check. That check expects a Supabase auth token on every call and would 401 the browser's direct requests before they ever reached your code. The functions are meant to be public here (the browser calls them directly), and config.toml already sets verify_jwt = false for both — the flag makes it explicit at deploy time.
Confirm they're live:
supabase functions list # ingest and query, both deployed5. Vercel — deploy the front-end
Deploy web/ to Vercel — either the CLI or importing the repo in the dashboard:
cd web && vercelThe one thing that must be set: the NEXT_PUBLIC_FUNCTIONS_URL environment variable in the Vercel project settings, pointed at:
https://<ref>.supabase.co/functions/v1That's the only value the front-end needs. No keys go into Vercel — the browser talks to Vercel and Supabase, never Gemini.
Smoke test — end to end
Prove the whole loop before you call it done.
Ingest some text (straight to the function, no UI needed):
curl -X POST https://<ref>.supabase.co/functions/v1/ingest \
-H "Content-Type: application/json" \
-d '{"text":"Brain Drip blueprints are short, buildable AI projects. The Agentic RAG one ships a Next.js app on Vercel backed by Supabase and Gemini.","source":"demo"}'
# {"ok":true,"source":"demo","chunks":1}Ask a question:
curl -X POST https://<ref>.supabase.co/functions/v1/query \
-H "Content-Type: application/json" \
-d '{"question":"What does the Agentic RAG blueprint ship?"}'
# {"answer":"It ships a Next.js app on Vercel backed by Supabase and Gemini [1].",
# "sources":[{"n":1,"source":"demo","similarity":0.82}]}If the answer cites [1] and lists demo as the source, every layer is working: the front-end's URL, the functions, the secrets, pgvector retrieval, and Gemini grounding. Now open your Vercel URL, paste real text, and ask away.
If the answer says "I don't know" with no sources, the table is empty — the ingest didn't land. Check supabase functions list and re-run the ingest curl. If either call 401s, you missed --no-verify-jwt. If ingest errors on insert, the migration didn't push or the secrets are wrong.
Step 7 is the production checklist — what to change before this points at anything real.