Servidor MCP
O @rebasepro/mcp é um servidor Model Context Protocol
que fornece a um assistente de IA ferramentas reais sobre um projeto Rebase: ler e
gravar linhas, gerenciar usuários, executar migrações, invocar funções, controlar o servidor
de desenvolvimento.
Ele se comunica via MCP apenas por stdio. Não há porta e nenhum listener — o processo é exatamente tão confiável quanto aquilo que o iniciou, e não há chamador remoto para autenticar. Essa é a parte segura. As perguntas interessantes dizem respeito ao que ele faz depois de estar em execução, e esta página as responde antes de mostrar o bloco de configuração.
Um backend implantado também pode servir o próprio MCP, via HTTP, para as pessoas que usam sua aplicação. Isso é algo diferente com um modelo de credenciais distinto: consulte O endpoint remoto.
Conectando um cliente
Seção intitulada “Conectando um cliente”O servidor é executado a partir do seu projeto: @rebasepro/mcp é uma devDependency que todo
scaffold do rebase init fixa junto com a CLI, e cada bloco abaixo — a integração
completa — inicia essa cópia (pnpm exec rebase-mcp, ou npx --no rebase-mcp
em um projeto npm), nunca uma mais recente do npm. Um projeto mais antigo a adiciona uma vez,
com rebase skills install --mcp ou pnpm add -D @rebasepro/mcp.
O rebase init grava o bloco para cada agente escolhido quando ele
configura seus agentes de codificação por IA, mantendo
quaisquer outros servidores já presentes no arquivo. O comando rebase init --agent cursor,codex faz
o mesmo sem perguntar.
Claude Code — .mcp.json na raiz do seu projeto. O rebase init grava este
arquivo para você:
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "." } } }}Cursor — o mesmo formato, em .cursor/mcp.json. O Cursor expande
${workspaceFolder} para a raiz do projeto:
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "${workspaceFolder}" } } }}Gemini CLI — .gemini/settings.json, sob a mesma chave:
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "." } } }}Codex CLI — TOML em vez de JSON, no .codex/config.toml do projeto.
O Codex lê a configuração do projeto somente após você confiar no projeto:
[mcp_servers.rebase]command = "pnpm"args = ["exec", "rebase-mcp"]
[mcp_servers.rebase.env]REBASE_PROJECT_DIR = "."Kiro — .kiro/settings/mcp.json:
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "." } } }}GitHub Copilot no VS Code — .vscode/mcp.json, sob servers e com
um transporte explícito:
{ "servers": { "rebase": { "type": "stdio", "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "${workspaceFolder}" } } }}O Windsurf lê os servidores MCP apenas da sua configuração no nível do usuário, portanto não há
arquivo de projeto para gravar. Adicione o servidor nas configurações de MCP dele como "command": "pnpm",
"args": ["--dir", "/absolute/path/to/your/project", "exec", "rebase-mcp"], com esse caminho como REBASE_PROJECT_DIR.
Qualquer cliente MCP capaz de iniciar um servidor stdio funciona; o formato é o mesmo.
Em qual diretório ele atua
Seção intitulada “Em qual diretório ele atua”REBASE_PROJECT_DIR é o diretório que contém rebase.json. Existe uma
precedência, e ela é a mesma em todos os clientes:
- O bloco de ambiente —
REBASE_PROJECT_DIR,REBASE_BASE_URL,REBASE_API_TOKEN. Se algum deles estiver definido, o projetodefaulté reconstruído a partir deles a cada inicialização. - O diretório de trabalho do servidor, quando contém um
rebase.json. Um projeto em que você está situado tem precedência sobre qualquer item lembrado em~/.rebase/projects.json. - O
defaultpersistido em~/.rebase/projects.json, quando nenhum dos dois primeiros define nada.
A descoberta automática a partir de .rebase/state.json preenche lacunas em todos os três casos e nunca
substitui um valor fornecido por um deles.
Os blocos no nível do projeto apontam o projeto — ".", o diretório de trabalho do cliente
ou o ${workspaceFolder} do editor — porque a regra 3 lê um arquivo compartilhado
por todos os projetos na máquina. Uma configuração no nível do usuário, como a do Windsurf,
informa um caminho absoluto.
O que o servidor pode alcançar
Seção intitulada “O que o servidor pode alcançar”Esta é a seção a ser lida antes de apontar um assistente para um banco de dados importante para você.
O servidor carrega uma credencial de ambiente para todo o processo. Não há identidade por ferramenta nem modo somente leitura; todas as ferramentas usam o mesmo token, e a única chave no pacote serve para ampliar o alcance em vez de reduzi-lo.
Qual credencial é usada, em ordem de prioridade:
REBASE_API_TOKEN/REBASE_TOKENdo ambienteREBASE_SERVICE_KEYlida do.envdo projeto- A chave de serviço descoberta automaticamente de
.rebase/state.jsonenquantorebase devestá em execução
Um token que você registra para um projeto tem precedência sobre a descoberta automática. A descoberta apenas preenche uma lacuna.
Fornecendo uma credencial restrita em vez disso
Seção intitulada “Fornecendo uma credencial restrita em vez disso”Registre uma API key com escopo e o modelo de duas etapas
se aplicará de fato. Uma chave de serviço é executada com as roles ["service"], as quais
as políticas de administrador injetadas não contemplam — portanto, o RLS não concede nada a ela a menos que uma
das suas próprias políticas declare o contrário, e os escopos dela a restringem ainda mais:
rebase api-keys create -n "claude-code" \ --scopes data:read:articles \ --expires-in 30Em seguida, passe a chave rk_live_… resultante para o servidor em vez de deixá-lo
descobrir uma service key:
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "/absolute/path/to/your/project", "REBASE_API_TOKEN": "rk_live_..." } } }}Duas coisas que isso não faz, ambas importantes antes de você confiar nisso:
- Não restringe as ferramentas de CLI.
rebase_db_push,rebase_db_migrate,rebase_doctore as ferramentas de branch executam a CLI do Rebase, que se conecta comDATABASE_URLe nunca enxerga seu token. O gate de loopback abaixo é a única proteção diante delas. - Uma chave só alcança uma ferramenta de administração com o escopo dessa ferramenta.
list_userselist_rolesprecisam deusers:read;create_user,update_user,delete_usererebase_auth_reset_passwordprecisam deusers:write; as ferramentas de storage e de cron precisam do escopostorage:*oucron:*correspondente;invoke_functionprecisa defunctions:invoke. Sem ele, a chamada responde403 SCOPE_MISSING. Mesmo comusers:write, uma chave não pode alterar a conta de um administrador: um administrador temkeys:readekeys:write, que nenhuma chave pode ter, e ninguém pode gerenciar uma conta que tenha mais do que ele próprio.
Uma chave criada com --roles admin é diferente: ela carrega as roles
["service", "admin"], o que atende às mesmas políticas padrão de admin que a service
key atende. Dê a ela também --full-access e seu alcance passa a ser o da service key,
exceto o gerenciamento de chaves. A diferença é que ela é revogável, expirável e possui
rate limit por chave, nada do qual é verdadeiro para a service key — rotacioná-la
exige editar o .env e reiniciar o servidor.
Consulte Agentes e Servidores MCP para obter as orientações completas sobre escopo de chaves.
Colocando uma coleção totalmente fora de alcance
Seção intitulada “Colocando uma coleção totalmente fora de alcance”A razão pela qual uma credencial de admin lê tudo é a política básica que o Rebase
injeta em cada coleção, concedendo acesso ao contexto confiável do servidor e à
role admin. Uma coleção pode desativar essa base e assumir a
responsabilidade total pelo seu próprio RLS:
import { defineCollection } from "@rebasepro/cms-types";
export const medicalRecordsCollection = defineCollection({ slug: "medical_records", name: "Medical records", table: "medical_records", properties: { patient_id: { name: "Patient", type: "string" }, notes: { name: "Notes", type: "string" } }, // Remove the injected admin/server baseline — nothing is readable // except what the rules below allow. disableDefaultPolicies: true, securityRules: [ { operations: ["select", "update"], ownerField: "patient_id" } ]});Agora, a única forma de acesso é correspondendo ao patient_id. O uid da service key é a
string literal service, portanto uma regra de proprietário (owner) nunca corresponderá a ele — as leituras retornam zero
linhas e as gravações são rejeitadas pelo Postgres. Esse é o único controle que restringe
a credencial padrão do servidor MCP em vez de ignorar as restrições.
Lembre-se de que essa é uma alteração real de RLS, não documental: ela entra em vigor
apenas depois que rebase schema generate e uma migração tiverem aplicado as políticas. Consulte
Regras de Segurança (RLS).
O gate de loopback
Seção intitulada “O gate de loopback”O comando rebase_project_add aceita qualquer baseUrl, e as ferramentas de CLI se conectam com
qualquer DATABASE_URL que o projeto declarar. A mesma lista de ferramentas que edita um
banco de dados de teste no seu laptop pode, portanto, apagar linhas de produção, sem nada
no caminho além do julgamento do assistente sobre qual projeto está ativo.
Toda ferramenta que modifica o ambiente de destino é recusada, a menos que esse destino esteja na interface de loopback. O gate foi escrito como uma lista do que não é bloqueado, de modo que uma ferramenta adicionada posteriormente já nasce protegida por padrão.
- Não bloqueadas — leituras:
rebase_schema_plan,rebase_doctor,rebase_db_branch_list,rebase_db_branch_info,list_documents,get_document,list_users,list_roles,storage_list_objects,storage_get_download_url,cron_list_jobs,cron_get_job,cron_get_job_logs,rebase_dev_logs. - Não bloqueadas — apenas locais:
rebase_schema_introspect,rebase_schema_generate,rebase_db_generate,rebase_generate_sdk, as ferramentas do servidor de desenvolvimento e as ferramentas de registro de projetos. Elas gravam arquivos locais ou estado local e não têm alvo remoto para verificar. - Bloqueadas com base na
DATABASE_URL: as ferramentas de CLI restantes —rebase_db_push,rebase_db_migrate,rebase_db_branch_create,rebase_db_branch_delete. - Bloqueadas com base na
baseUrldo projeto: as ferramentas de SDK restantes —create_document,update_document,delete_document,create_user,update_user,delete_user,rebase_auth_reset_password,storage_delete_object,cron_trigger_job,cron_toggle_job,invoke_function.
Os dois alvos não são intercambiáveis. As ferramentas de CLI nunca veem a baseUrl, portanto um
backend em localhost associado a uma DATABASE_URL de produção é verificado contra
o banco de dados, não contra o backend.
Uma recusa se parece com isto:
Error: Refusing to run "delete_document": project "default" points athttps://api.example.com/, which is not local. Set REBASE_MCP_ALLOW_REMOTE_WRITES=trueto allow destructive tools against remote environments.Se nenhuma string de conexão puder ser resolvida, as ferramentas de DB protegidas são recusadas.
Sem DATABASE_URL, o CLI usa o banco de dados de desenvolvimento gerenciado, que é
o padrão de um projeto novo, e o gate recusa ali as suas quatro ferramentas de
banco de dados. A recusa diz por quê e indica o que funciona no lugar. Ela
não sugere a opção de desativar a proteção:
Error: Refusing to run "rebase_db_push": project "default" sets no DATABASE_URL, so theCLI would use the managed development database (PGlite, started by `rebase dev`). Youmost likely do not need this tool: the dev server applies the collections to thatdatabase at boot, additively. After changing a collection, restart it withrebase_dev_stop and rebase_dev_start. …Desde 0.25 A partir de um
terminal, rebase db push e rebase db migrate rodam nesse banco de dados;
apenas as ferramentas do MCP são recusadas. Na 0.24 o CLI também as recusa ali.
Apenas o loopback é considerado local: localhost, *.localhost, 127.0.0.0/8, ::1.
Faixas privadas como 10.x e 192.168.x não são — essas têm tanta probabilidade de ser
um cluster de homologação compartilhado quanto um laptop, e tratá-las como locais liberaria
exatamente o tipo de acidente que o gate foi criado para impedir.
Defina REBASE_MCP_ALLOW_REMOTE_WRITES=true para desativar essa proteção. Definir isso globalmente na sua
configuração de cliente MCP remove o gate para todos os projetos que o servidor pode alcançar, não
apenas aquele no qual você estava pensando.
Marcação de dados não confiáveis
Seção intitulada “Marcação de dados não confiáveis”Linhas, registros de usuário, listagens de storage, jobs cron, respostas de funções e saídas de CLI retornam envolvidos em um envelope explícito:
<<<UNTRUSTED_DATA source="list_documents" id="9b2f4c1e-…">>>[ … rows … ]<<<END_UNTRUSTED_DATA id="9b2f4c1e-…">>>Qualquer coisa armazenada no seu banco de dados foi gravada por alguém, e chega pelo mesmo canal que o contrato de ferramentas seguido pelo assistente. O envelope instrui o modelo a tratar isso como conteúdo inerte, e não como instruções.
O id é gerado do zero para cada resposta, após os dados terem sido gravados, e
apenas o marcador final que o contém fecha o bloco. Textos dentro dos dados que tenham
formato semelhante ao marcador são quebrados com um espaço de largura zero (zero-width space), para que uma linha contendo
<<<END_UNTRUSTED_DATA>>> não encerre o envelope prematuramente deixando o que vem a seguir
do lado de fora.
O endpoint remoto cerca os resultados das suas ferramentas da mesma
forma e avisa o cliente disso; seu structuredContent carrega o resultado puro.
Desde 0.25 list_collections e
describe_collection são as exceções: só um modelo as lê, por isso são
enviadas uma única vez, no texto. Antes da 0.24 a listagem também carregava uma
cópia em structuredContent.
Trata-se de um marcador, não de uma sandbox. Um assistente que possui essas ferramentas é apenas tão seguro quanto o conteúdo que você permite que ele leia.
Múltiplos projetos
Seção intitulada “Múltiplos projetos”As configurações de projetos são armazenadas em ~/.rebase/projects.json, e o servidor
pode manter vários ao mesmo tempo — útil quando você trabalha alternando entre ambientes
locais e remotos. Enquanto o rebase dev estiver em execução, o servidor lê a porta ativa e
a service key de .rebase/state.json no diretório do projeto, o que
torna o caso local sem necessidade de configuração (zero-config).
Os tokens são armazenados nesse registro em texto simples. É um arquivo no seu diretório pessoal contendo credenciais de administrador para cada projeto que você registrou; trate-o com o devido cuidado.
Referência de ferramentas
Seção intitulada “Referência de ferramentas”42 ferramentas, divididas em nove grupos: schema e banco de dados, planejamento de schema, documentos, usuários e roles, storage, cron, funções, servidor de desenvolvimento e registro de projetos. Cada uma, com o que precisa e se o gate a recusa contra um destino não local, está na referência de ferramentas do MCP.
Recursos
Seção intitulada “Recursos”Além das ferramentas, o servidor expõe recursos MCP para que o cliente possa obter contexto do projeto sem gastar uma chamada de ferramenta:
| URI | Descrição |
|---|---|
rebase://collections/{name} |
Código TypeScript da definição da coleção |
rebase://schema |
O schema Drizzle gerado (schema.generated.ts) |
As coleções são descobertas em app/config/collections/,
config/collections/ ou collections/ sob o diretório do projeto ativo —
qualquer que existir.
rebase://schema é listado apenas se o schema gerado existir.
O findBackendDir procura por backend/ e depois por app/backend/ sob o diretório
do projeto ativo, e lê src/schema.generated.ts daquele que encontrar —
de modo que tanto o layout padrão quanto o deste monorepo funcionam, e um projeto estruturado
de uma terceira forma, ou um que ainda não executou rebase schema generate, simplesmente não
verá o recurso ser disponibilizado.
O endpoint remoto
Seção intitulada “O endpoint remoto”Tudo o que foi citado acima é uma ferramenta de desenvolvedor: roda na sua máquina e utiliza uma
service key ou uma API key. Um backend implantado também pode servir o próprio MCP, em /mcp, para
as pessoas que usam sua aplicação. Um assistente conectado por uma delas lê e
grava no projeto como aquela pessoa, e cada chamada é executada sob as suas próprias
regras de row-level security (RLS).
Ele fica desativado a menos que você o ative, e ambas as variáveis são obrigatórias:
REBASE_MCP_ENABLED=trueREBASE_PUBLIC_URL=https://app.example.com # this deployment's real originSem REBASE_PUBLIC_URL, um segredo JWT ou um driver de dados capaz de restringir uma consulta
a um usuário, o endpoint se recusa a inicializar e informa o motivo no log de boot. Nenhuma
REBASE_ROLE o ativa.
- OAuth, com uma tela de consentimento. O cliente localiza o servidor de autorização
por meio de
/.well-known/oauth-protected-resource, registra-se (o registro dinâmico vem ativado por padrão;REBASE_MCP_OPEN_REGISTRATION=falselimita-o aos clientes que você registrar) e envia a pessoa para uma tela de consentimento que faz o login através do seu/auth/loginexistente. - Oito ferramentas, três escopos. Os mesmos escopos
que toda credencial usa.
data:readoferecelist_collections,describe_collection,query_collection,count_documentseget_document;data:writeadicionacreate_documenteupdate_document;data:deleteadicionadelete_document. Um cliente que não pede nada recebedata:read. Cada um pode ser restringido a uma coleção:data:read:postslista, descreve e lêpostse nada mais. Um escopo decide quais ferramentas são oferecidas e quais coleções elas alcançam, não quais linhas: uma lista vazia pode ser o RLS atuando, edata:writeainda assim não poderá gravar uma linha que a pessoa não pudesse gravar. - Concessões feitas antes da 0.24 mantêm seu alcance.
mcp:readé lido comodata:read, emcp:writecomodata:write data:delete, nas concessões armazenadas e nos tokens já emitidos. - Uma chave de API também funciona.
/mcptambém aceitaAuthorization: Bearer rk_…, para um cliente configurado com um header em vez de um fluxo OAuth. A chave alcança as ferramentas que seus escoposdata:*cobrem, como quem quer que ela represente: uma chave pessoal como seu proprietário, uma chave de serviço comoapi-key:<id>. - O vocabulário do SDK, as respostas do REST. As ferramentas recebem o que o SDK recebe —
where({"status": ["==", "paid"]}),orderBy(["created_at", "desc"]ou"created_at:desc"),limit,offset,searchString, edatapara uma escrita — e leem através do caminho deGET /api/data/<collection>, então uma linha volta como o REST a serve (datas ISO, umbelongsTocomo sua chave estrangeira, por exemploauthorId) e pode ser enviada de volta em uma atualização sem alterações.query_collectionresponde{ data, meta }commeta.totalemeta.hasMore, ecount_documents{ count }. Como no REST, umlimitacima de 1000, um argumento não declarado e uma edição ou exclusão de uma linha na lixeira (404) são recusados; definir o campo de soft-delete comonulla restaura. - Desde 0.25 A listagem nomeia as coleções;
describe_collectiondá o esquema de uma.list_collectionsrespondename,titleedescriptionde cada coleção, edescribe_collection { collection }os esquemas OpenAPIrowecreatedessa coleção, além desoftDeleteFieldonde linhas vão para a lixeira. As descrições das ferramentas dizem ao modelo para descrever uma coleção antes de gravar nela. A listagem de um projeto com 200 coleções tem cerca de 5k tokens, e cada descrição menos de 1k; com todos os esquemas na listagem eram cerca de 150k. - Um token apenas para este endpoint. Um token de acesso MCP é recusado por
/api/data,/api/admine pelo WebSocket, logo conectar um assistente não entrega uma sessão a ele.
Uma limitação: desconectar um cliente (DELETE /api/oauth/grants/:clientId, com a
sessão da própria pessoa) revoga seus refresh tokens imediatamente, mas um token de acesso
já emitido continua funcionando até expirar, dentro do prazo de uma hora. Essa mesma hora
limita todo o restante: cada refresh relê as roles da pessoa e recusa
uma conta que foi excluída ou uma concessão mais antiga que o último “sair de todos os dispositivos”
ou alteração de senha. Portanto, um rebaixamento de permissão ou logout atinge um cliente conectado
dentro da vida útil de um token de acesso. Uma sessão de visitante (guest) não pode dar consentimento.
As rotas estão em Endpoints e as variáveis em Configuração.
Configuração recomendada
Seção intitulada “Configuração recomendada”- Aponte o servidor para um projeto local e mantenha
REBASE_MCP_ALLOW_REMOTE_WRITESindefinido. O gate é o recurso mais valioso do pacote. - Para qualquer ambiente remoto, registre uma API key
rk_com escopo restrito em vez de permitir que a descoberta automática utilize uma service key. - Verifique
rebase_project_currentquando a saída parecer estranha. O projeto ativo é persistente (sticky) e fica fora do seu repositório. - Trate o arquivo
~/.rebase/projects.jsoncomo um arquivo de segredos.