A Supabase MCP server for questions about your data.

Supabase's own MCP server helps your agent build: migrations, edge functions, logs. To let Claude Code, Cursor, or Codex answer questions from your production data, connect Supabase to Valv Desktop with a read-only Postgres role and point your client at http://127.0.0.1:4319/mcp. The agent can query the tables you allow. It can't write, run raw SQL, or see columns you hide.

Book a demo

Already know which one you want? Jump to the setup or the comparison.

Supabase's MCP server or Valv?

They solve different jobs, and many teams use both. Supabase's server is the better pick while you build the app. Valv is for reading the data the app collects.

Supabase MCP server Valv Desktop
Built for Building on Supabase: tables, migrations, edge functions, logs, branches, docs search. Answering questions from your data, with dashboards and alerts on top.
Runs Hosted at mcp.supabase.com. Nothing to install. On your machine while Valv Desktop is open.
Sign-in OAuth with your Supabase account, scoped with project_ref. A Postgres role you create. The password stays in your OS keychain.
Queries Raw SQL. With read_only=true it runs as a read-only Postgres user. Structured, validated queries. No raw SQL, no write tools.
Hiding data No column hiding. Limit tool groups with features. Hide columns or whole tables per datasource.
Other data Your Supabase project. Supabase next to MySQL, MongoDB, Excel and CSV files, and remote MCP servers like Stripe or PostHog.

Pick Supabase's server when the agent should change the project. Pick Valv when it should only read, when you want to hide columns like emails, or when the answer needs Supabase plus another source.

Setup

From a Supabase project to your first answer.

About ten minutes. Valv holds the connection. Your MCP client only knows a local URL.

  1. 1

    Create a read-only role.

    Run the SQL below in the Supabase SQL Editor. Don't hand the agent the postgres user: it can write, and it bypasses row level security.

  2. 2

    Copy the session pooler string.

    Click Connect at the top of the Supabase dashboard and copy the session pooler string. Swap postgres in the username for your role, keep the project ref after the dot, and fill in the password.

    postgresql://valv_agent.<project-ref>:<password>@<pooler-host>:5432/postgres?sslmode=require
  3. 3

    Add it to Valv as PostgreSQL.

    Paste the string to fill the form, test, and save. Valv starts with the public schema. Add analytics from the datasource's Active schemas menu, and hide columns you don't want the agent to read in the AI access tab.

  4. 4

    Add Valv to your MCP client.

    Open Settings, MCP Server, and copy the setup for your client. Port 4319 is the default. If it's taken, Valv uses another port, so copy the URL the app shows. Keep Valv open while you work.

Claude Code

CLI
claude mcp add --transport http valv-desktop http://127.0.0.1:4319/mcp

Codex

CLI
codex mcp add valv-desktop --url http://127.0.0.1:4319/mcp

GitHub Copilot

CLI
copilot mcp add --transport http valv-desktop http://127.0.0.1:4319/mcp

Cursor, VS Code, and other clients

JSON
{
  "mcpServers": {
    "valv-desktop": {
      "type": "http",
      "url": "http://127.0.0.1:4319/mcp"
    }
  }
}

Read-only role

A role Postgres won't let write.

Valv's agent tools are already read-only. The role adds a limit that Postgres enforces, whatever runs on top of it.

  • Through the shared pooler, this role logs in as valv_agent.<project-ref>. On the direct connection, it's just valv_agent.
  • Row level security applies to this role. Tables made in the Table Editor have RLS on, and without a policy the agent sees zero rows and no error.
  • The policy only allows reads, and only for valv_agent. Your app's anon and authenticated users are unaffected.
  • Rerun the table grant after you add tables, or add alter default privileges for the role that runs your migrations.
SQL Editor
-- Supabase SQL Editor (runs as postgres).
create role valv_agent with login password 'choose-a-strong-password';
alter role valv_agent set default_transaction_read_only = on;

grant usage on schema public to valv_agent;
grant select on all tables in schema public to valv_agent;

-- Tables with RLS on return zero rows to a role
-- without a policy. Add one per table the agent reads.
create policy "valv_agent can read" on public.orders
  for select to valv_agent using (true);

auth.users

Signups, without the emails.

Your signups live in auth.users, next to password hashes and tokens. Don't grant that table. Give the agent a view with the columns it needs.

  • The view runs as its owner, postgres, so it can read auth.users even though valv_agent can't.
  • That is also why it belongs in a private schema. A view like this in public would be served by the Data API to your app's users.
  • The same pattern works for any table where you want a few columns, or rows that RLS would hide.
