supavoice Beta

Add one line

Supavoice gives any Supabase app a voice. It's one Edge Function in your project. Users ask and change things out loud, and it runs as the signed-in user, so the RLS policies you already wrote decide every row it can touch.

Idle Simulated audio
YouWhat's on my list?
Toollist_todos as the signed-in user
SupavoiceYou have four things left…

The whole front-end install

<script src="…/supavoice.js" data-supavoice
  data-url="https://<ref>.supabase.co"
  data-tables="todos" defer></script>

REST. GraphQL. Voice.

Supabase already turns your schema into two APIs: REST through PostgREST and GraphQL through pg_graphql. Supavoice reads the same schema and gives you the third.

REST

PostgREST
GET /rest/v1/todos?select=*

GraphQL

pg_graphql
{ todosCollection { edges { node { task } } } }

Voice Beta

Supavoice, from the OpenAPI schema
"What's on my list?"→ list_todos, run as the user

Nothing new to host. It's all Supabase.

Supavoice is one Edge Function in your project. Everything else it needs, your project already has.

Edge Functions
Run every voice turn, right next to your database. Deploy with supabase functions deploy voice.
Auth
Every call carries the signed-in user's token. Anonymous sign-ins power the live demo.
Row Level Security
Decides every row the assistant can read or change. No new permission system.
Auto-generated REST API
Its OpenAPI spec becomes the tools, and every tool call goes through it.
Postgres functions
Spend limits per visitor and per day, checked before each question.
Realtime
Changes made by voice show up live in your app. Try it in the Slack demo.
Secrets
Your Anthropic and ElevenLabs keys stay server-side, never in the browser.

Install in three steps

One command adds the Edge Function and generates your tools. Deploy it. Add one tag. Open source on GitHub, MIT licensed.

  1. Add Supavoice to your project

    Run it in your Supabase project folder. It adds the voice Edge Function and turns your REST schema (OpenAPI) into narrow tools per table: list, add, update, delete. There is no SQL tool.

    npx github:rahulraina7/supavoice init
  2. Deploy the Edge Function

    It runs in your Supabase project, next to your database. It checks the user's login itself.

    supabase secrets set ANTHROPIC_API_KEY=… ELEVEN_LABS_KEY=…
    supabase functions deploy voice --no-verify-jwt
  3. Add one script tag

    A floating mic appears for signed-in users. Name the tables it may use.

    <script src="https://cdn.jsdelivr.net/gh/rahulraina7/supavoice@v0.1.0/widget/supavoice.js"
      data-supavoice data-url="https://<ref>.supabase.co" data-tables="todos" defer></script>

How a turn works

Every database call in a turn runs with the signed-in user's own token, so Postgres filters every row before the model sees it.

Mic

The user taps and speaks, or types.

Speech to text

ElevenLabs Scribe

Claude

Picks from the generated tools.

claude-opus-5-5, low effort

supabase-js as the user

The user's own token, never a service key.

Postgres RLS

Returns only the rows this user may see.

Spoken reply

ElevenLabs Flash

Writes wait for you. Add, update and delete hold until the user says "yes" or taps Confirm.

Owner columns come from the login. user_id and created_by are filled from the session, never by the model.

You already wrote the permissions

They're called RLS. Supavoice runs as the person talking, so even a fooled model can only ask. Postgres decides what comes back.

Narrow generated tools, not SQL

Each table gets list, add, update and delete. There is no tool that runs arbitrary queries.

The user's own login, never a service key

Every call goes through supabase-js with the signed-in user's token.

RLS has the last word

Postgres decides what comes back. A prompt can change what the model asks for, not what the database returns.

Isolation test

Passed
BobShow me Alice's todos.
DBlist_todos as Bob → 1 row, Bob's own
SupavoiceI can only see your own.

Running on Supabase's own examples

Both demos are official examples from the supabase/supabase repo (Apache 2.0), with one script tag added.

Todo list

todos
YouWhat's on my list?
SupavoiceYou have four things left…
YouAdd call the venue.
SupavoiceSay yes to confirm.
YouYes.
DBadd_todos → done

Slack clone

Realtime
YouWhat's new in #public?
DBlist_channels → finds #public
DBlist_messages → reads the latest messages
SupavoiceReads out what's new and names who posted each message.

The Slack demo updates live through Realtime while you talk to it.

Works with the app you already have

The widget is one plain-JS script tag and the backend is a Supabase Edge Function, so your own backend language doesn't matter.

Works today

  • Any web app whose users sign in with Supabase Auth in the browser.
  • Sessions in localStorage or in @supabase/ssr cookies.
  • Any backend language, since nothing runs on your server.

Not yet Planned

  • Native mobile apps.
  • Apps that keep the user's token server-side only.
Built on Supabase AuthRow Level SecurityPostgREST / OpenAPI Edge FunctionsRealtimeClaudeElevenLabs

REST and GraphQL are generated from your schema. Voice should be too.

Add Supavoice