Skip to main content
Jason Finance
AI Startup

Claude Code Supabase MCP: Lock It to One Project, Read-Only, with a Project-Scoped .mcp.json, Then Log In with OAuth

Connect Claude Code to Supabase MCP: write it to .mcp.json with --scope project, add project_ref and read_only to the URL, then finish OAuth with /mcp.

On this page
  1. 1.Choose a scope first: local, project or user
  2. 2.Adding Supabase MCP: the official command plus project_ref and read_only
  3. 2.1Three URL parameters
  4. 3.First run: approving the project-scoped server
  5. 4.Logging in to Supabase with OAuth
  6. 4.1Logging in on a remote host over SSH
  7. 5.Check which project it is connected to: always do this before writing data
  8. 5.1Two Supabase entries in /mcp
  9. 6.Security settings: Supabase’s official warnings
  10. 7.Removing it or logging in again
  11. FAQ

Once Supabase MCP is connected in Claude Code, Claude can query tables, read logs and apply migrations directly. That is convenient and also dangerous: an MCP with no scope limits can see every organization and project under your account. I run Claude Code over SSH on a VM in Oracle Cloud, and my approach is to set Supabase MCP to project scope (written in the project’s .mcp.json), lock the URL to a single project, read-only, and then log in with OAuth.

The short answer: use claude mcp add --scope project --transport http to add Supabase’s official URL https://mcp.supabase.com/mcp, and append project_ref and read_only=true to the URL yourself; then finish OAuth with /mcp or claude mcp login supabase. After logging in, and before writing any data, check which project it is connected to.

This post is based on the official Claude Code and Supabase docs as I read them on 15 October 2026. Commands and parameters may change between versions, so check the official docs before you use them.

Choose a scope first: local, project or user

Claude Code MCP settings come in three scopes (official Claude Code docs):

Scope Where it applies Shared with others? Where it is stored
local (default) Current project only No This project’s settings in ~/.claude.json
project Current project only Yes, through version control .mcp.json in the project root
user All your projects No ~/.claude.json

I chose project scope for two reasons:

  1. The settings are visible and easy to edit: .mcp.json is a file in the project, so you can open it and see right away whether the URL has project_ref and read_only.
  2. It applies only to this project: switch to another project folder and this Supabase connection does not appear.

When a server with the same name appears in more than one scope, the order of precedence is local, project, user, and only then plugins and claude.ai connectors. Claude Code uses the whole entry from the scope that wins; it does not merge fields.

Adding Supabase MCP: the official command plus project_ref and read_only

The command Supabase’s official docs give for Claude Code is (official Supabase docs):

claude mcp add --scope project --transport http supabase "https://mcp.supabase.com/mcp"

This command does not lock the project. I add two parameters to the end of the URL:

claude mcp add --scope project --transport http supabase \
  "https://mcp.supabase.com/mcp?project_ref=<project-ref>&read_only=true"

After running it, .mcp.json in the project root looks like this:

{
  "mcpServers": {
    "supabase": {
      "type": "http",
      "url": "https://mcp.supabase.com/mcp?project_ref=<project-ref>&read_only=true"
    }
  }
}

<project-ref> is the Supabase project’s Project ID, which you can find on the project’s settings page.

Three URL parameters

Parameter What it does
project_ref=<project-ref> Only this one project can be used; account-level tools such as listing projects and creating projects are turned off
read_only=true Queries run as a read-only Postgres user
features=<tool-groups> Only the listed tool groups are enabled, separated by commas, for example features=database,docs

The tool groups are Database (querying tables, running SQL, applying migrations), Debugging (logs, security advisories), Development (project URL, public keys, generating TypeScript types), Edge Functions, Docs, Branching, and Storage, which is off by default (Supabase tool list).

My approach is to use read_only=true day to day. The one time I really need to apply a migration, I handle it separately, and I try it first on a development branch or a test project.

First run: approving the project-scoped server

Someone else may have put .mcp.json into the repo, so in interactive mode Claude Code asks whether you approve a project-scoped server before using it for the first time. Until you approve it, claude mcp list shows Pending approval.

  • Your approval or rejection is recorded in the project’s .claude/settings.local.json.
  • To choose again: claude mcp reset-project-choices.
  • An exception to watch for: when running with claude -p, the Agent SDK or a cloud session, it does not ask, and project-scoped servers load directly. If you don’t want it to load in those cases, exclude it separately with a setting such as disabledMcpjsonServers (Claude Code settings reference).

Logging in to Supabase with OAuth

Supabase’s hosted MCP supports OAuth, so you don’t need to create an access token yourself.

In Claude Code: run /mcp, choose supabase, then choose Authenticate. Your browser opens Supabase’s authorization page; after logging in, choose an organization. The Supabase docs recommend doing this in a regular terminal, not in an IDE extension.

In the shell:

claude mcp login supabase

Once you are logged in, claude mcp list shows Connected; when a login is needed it shows Needs authentication. The official docs say tokens are stored securely and refreshed automatically.

Logging in on a remote host over SSH

My Claude Code runs on a VM in Oracle Cloud. I connect to it from my Mac over SSH, and the host has no browser. The approach in the official docs (official Claude Code docs):

  1. Connect with ssh -t and run claude mcp login supabase. When it cannot detect a browser, it prints the authorization URL; to force this flow, add --no-browser.
  2. Paste the URL into the browser on your Mac, log in to Supabase and choose an organization.
  3. After authorization, the browser jumps to http://localhost:<port>/callback. That is the VM’s localhost, so it will not open on the Mac. That’s fine: copy the full callback URL from the browser’s address bar and paste it back where Claude Code is waiting for input.

