MCP do Supabase: como limitar o que o agente pode fazer no seu banco

O MCP do Supabase é um servidor remoto em https://mcp.supabase.com/mcp, e a segurança dele é configurada por parâmetros na própria URL. Sem opt-in, o read_only vale false: o cliente MCP pode executar SQL destrutivo, tipo DROP TABLE e DELETE FROM. Para limitar, você trava o projeto com project_ref, liga read_only=true (que roda tudo como usuário Postgres de leitura e desabilita as ferramentas de escrita) e recorta os grupos em features. O próprio Supabase recomenda apontar o MCP para um projeto de desenvolvimento, com dados não produtivos ou ofuscados, nunca para produção
Fala aí, beleza? O servidor MCP do Supabase aceita escrita por padrão
O parâmetro read_only tem valor padrão false, então, sem opt-in explícito, o cliente MCP pode executar SQL destrutivo no seu banco: DROP TABLE, DELETE FROM, o pacote completo
Isso não é boato de thread de Twitter, está aberto como issue de segurança no repositório do projeto, com o título Default-unsafe configuration allows destructive operations without opt-in
Este post NÃO é sobre instalar
É sobre recortar o que o agente alcança antes de você clicar em aprovar a conexão
O que você precisa ter em mãos antes:
Antes de montar a URL, junta essas quatro coisas
- O Project ID do projeto: ele aparece nas configurações do projeto e é exatamente o valor que vai no parâmetro
project_ref - A decisão de QUAL projeto conectar: a documentação oficial do Supabase orienta usar o servidor MCP com um projeto de desenvolvimento, e garantir que esse ambiente tenha dados não produtivos ou ofuscados
- A noção do que é a
service_role: as chaves de serviço contornam o Row Level Security por design, e a documentação diz que elas nunca devem ser usadas no navegador nem expostas a clientes - O cliente MCP que vai consumir isso: pode ser o Claude Code via transporte HTTP, ou o servidor local servido pelo Supabase CLI, que fica em
http://localhost:54321/mcppara desenvolvimento
Repara que a configuração de segurança aqui não mora num painel de permissões
Ela mora em parâmetros de query na URL do servidor, e isso é ótimo: dá pra ler a linha inteira e saber o que o agente pode fazer 🙂
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Como limitar o MCP do Supabase passo a passo:
A ordem importa, porque cada parâmetro fecha uma porta diferente
- Trave o escopo com
project_ref
Sem isso, o servidor enxerga sua conta inteira
Com o project_ref, ele fica restrito a um único projeto, e as ferramentas de nível de conta somem: list_projects e list_organizations deixam de ficar disponíveis
https://mcp.supabase.com/mcp?project_ref=abc123
O erro comum deste passo: procurar um campo chamado "project ref" no painel e não achar
Ele aparece como Project ID nas configurações do projeto
- Ligue o
read_only=true
Esse é o parâmetro que muda o jogo de verdade
Com ele ligado, o servidor entra em modo somente leitura e executa todas as queries como um usuário Postgres de leitura
Na prática, o execute_sql passa a rodar como esse usuário read-only, e insert, update e delete ficam bloqueados
Junto disso, as ferramentas que alteram estado ficam desabilitadas: apply_migration, create_project, pause_project, restore_project, deploy_edge_function, create_branch, delete_branch, merge_branch, reset_branch, rebase_branch e update_storage_config
O erro comum deste passo (e é o mais recorrente de todos): assumir que o modo somente leitura é o padrão
Não é
Se o parâmetro não está na URL, o servidor aceita escrita
- Escolha os grupos em
features
O parâmetro features define quais grupos de ferramentas ficam ativos
Os grupos são: account, database, docs (a base de conhecimento), debugging, development, functions (edge functions), branching (plano pago) e storage
Todos vêm habilitados por padrão, exceto storage
Ou seja: se você não declarar nada, tu leva quase tudo junto
Declarar features é o jeito de dizer "só isso aqui, obrigado"
- Junte tudo numa URL só
Os parâmetros são combináveis, então a configuração final é uma linha
https://mcp.supabase.com/mcp?project_ref=abc123&read_only=true&features=database,docs,debugging
Lê essa URL em voz alta antes de aprovar: um projeto, somente leitura, três grupos
O erro comum deste passo: copiar a URL de exemplo de um tutorial e esquecer de trocar o project_ref pelo seu
- Registre no Claude Code
A documentação do Supabase traz o comando de instalação via transporte HTTP
claude mcp add --scope project --transport http supabase "https://mcp.supabase.com/mcp?features=docs,account,database,debugging,development,functions,branching"
Esse comando é o da doc, com os grupos abertos
Se a ideia é restringir, a URL que vai entre aspas é a SUA, aquela do passo 4, com project_ref e read_only dentro
A alternativa equivalente é declarar o servidor no arquivo .mcp.json, usando "type": "http" e a mesma URL
- Autentique pelo navegador
O servidor hospedado usa dynamic client registration com OAuth 2.1, ou seja, login pelo navegador
Não é token pessoal colado dentro de arquivo
O Personal Access Token segue existindo como alternativa manual, mas para dois casos específicos: ambientes de CI, onde o fluxo de navegador não rola, e clientes MCP que não suportam registro dinâmico
O que esses limites não resolvem:
Agora a parte que a maioria dos tutoriais pula
Configurar bem os parâmetros reduz o estrago possível, mas não fecha a categoria de risco inteira
O sintoma:
Dado privado sai do banco sem ninguém ter pedido
Ninguém digitou "me mostra a tabela de tokens"
O agente fez isso sozinho, obedecendo instrução que ele leu em algum lugar
A causa:
Em julho de 2025, pesquisadores da General Analysis demonstraram publicamente o cenário
Um ticket de suporte contendo instruções escondidas leva o agente a fazer SELECT numa tabela privada (integration_tokens) e devolver o conteúdo dentro do próprio ticket
O detalhe que faz a coisa funcionar: o agente operava com service_role, que por design ignora o RLS
Isso é prompt injection, e é um problema de quem lê o conteúdo, não de quem configurou a URL
Quanto mais autonomia você dá, mais superfície aparece, e isso vale pra qualquer setup de deixar o agente rodando tarefas sozinho, não só pra banco
E o que o Supabase diz sobre isso?
A posição pública deles é clara em dois pontos: o MCP não faz bypass de proteções de banco como Row Level Security, que seguem aplicadas, e não há incidente reportado de cliente Supabase com vazamento de dados via MCP
As camadas que eles citam são modo somente leitura, escopo por projeto, grupos de features e encapsulamento dos resultados de query
E aqui está a parte honesta: o próprio Supabase afirma que essas medidas reduzem o risco mas não eliminam, e que "guardrails sozinhos não bastam"
Prompt injection segue como preocupação número um mesmo em modo somente leitura
Como prevenir:
- Não usar
service_roleno agente, já que ela ignora o RLS por design - Apontar o MCP para projeto de desenvolvimento, com dados não produtivos ou ofuscados
- Manter escrita fora do escopo com
read_only=true, pra que uma instrução injetada no máximo leia, nunca altere
Tome cuidado com o raciocínio de que "é só leitura, então tá tranquilo"
Leitura é exatamente o vetor da demonstração acima
Qual configuração usar em cada cenário?
Cada contexto pede um recorte diferente, se liga
| Cenário | Servidor | Configuração |
|---|---|---|
| Explorar schema e documentação num projeto de dev | https://mcp.supabase.com/mcp |
project_ref fixo, read_only=true, features enxuto (ex: database,docs,debugging) |
| Desenvolvimento local com o Supabase CLI | http://localhost:54321/mcp |
Servidor local, sem depender do projeto hospedado |
| CI ou cliente MCP sem registro dinâmico | https://mcp.supabase.com/mcp |
PAT como alternativa manual, já que o fluxo de navegador não é possível |
| Produção | Nenhum | A documentação orienta usar o MCP com projeto de desenvolvimento, não com produção |
O primeiro cenário é o que mais aparece no dia a dia: você quer que o modelo entenda o schema e consulte a base de conhecimento, e ponto
Para isso, escrita não serve pra nada, então read_only=true não te custa NADA em capacidade útil
O segundo é o caso do desenvolvimento local: o servidor MCP fica em http://localhost:54321/mcp, servido pelo próprio Supabase CLI, sem depender do projeto hospedado
O terceiro é a exceção que a doc reconhece, não a regra
E o quarto tem resposta pronta: produção é o cenário que a documentação orienta evitar
Se você já convive com agentes que agem nas pull requests, o raciocínio é o mesmo aqui: definir o alcance antes é mais barato que auditar depois
Conclusão
Em 03/02/2026 o servidor MCP do Supabase entrou na lista de connectors oficiais do Claude, o que permite executar SQL, alterar schema, fazer deploy de edge functions e gerenciar branches dentro da conversa
É mto massa em termos de conveniência
E é justamente por isso que revisar o escopo virou urgente: quanto mais fácil conectar, mais gente conecta sem olhar a URL
Próximo passo concreto, leva uns dois minutos: abre a URL do seu servidor MCP, confere se project_ref e read_only estão lá, e recorta features pro mínimo que o seu uso exige
Se a URL estiver limpa demais, ela provavelmente está permissiva demais 😀
até o próximo post!
Perguntas frequentes
O MCP do Supabase é seguro para conectar num projeto de produção?
A recomendação oficial do Supabase é não fazer isso. A documentação orienta usar o servidor MCP com um projeto de desenvolvimento, garantindo que esse ambiente tenha dados não produtivos ou ofuscados.
Como faço para o agente só ler meu banco, sem poder escrever nada?
Adiciona read_only=true na URL do servidor MCP do Supabase. Com isso, o execute_sql passa a rodar como um usuário Postgres somente leitura, e insert, update e delete ficam bloqueados.
O que muda quando eu coloco o project_ref na URL do MCP?
O servidor deixa de enxergar sua conta inteira e fica restrito a um único projeto. As ferramentas de nível de conta, como list_projects e list_organizations, deixam de ficar disponíveis.
O MCP do Supabase consegue burlar o RLS (Row Level Security)?
A posição pública do Supabase é que o MCP não faz bypass do RLS, que segue aplicado normalmente. O ponto de atenção é outro: a chave service_role ignora o RLS por design, e é ela que aparece no caso de vazamento demonstrado pela General Analysis.
Preciso gerar um token pessoal (PAT) para autenticar o MCP do Supabase?
Não como regra. O servidor hospedado usa dynamic client registration com OAuth 2.1, ou seja, login pelo navegador. O Personal Access Token continua existindo como alternativa manual, mas só para ambientes de CI ou clientes MCP sem suporte a registro dinâmico.
Quais ferramentas ficam desabilitadas no modo read_only do MCP do Supabase?
Ficam fora do ar as ferramentas que alteram estado: apply_migration, create_project, pause_project, restore_project, deploy_edge_function, create_branch, delete_branch, merge_branch, reset_branch, rebase_branch e update_storage_config. O execute_sql continua ativo, mas rodando como usuário Postgres de leitura.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
Supabase MCP no Claude Code: como conectar o agente ao schema do seu banco
Supabase MCP no Claude Code conecta o agente ao schema real do seu banco: veja como instalar, autenticar via OAuth e por que usar só em desenvolvimento.
O que são servidores MCP no Claude Code e quando eles valem a pena?
Servidores MCP no Claude Code conectam o agente a bancos, docs e ferramentas externas. Entenda como funcionam e quando realmente valem a pena usar.
Context7 MCP no Claude Code: como parar de receber código de uma versão antiga da biblioteca
Context7 MCP no Claude Code busca a documentação atual da biblioteca e evita código desatualizado. Veja como instalar, os comandos e os planos Free e Pro.
