communitystdio

Supabase MCP Server

Run SQL against your Supabase project, manage auth users, and read storage buckets from Claude Code or Cursor.

Updated: April 15, 2026

Install

npx @supabase/mcp-server-supabase
~/.claude/settings.json
{
  "mcpServers": {
    "supabase-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase",
        "--supabase-url",
        "https://xxx.supabase.co",
        "--supabase-key",
        "your-service-role-key"
      ]
    }
  }
}

Capabilities

  • + Query Supabase tables via raw SQL with SELECT, INSERT, UPDATE, DELETE
  • + Manage auth users - create, invite, update metadata, and reset passwords
  • + Read and write objects across storage buckets
  • + Invoke Edge Functions synchronously and return the response body
  • + Inspect project settings including API keys and database connection strings
  • + Read Row Level Security policies attached to any table or schema

Limitations

  • - Service role key bypasses RLS, so any prompt can read any row - not safe for production data
  • - No real-time subscription support; the server cannot watch for row changes
  • - Edge Function invocation is synchronous and waits up to 30 seconds before timing out
  • - Project management operations like pausing or deleting are destructive and run without a confirmation prompt

Supabase MCP server setup for Claude Code and Cursor

Quick answer: The Supabase MCP server is a Node process that wraps the Supabase REST, Auth, Storage, and Edge Functions APIs as MCP tools. Install with one npx command, pass your project URL and service role key as flags, and Claude Code or Cursor can query tables, manage users, and call Edge Functions. Setup takes about 5 minutes, tested on server version 0.4.1 on April 15, 2026.

The Supabase MCP server turns your Supabase project into a toolbox that Claude can reach through the Model Context Protocol. Instead of copying SQL into the Supabase dashboard and pasting results back into chat, the editor runs queries for you, reads the rows, and keeps working. That loop is worth the 5 minutes of setup on the first day alone.

This guide walks through installation, config for Claude Code and Cursor, working prompt patterns, and the real limits you should know before you wire the server into a production project.

What this server does

The server speaks MCP over stdio and exposes roughly 20 tools backed by the official Supabase client libraries. When Claude wants to read a row, it calls query_table with a SQL string. When it wants to create an auth user, it calls create_user with an email and metadata payload. There is no ORM and no custom abstraction - the server forwards calls to Postgres and the Supabase HTTP API.

The main tool groups:

  • Database: query, insert, update, delete, list_tables, describe_table
  • Auth: list_users, create_user, update_user, delete_user, invite_user
  • Storage: list_buckets, list_objects, upload_object, download_object, delete_object
  • Edge Functions: invoke_function, list_functions
  • Project: get_project_settings, list_policies

Because the server runs locally, your service role key never leaves the machine. It sits in the subprocess env for the life of the session and gets re-read on every restart. The server writes no logs by default, so there is no file on disk that leaks the key.

Installing Supabase MCP

The package is published on npm as @supabase/mcp-server-supabase. You do not need to install it globally. The npx -y prefix in the config tells npm to fetch on first launch and cache after that. Cold start pulls about 6.8 MB and takes 3 to 4 seconds on a typical connection.

Before you touch any config, grab two values from the Supabase dashboard:

  1. Open your project in https://app.supabase.com and navigate to Settings > API.
  2. Copy the Project URL - it looks like https://abcdefg.supabase.co.
  3. Copy the service_role key, not the anon key. The service role key bypasses RLS, which is what you want for an agent that is acting on your behalf. Keep it out of any file you commit.

If you are wiring this into a production project, create a dedicated Postgres user with a narrower grant and use its JWT instead of the service role key. More on that in the troubleshooting section.

Configuring for Claude Code

Claude Code reads MCP servers from ~/.claude/mcp.json globally or .mcp.json in the project root. Add a supabase entry that runs the server with your URL and key as CLI flags:

{
  "mcpServers": {
    "supabase": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase",
        "--supabase-url",
        "https://xxx.supabase.co",
        "--supabase-key",
        "your-service-role-key"
      ],
      "env": {}
    }
  }
}

Restart Claude Code. Run /mcp inside the session to confirm Supabase is attached. You should see around 20 tool names listed. Call list_tables once as a smoke test - if it returns your schema, the wiring is correct.

For team projects, commit a placeholder version of .mcp.json and pass the real key via SUPABASE_SERVICE_ROLE_KEY in your shell, then reference it as $SUPABASE_SERVICE_ROLE_KEY in the args array. Claude Code expands env vars in config at spawn time.

Configuring for Cursor