The port is random each time by default; to fix it, use --callback-port when adding the server.

If you can’t copy the authorization URL in the terminal, and the screen says Sent via OSC 52 but nothing reaches the clipboard, that is a separate problem. I covered the fix in Can’t Copy the Claude Code OAuth URL?, which also covers handling the callback with SSH port forwarding.

Check which project it is connected to: always do this before writing data

At login you choose an organization; the project_ref in the URL is what decides the project. I do two checks:

  1. Look at the settings: claude mcp get supabase shows the configured URL and scope. Confirm that project_ref is the project you want and that read_only=true is still there.
  2. Ask the MCP itself: ask Claude to call the Supabase MCP get_project_url tool. It returns the project’s API URL, which contains the project ref, so you can compare it with the one you expect.

This is my own checking habit; the official docs do not require it. But when two projects have very similar tables, getting the target wrong is costly.

Two Supabase entries in /mcp

If you have added the Supabase connector to your claude.ai account, you may see both supabase and claude.ai Supabase in /mcp. The official docs say claude.ai connectors are brought into Claude Code automatically, and their authorization is handled on the claude.ai side (official Claude Code docs).

How they differ:

Project-scoped supabase claude.ai Supabase
Where it is configured The project’s .mcp.json Connector settings in your claude.ai account
Can it be locked to one project, read-only? Yes, and the URL parameters are visible Depends on what you authorized on claude.ai; the settings are not visible in the project
Where you authorize it OAuth login on this host The claude.ai website

In my environment, claude.ai Supabase may connect to a different organization, not necessarily the project I want to work on. So when I work on the database inside a project, I use only the project-scoped one. If you don’t need the claude.ai connector, you can turn it off in /mcp, or add "disableClaudeAiConnectors": true to your settings file (Claude Code settings reference).

Security settings: Supabase’s official warnings

The Supabase docs specifically warn about prompt injection: text in a table (a customer support message, for example) may carry instructions that lead the AI to do something you didn’t ask for. Query results do come wrapped with protective instructions, but the docs also state that this is “not foolproof” (official Supabase docs). Supabase recommends:

  • In interactive use, keep manual approval for each tool call.
  • Connect to a production project only when the task really needs production data.
  • Use read-only mode, lock it to a single project, and enable only the tool groups you need.
  • Try database schema changes on a development branch first.
  • Do not give this MCP to end users: it runs with your developer account’s permissions.

Removing it or logging in again

What you want to do How
Log in again /mcp → choose the server → Clear authentication → Authenticate; or claude mcp logout supabase then claude mcp login supabase
Token expired and rejected /mcp prompts you to Re-authenticate
Disable it temporarily Turn the server off in /mcp
Remove it completely claude mcp remove supabase --scope project, which also deletes the OAuth tokens and client registration it stored

For how to install Claude Code on an Oracle Cloud VM and keep it running, see Running Claude Code Remote Control on a Free Oracle Cloud Server.

FAQ

Which command connects Claude Code to Supabase MCP?

The command in Supabase's official docs is claude mcp add --scope project --transport http supabase "https://mcp.supabase.com/mcp". It writes .mcp.json to the project root. The official command does not include project_ref; to lock it to a single project and make it read-only, add ?project_ref=your-project-ref&read_only=true to the end of the URL yourself.

What is the difference between the local, project and user MCP scopes?

According to the official Claude Code docs: local is the default, applies only to the current project, is for you alone and is stored in ~/.claude.json; project is written to .mcp.json in the project root and can go into version control and be shared with your team; user applies to all your projects and is also stored in ~/.claude.json. When a server with the same name appears in more than one scope, local takes precedence, then project, then user, and only after those come plugins and claude.ai connectors.

How do I log in to Supabase MCP with OAuth on a host I reach over SSH?

In Claude Code, run /mcp, choose supabase and then Authenticate, or run claude mcp login supabase in the shell. In an environment without a browser it prints the authorization URL. Open it in a browser on your own computer, log in to Supabase, then paste the full callback URL from the browser's address bar back into Claude Code. Pasting interactively requires connecting with ssh -t.

How do I check which project Supabase MCP is connected to?

First look at the URL in .mcp.json or in the output of claude mcp get supabase; the project_ref parameter is the project ref. You can also ask Claude to call the Supabase MCP get_project_url tool, which returns the project's API URL, and the URL contains the project ref. Do this check before running anything that writes data.

Both supabase and claude.ai Supabase appear in /mcp. Which one should I use?

claude.ai Supabase is the connector you added to your claude.ai account. Claude Code brings it in automatically, its authorization and settings live on the claude.ai side, and which organization it reaches depends on what you authorized on claude.ai at the time. The project-scoped supabase is the configuration written in .mcp.json; its URL parameters are visible and it can be locked to a single project. To work on the database inside a project, I use the project-scoped supabase.

How do I remove Supabase MCP or log in again?

To log in again: in /mcp, choose the server, clear it with Clear authentication, then Authenticate; or run claude mcp logout supabase and then claude mcp login supabase in the shell. To remove it completely: claude mcp remove supabase --scope project. The official docs say this also deletes the OAuth tokens and client registration it stored.

Related articles

About the author

Photo of Jason

Jason

Account Manager in Google Large Customer Sales and Columbia MBA admit, sharing the money tools and experience he actually uses.

Comments

Sign in with Google to comment. Your comment will not show your Google profile picture or name; it appears under a randomly generated nickname to protect your privacy.

By signing in you agree to this site's privacy policy.

  1. Loading comments…