supabase-mcp-server
Provides read-mostly, row-level-security-aware access to a Supabase Postgres database, with tools to inspect schemas, tables, columns, and RLS policies; run filtered selects and counts; optionally execute read-only SQL; and optionally insert a single row subject to RLS policies.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@supabase-mcp-serverDescribe the tasks table and show me its RLS policies"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
supabase-mcp-server
A Model Context Protocol (MCP) server that gives Claude (or any MCP client) read-mostly, row-level-security-aware access to a Supabase Postgres database. Personal open-source project, built with AI coding agents and tested like a QA engineer would want it tested.
The point of the repo is the safety model and the tests around it, not the number of tools.
What it does
Tool | Default | What it does |
| on | Role, |
| on | Tables/views in the exposed schemas that the role can see, with the RLS flag |
| on | Columns, RLS flag, RLS policy names and commands |
| on | Structured select: columns, filters ( |
| on | Count with the same filters |
|
| One |
|
| Insert one row; RLS insert policies decide |
Related MCP server: mcp-data-gateway
Safety model
Every tool call runs in its own transaction that:
switches to the Supabase API role with
SET LOCAL ROLE anon | authenticated, so the connection's own privileges are not used for queries;sets
request.jwt.claims/request.jwt.claim.subthe way PostgREST does, soauth.uid()and every RLS policy behave as they would for a supabase-js client signed in asMCP_USER_ID;is
READ ONLYfor every tool exceptinsert_row;has a
statement_timeout(MCP_STATEMENT_TIMEOUT_MS, default 5000).
On top of that:
Identifiers must be plain names (validated with zod), are checked against the live catalog as seen by the role, and are always quoted. Values are always bound parameters.
Only schemas in
MCP_SCHEMAScan be named.auth,storageandpg_catalogare not reachable by default.Results are capped at
MCP_MAX_ROWS(default 100, max 1000), enforced in the tool's input schema.run_select_sqlhas a literal/comment-aware guard (single statement,SELECT/WITH/VALUES/TABLEonly, no DML/DDL keywords). The guard gives early, clear errors; the read-only transaction and the role are what actually prevent writes.Errors are returned as tool results (
isError: true) with the Postgres code and a short hint (e.g.42501: permission denied (row-level security or grants)), so the model can correct itself. Unknown tools are JSON-RPC errors (-32602), as the spec requires.The server logs only to stderr and never prints the connection string.
What it does not do: verify a user's JWT. You choose the role and user id in the server's environment. Treat it as a local developer tool for your own data, not as a multi-user gateway. Never point it at a connection that uses service_role.
Protocol version
Built on the official TypeScript SDK (@modelcontextprotocol/sdk 1.32.2), which negotiates MCP 2025-11-25. The spec has a newer revision (2026-07-28); the server will move to it when the SDK does. The low-level Server API is used so error handling follows the spec exactly (see above).
Quick start (local Supabase)
Needs Node 22+ (24 recommended), Docker and the Supabase CLI.
git clone https://github.com/mustafaautomation/supabase-mcp-server.git
cd supabase-mcp-server
npm ci && npm run build
supabase db start # Postgres on 54322, applies supabase/migrations and supabase/seed.sqlThe demo schema has projects (public or private, owned by a user) and tasks (visible when their project is), plus an internal_notes table with no grants for API roles. The seed uses two fixed user ids: alice 11111111-1111-4111-8111-111111111111 and bob 22222222-2222-4222-8222-222222222222.
Claude Desktop
Add to claude_desktop_config.json (Settings → Developer → Edit Config), using the absolute path to your clone:
{
"mcpServers": {
"supabase-local": {
"command": "node",
"args": ["/absolute/path/to/supabase-mcp-server/dist/src/index.js"],
"env": {
"DATABASE_URL": "postgresql://postgres:postgres@127.0.0.1:54322/postgres",
"MCP_DB_ROLE": "authenticated",
"MCP_USER_ID": "11111111-1111-4111-8111-111111111111"
}
}
}
}Restart Claude Desktop, then ask e.g. "Which of my projects have open tasks?".
Claude Code
claude mcp add supabase-local \
--env DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres \
--env MCP_DB_ROLE=anon \
-- node "$PWD/dist/src/index.js"
claude mcp listAdd --scope project to write a shareable .mcp.json instead (keep real connection strings out of it).
MCP Inspector
npx @modelcontextprotocol/inspector --cli -e DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres \
--method tools/list -- node dist/src/index.jsConfiguration
Variable | Default | Notes |
| required | A role that can |
|
|
|
| none | uuid returned by |
|
| Comma-separated allowlist |
|
| 1–1000 |
|
| 100–60000 |
|
| Registers |
|
| Registers |
Invalid configuration stops the server at startup with exit code 2 and a message naming the variable.
Tests
Layer | Where | What it covers |
Unit |
| Config parsing, SQL builder (parameters, quoting), the SQL guard (comments, literals, dollar quotes, multi-statement), error mapping |
Integration |
| Through a real MCP client (in-memory transport) against Postgres: anon vs alice vs bob visibility, tasks inheriting project RLS, invisible ungranted table, unknown columns and schemas, injection strings as data, row cap, read-only transaction, statement timeout, RLS blocking spoofed inserts, opt-in tools hidden by default, protocol errors |
stdio e2e |
| The built server as a child process, the way Claude starts it: handshake, tool list, a real query, bad arguments, unknown tool, stderr-only logging, exit code 2 on bad config |
Inspector | CI |
|
Conformance | CI | mcp-conformance-tests (pinned) must pass all MUST checks |
I checked that the RLS tests catch a real regression: with the SET LOCAL ROLE line removed, the visibility and insert-policy tests fail.
npm test # unit, no database
supabase db start
npm run build && npm run test:integration && npm run test:e2e
DATABASE_URL=postgresql://... npm run test:integration # any Postgres 15+; a shim adds roles and auth.uid()CI
.github/workflows/ci.yml; every job must pass:
checks: ESLint, Prettier,
tsc, unit tests, buildsupabase: Supabase CLI 2.122
supabase db start, integration and stdio tests, Inspector CLI smoke test, conformance runplain-postgres: the same integration and stdio tests against a
postgres:17service with the shim intests/sqlsecrets: gitleaks over the full git history
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Your Supabase account in natural language: run SQL, apply migrations, manage tables, storage, edge f
Query your Postgres from ChatGPT or Claude without exposing the database or handing over credentials. Run npx boltschema connect next to your database and it dials out over HTTPS — no inbound firewall rule, no open port, works with localhost and VPC-private databases. Read-only is enforced by a SQL guard, a Postgres READ ONLY transaction, and a scoped role generated for you.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to safely interact with PostgreSQL databases through read-only operations, providing schema discovery, table inspection, and query execution capabilities with structured context awareness.MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to query a PostgreSQL database through a small set of controlled, read-only tools for schema inspection, row lookup, and aggregate statistics.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables read-only, SELECT-only querying of any Postgres database through MCP-compatible clients like Claude, with schema introspection and guarded SQL execution.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to safely inspect and query PostgreSQL databases with read-only enforcement, row/timeout limits, and audit logging, providing tools for schema/table listing, read-only queries, query explanations, and table statistics.-