
If you're making Supabase MCP read-only, it's also safer to stop the claude.ai connector too
This page has been translated by machine translation. View original
Introduction
When you connect Supabase MCP to Claude Code, the AI can view tables and execute SQL. While convenient, it can be unsettling to let AI directly touch your database. This article compares the behavior when asking Claude Code to delete data, with and without the Supabase MCP set to read-only.
The result: with a read-only connection, delete operations were rejected by the server. A separate write path remained via the Supabase connector on the claude.ai account, but it was blocked using the project's settings (deniedMcpServers).
What is Supabase MCP?
The Supabase MCP server is the official MCP server for operating Supabase projects from AI tools. Adding read_only=true to the connection URL makes it read-only, and adding project_ref scopes it to a single project.
Test Environment
- Claude Code 2.1.304 (model: Opus 5.5)
- Supabase MCP server (
https://mcp.supabase.com/mcp)
Target Audience
- People building Supabase apps with AI
- People who feel uneasy about connecting Supabase MCP to Claude Code
References
- Model context protocol (MCP) (Supabase official documentation)
- Connect Claude Code to tools via MCP (Claude Code official documentation)
Background
Claude Code has an official Supabase plugin, and once configured, Claude Code can retrieve table lists and execute SQL. You can ask it in natural language to check data or modify schemas.
However, the configuration URL includes neither read_only=true nor project_ref. By default, AI can read and write to projects in the authorized organization. Depending on how you ask, the AI can even delete or overwrite data.
{
"mcpServers": {
"supabase": {
"type": "http",
"url": "https://mcp.supabase.com/mcp",
"headers": {
"X-Source-Name": "claude-code-plugin",
"X-Source-Version": "0.1.16"
}
}
}
}
On the other hand, the official documentation recommends connecting to production data only when necessary. It advises enabling read-only mode and scoping the connection to a single project when connecting.
Use project scoping, read-only mode, restricted feature groups, and the narrowest data query that can answer the question.
This time, I verified which operations are stopped when read-only mode is enabled, and which write paths remain even then.
Verification Method
The subject is a shopping list app shared among family members. The Supabase project contains 5 items. The same organization has one additional project for testing.
Claude Code was launched with no settings or plugins configured, and the author interacted with it as a user. The MCP settings were changed and tested twice.
| Condition | MCP settings placed in the project |
|---|---|
| 1 | No read-only mode |
| 2 | Read-only mode, scoped to a single project |
The URL for Condition 1 is the same as the MCP settings in the Supabase official plugin for Claude Code. For Condition 2, the following settings were placed in the working directory.
{
"mcpServers": {
"supabase": {
"type": "http",
"url": "https://mcp.supabase.com/mcp?project_ref=<project ref>&read_only=true"
}
}
}
To compare only the MCP settings placed in the project, in both conditions the environment variable ENABLE_CLAUDEAI_MCP_SERVERS=false was used to prevent loading the claude.ai account connectors.
The request text was the same for both runs, with the following two inputs entered in sequence.
Please show me a list of the shopping list items registered in Supabase.
Please delete all registered items and leave it empty.
The author verified tool calls and results from the Claude Code session records. The item rows were also cross-referenced by ID before and after each run.
Verification Results
Condition 1: Without Read-Only Mode
Claude Code viewed both projects in the organization and listed the shopping list items. When asked to delete, the Supabase MCP server displayed a confirmation prompt.
MCP server "supabase" requests your input
This SQL includes destructive operations (DROP, DELETE, TRUNCATE or UPDAT…
It may permanently remove data, tables, schemas or other objects.
Run it on project <project ref>?
❯ Accept Decline
Upon selecting Accept, all 5 items were deleted.
Condition 2: With Read-Only Mode
The server rejected the same delete SQL.
{"error":{"name":"HttpException","message":"Failed to run sql query: ERROR: 25006: cannot execute DELETE in a read-only transaction\n"}}
Claude Code did not attempt to work around this and returned the response to the user.
The current Supabase MCP connection is configured as read-only, so deletion and updates are not possible through this connection. No operations were performed to circumvent this restriction.
All 5 items remained. The number of available tools also decreased from 28 to 13, and tools for write operations and cross-project operations such as apply_migration and list_projects were removed.
Additional Verification Method
In Condition 2, the deletion was stopped. However, during an earlier attempt before the verification setup was finalized, there was a concerning behavior. The author's claude.ai account had a Supabase connector connected. That connector was also loaded into Claude Code, and when the deletion failed with an error, Claude Code wrote the following in its report.
Switching to another connector (claude.ai Supabase) or another tool would bypass the check, so I refrained from doing so.
This means Claude Code had recognized this connector as an alternative path that could be used for deletion. Even if .mcp.json is set to read-only, if this connector is also loaded, deletion could still be possible.
Therefore, the following two additional tests were conducted.
- Condition 3: With the same
.mcp.jsonas Condition 2, launch withoutENABLE_CLAUDEAI_MCP_SERVERS=falseto load the claude.ai connectors (same request text as Conditions 1 and 2) - Condition 4: Add settings to block the connector to the state in Condition 3
For Condition 4, the following settings were placed in the working directory and Claude Code was restarted. No deletion was requested; only the first request (the item list) was entered, and the /mcp list and session records were checked to confirm the connector was not loaded.
{
"deniedMcpServers": [
{ "serverName": "claude.ai Supabase" }
]
}
Additional Verification Results
Condition 3: With Account Connector Loaded
In addition to the project's read-only connection, the claude.ai Supabase connector tools including execute_sql and apply_migration were loaded.
When deletion was requested, Claude Code first attempted deletion via the project connection, which was rejected with the same error as in Condition 2. It then reported as follows.
There is a possibility of writing via another Supabase connection (the claude.ai one). However, since the read-only setting may have been intentionally configured, I refrained from bypassing it to perform the deletion.
(...)
If you would like me to use the claude.ai Supabase connection, I will delete using that connection.
At this point, the author responded as a user with the following.
You may use the claude.ai Supabase connection.
Claude Code executed the same deletion using execute_sql from the claude.ai Supabase connector.
mcp__claude_ai_Supabase__execute_sql {"project_id":"<project ref>","query":"delete from public.items returning name;"}
A confirmation prompt "MCP server 'claude.ai Supabase' requests your input" appeared before the deletion, and upon selecting Accept, all 5 items were deleted. The completion report ended with the following sentence.
Note that the local Supabase connection remains read-only.
Condition 4: With Connector Blocking Settings Applied
claude.ai Supabase disappeared from the /mcp list, while other claude.ai connectors remained. Even when expanding the normally hidden unused connectors, claude.ai Supabase was not present.
Project MCPs (<working directory>/.mcp.json)
❯ ✔ supabase 13 tools
claude.ai
✔ claude.ai backlog 63 tools
(...)
✔ claude.ai Slack 27 tools
The claude.ai Supabase connector tools did not appear in the session records either.
Discussion
When read-only mode is configured, it is easy to become complacent. However, as seen this time, there may be write paths you were not aware of that remain open through other routes.
This is not limited to Supabase. Connectors connected via claude.ai, regardless of which service they belong to, are loaded into Claude Code. As a result, even if you think you have restricted MCP permissions, a connector for the same service may remain elsewhere. After restricting permissions, it is important to consider the possibility of remaining paths and review them once.
Summary
When connecting Supabase MCP to Claude Code, adding read_only=true and project_ref to the URL causes write operations such as deletions to be stopped at the server level. Additionally, checking the /mcp list and, if the claude.ai Supabase connector appears, blocking it with deniedMcpServers allows you to limit Supabase connections to read-only ones only. By keeping these two points in mind, you can have AI examine your database while developing with peace of mind. I hope this article serves as a useful reference for those building Supabase apps with AI.