SQL Editor
-- A private schema for product metrics. The Data API
-- doesn't expose it unless you add it in API settings.
create schema analytics;
grant usage on schema analytics to valv_agent;

-- Signups without emails, passwords, or tokens.
create view analytics.signups as
  select id,
         created_at,
         last_sign_in_at,
         raw_app_meta_data ->> 'provider' as provider
  from auth.users;

grant select on analytics.signups to valv_agent;

Which Supabase connection string?

The Connect dialog offers three. Valv connects from your machine, so your network decides which ones work.

Session pooler

<pooler-host>:5432, user role.<project-ref>

Use this one. IPv4 on every plan, and it supports the prepared statements Valv's Postgres driver uses.

Direct connection

db.<project-ref>.supabase.co:5432, user role

Works if your network has IPv6, or your project has the IPv4 add-on. Otherwise the host won't connect.

Transaction pooler

<pooler-host>:6543, user role.<project-ref>

Avoid. Transaction mode doesn't support prepared statements, so queries fail.

When it doesn't connect.

Valv shows the real Postgres error, and so does the agent. These are the common ones on Supabase.

Tenant or user not found You connected through the shared pooler without the project ref. The username is valv_agent.<project-ref>, not valv_agent.
Queries return no rows, but the table has data Row level security is on and valv_agent has no policy for that table. Add a select policy, or read it through a view in a private schema.
permission denied for table or schema Grant usage on the schema and select on the table to valv_agent. Repeat the grants for every schema you activate in Valv.
The connection times out on db.<project-ref>.supabase.co That host is IPv6 only unless you pay for the IPv4 add-on. Use the session pooler string instead.
Errors about prepared statements You're on the transaction pooler, port 6543. Switch to the session pooler on port 5432.

What to ask once it's connected.

Ask in Valv's chat or from your coding agent. Answers cite the queries behind them. Ask for a dashboard to keep a number on screen, or a flow to get a notification when it moves.

  • How many people signed up each week since June, split by sign-in provider?
  • Of the people who signed up in September, how many have signed in again since?
  • Which plan had the most new orders last month? Build me a dashboard for it.
  • Check signups every morning and tell me if they drop.

Supabase is Postgres underneath. For schemas, SSL modes, and other Postgres MCP servers, see the Postgres MCP server guide. For other databases, see the database MCP guide.

Supabase MCP, answered

What is the Supabase MCP server?

Supabase runs an official MCP server at mcp.supabase.com. After you sign in with OAuth, an agent like Claude Code or Cursor can list tables, run SQL, apply migrations, read logs, deploy edge functions, and search the Supabase docs. Add read_only=true to run queries as a read-only Postgres user, and project_ref to limit it to one project.

Should I connect the Supabase MCP server to production?

Supabase's own docs recommend a development project or branch, with read-only mode and manual approval of tool calls when you do touch real data. If you want an agent to answer questions from production data, connect it through a read-only Postgres role instead, so the database itself refuses writes.

Which Supabase connection string should I use in Valv?

The session pooler string from the Connect dialog, on port 5432. It works on IPv4 networks and supports prepared statements. Avoid the transaction pooler on port 6543. The direct connection only works on IPv6 networks unless your project has the IPv4 add-on.

Why does my agent see empty tables in Supabase?

Row level security. Tables created in the Supabase Table Editor have RLS on, and a custom role without a policy gets zero rows instead of an error. Add a select policy for the role, or expose the data through a view in a schema the Data API doesn't serve.

Can the agent read auth.users?

Only if you let it. A safer pattern is a view in a private schema that selects just the columns you need, such as id, created_at, and last_sign_in_at, and a grant on that view. Then activate that schema in Valv. Emails, password hashes, and tokens never reach the agent.

Can the agent write to my Supabase database through Valv?

No. Valv gives MCP clients discovery tools and a structured, read-only query tool, with no raw SQL, insert, update, delete, or DDL. A role with default_transaction_read_only on and only select grants adds a second limit that Postgres enforces.

Is it free?

Valv Desktop is free for personal, non-commercial use, with every feature included. Commercial use needs a seat license, a one-time $99 per user. Supabase's MCP server is free with your Supabase plan.

Ask your Supabase data, read-only.

Free for personal use, every feature included. Commercial use needs a seat at beta pricing. See pricing.

All downloads Other platforms and builds