Cursor uses the same MCP spec and reads from ~/.cursor/mcp.json on macOS and Linux or %USERPROFILE%\.cursor\mcp.json on Windows. The JSON is identical to Claude Code:

{
  "mcpServers": {
    "supabase": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase",
        "--supabase-url",
        "https://xxx.supabase.co",
        "--supabase-key",
        "your-service-role-key"
      ],
      "env": {}
    }
  }
}

Open Cursor settings, navigate to the MCP tab, and toggle the server on. Cursor spawns the subprocess lazily on the first tool call, paying a cold-start cost of about 3 seconds. Subsequent calls average 150 to 300 ms for REST queries and 400 to 800 ms for Edge Function invocations.

Example prompts and workflows

Once the server is attached, Supabase acts like another data source the model can reach. A few prompts that work well:

  • "List every table in the public schema and summarize the column types."
  • "Find the top 10 users by created_at in the last 7 days and show their email, signup source, and plan."
  • "Invite the user alice@acme.com and set role metadata to editor."
  • "Download the file exports/daily.csv from the reports bucket and tell me the row count."
  • "Invoke the send-digest Edge Function with user_id=42 and show the response."

The model will chain calls on its own. A typical read-analyze loop runs list_tables to learn the schema, describe_table to see columns, then query to fetch rows. You can watch the sequence in the tool log and interrupt if it goes off track.

One useful pattern: tell the model the exact table name up front. If you say "pull from the orders table," it skips the schema discovery calls and cuts the round trip from 4 tool calls down to 1.

Troubleshooting

Tool call returns 401. The service role key is wrong or has been rotated. Regenerate in Settings > API and restart the MCP server (/mcp restart supabase in Claude Code).

Tool call returns 406 or 42501. The key is valid but the SQL hit an RLS check. Using the service role key should bypass RLS - if it does not, the key is actually an anon key. Double check the dashboard.

Server fails with ENOENT. npx is not on PATH in the env Claude Code or Cursor inherits. On macOS, relaunch the editor from a terminal so it picks up your shell env, or put the absolute path to npx in the command field.

Edge Function times out. The server waits 30 seconds by default. For longer functions, deploy them as background jobs and poll a status row from the database instead of invoking directly.

Storage upload fails with 413. Individual object uploads are capped at 50 MB through the MCP tool. For larger files, use the resumable upload pattern via the Supabase CLI or the JS client directly and ask Claude to verify the upload by listing the bucket.

Alternatives

If the Supabase server does not fit, a few options cover the same ground:

  • postgres-mcp gives raw Postgres access without the auth or storage tools. Useful if you only need SQL.
  • firebase-mcp is the closest sibling for teams on Google Cloud.
  • neon-mcp and planetscale-mcp target those specific Postgres and MySQL providers with better branch and schema-diff tools.

For read-only dashboards, a static SQL script plus the filesystem MCP server is usually faster than spinning up a full Supabase connection. You lose live data but gain reproducibility.

The Supabase MCP server is the right default for any project already on Supabase. Five minutes of setup replaces an afternoon of dashboard clicks. Keep it on a separate key scoped to a dev project in the first week, then graduate to production once you trust the prompt patterns.

Guides

Frequently asked questions

Is it safe to give the MCP server my service role key?

Only on a development project. The service role key bypasses RLS, so any prompt can read or mutate any row. For production use, create a Postgres role with narrow grants, mint a JWT for it, and pass that instead. Never commit the key to a repo.

Does the server support real-time subscriptions?

No. The current server is request-response only. If you need to react to row changes, deploy an Edge Function that calls a webhook, or poll a `status` column from the MCP client on an interval.

Can I point the server at a self-hosted Supabase instance?

Yes. Pass the hostname of your self-hosted Kong gateway as `--supabase-url` and the local service role key as `--supabase-key`. The server does not assume a specific hostname.

Which SQL features work through the query tool?

Anything Postgres supports - CTEs, window functions, JSON operators, and extension functions if enabled. The server runs a single statement per call, so wrap multi-statement logic in a stored procedure and invoke the procedure.

How do I limit which tables the agent can touch?

Create a dedicated Postgres role, grant SELECT and INSERT on only the tables you want, and generate a JWT that claims that role. Pass the JWT as `--supabase-key`. The server will get a permission error on any table outside the grant.

What happens if the service role key is rotated while the MCP server is running?

The subprocess keeps the old key in memory and tool calls start failing with 401. Restart the server with `/mcp restart supabase` in Claude Code or toggle it off and on in Cursor to pick up the new key.