Self-Hosted Supabase MCP Server

Interaja com instâncias auto-hospedadas do Supabase para introspecção, gerenciamento e interação de banco de dados.

Documentação

Servidor MCP Supabase Auto-hospedado

License: MIT smithery badge

Visão Geral

Este projeto fornece um servidor Model Context Protocol (MCP) projetado especificamente para interagir com instâncias Supabase auto-hospedadas. Ele preenche a lacuna entre clientes MCP (como extensões de IDE) e seus projetos Supabase locais ou hospedados privadamente, permitindo introspecção de banco de dados, gerenciamento e interação diretamente do seu ambiente de desenvolvimento.

Este servidor foi construído do zero, aproveitando lições aprendidas ao adaptar o servidor MCP oficial da nuvem Supabase, para fornecer uma implementação mínima e focada, adaptada ao caso de uso auto-hospedado.

Propósito

O objetivo principal deste servidor é permitir que desenvolvedores que usam instalações Supabase auto-hospedadas aproveitem ferramentas baseadas em MCP para tarefas como:

  • Consultar esquemas e dados do banco de dados.
  • Gerenciar migrações de banco de dados.
  • Inspecionar estatísticas e conexões do banco de dados.
  • Gerenciar usuários de autenticação.
  • Interagir com o Supabase Storage.
  • Gerar definições de tipos.

Ele evita as complexidades do servidor oficial da nuvem relacionadas ao gerenciamento de múltiplos projetos e APIs específicas da nuvem, oferecendo uma experiência simplificada para ambientes auto-hospedados de projeto único.

Recursos (Ferramentas Implementadas)

As ferramentas são categorizadas por nível de privilégio:

  • Ferramentas Regulares são acessíveis por qualquer JWT Supabase autenticado (função authenticated ou service_role).
  • Ferramentas Privilegiadas exigem um JWT service_role (modo HTTP) ou acesso direto ao banco de dados/chave de serviço (modo stdio).

Esquema e Migrações

FerramentaDescriçãoPrivilégio
list_tablesLista tabelas nos esquemas do banco de dadosRegular
list_extensionsLista extensões PostgreSQL instaladasRegular
list_available_extensionsLista todas as extensões disponíveis (instaláveis)Regular
list_migrationsLista migrações aplicadas de supabase_migrations.schema_migrationsRegular
apply_migrationAplica uma migração SQL e a registra em supabase_migrations.schema_migrationsPrivilegiado
list_table_columnsLista colunas para uma tabela específicaRegular
list_indexesLista índices para uma tabela específicaRegular
list_constraintsLista restrições para uma tabela específicaRegular
list_foreign_keysLista chaves estrangeiras para uma tabela específicaRegular
list_triggersLista gatilhos para uma tabela específicaRegular
list_database_functionsLista funções de banco de dados definidas pelo usuárioRegular
get_function_definitionObtém a definição de origem de uma funçãoRegular
get_trigger_definitionObtém a definição de origem de um gatilhoRegular

Operações e Estatísticas do Banco de Dados

FerramentaDescriçãoPrivilégio
execute_sqlExecuta uma consulta SQL arbitráriaPrivilegiado
explain_queryExecuta EXPLAIN ANALYZE em uma consultaPrivilegiado
get_database_connectionsMostra conexões ativas (pg_stat_activity)Regular
get_database_statsRecupera estatísticas do banco de dados (pg_stat_*)Regular
get_index_statsMostra estatísticas de uso de índicesRegular
get_vector_index_statsMostra estatísticas de índices pgvectorRegular

Segurança e RLS

FerramentaDescriçãoPrivilégio
list_rls_policiesLista políticas de Row-Level Security para uma tabelaRegular
get_rls_statusMostra status RLS habilitado/desabilitado para tabelasRegular
get_advisorsRecupera avisos de segurança e desempenhoRegular

Configuração do Projeto

FerramentaDescriçãoPrivilégio
get_project_urlRetorna a URL Supabase configuradaRegular
verify_jwt_secretVerifica se o segredo JWT está configuradoRegular

Ferramentas de Desenvolvimento e Extensão

FerramentaDescriçãoPrivilégio
generate_typescript_typesGera tipos TypeScript a partir do esquema do banco de dadosRegular
rebuild_hooksReinicia o worker pg_net (se usado)Privilegiado
get_logsRecupera entradas de log recentes (stack de analytics ou fallback CSV)Regular

Gerenciamento de Usuários de Autenticação

FerramentaDescriçãoPrivilégio
list_auth_usersLista usuários de auth.usersRegular
get_auth_userRecupera detalhes para um usuário específicoRegular
create_auth_userCria um novo usuário em auth.users (senha com hash bcrypt via pgcrypto)Privilegiado
update_auth_userAtualiza detalhes do usuário (senha com hash bcrypt se alterada)Privilegiado
delete_auth_userExclui um usuário de auth.usersPrivilegiado

Armazenamento

FerramentaDescriçãoPrivilégio
list_storage_bucketsLista todos os buckets de armazenamentoRegular
list_storage_objectsLista objetos dentro de um bucket específicoRegular
get_storage_configRecupera configuração do bucket de armazenamentoRegular
update_storage_configAtualiza configurações do bucket de armazenamentoPrivilegiado

Inspeção em Tempo Real

FerramentaDescriçãoPrivilégio
list_realtime_publicationsLista publicações PostgreSQL (ex.: supabase_realtime)Regular

Ferramentas Específicas de Extensão

FerramentaDescriçãoPrivilégio
list_cron_jobsLista trabalhos agendados (requer extensão pg_cron)Regular
get_cron_job_historyMostra histórico de execução recente para um trabalho cronRegular
list_vector_indexesLista índices pgvector (requer extensão pgvector)Regular

Edge Functions

FerramentaDescriçãoPrivilégio
list_edge_functionsLista Edge Functions implantadasRegular
get_edge_function_detailsObtém detalhes e metadados para uma Edge FunctionRegular
list_edge_function_logsRecupera logs recentes para uma Edge FunctionRegular

Sobre supabase_migrations.schema_migrations

As ferramentas list_migrations e apply_migration dependem da tabela supabase_migrations.schema_migrations. Esta tabela é criada e gerenciada pelo Supabase CLI — ela não faz parte do servidor MCP em si.

Como a tabela é criada:

A tabela é criada automaticamente quando você inicializa ou executa migrações usando o Supabase CLI:

supabase db push        # pushes local migrations to a remote database
supabase migration up   # applies pending local migration files

Se você nunca executou o Supabase CLI contra seu banco de dados, a tabela não existirá e list_migrations retornará um erro. Você pode criá-la manualmente com:

CREATE SCHEMA IF NOT EXISTS supabase_migrations;
CREATE TABLE IF NOT EXISTS supabase_migrations.schema_migrations (
    version text NOT NULL PRIMARY KEY,
    name    text NOT NULL DEFAULT '',
    inserted_at timestamptz NOT NULL DEFAULT now()
);

Diferença de esquema vs. Supabase oficial:

A plataforma de nuvem Supabase rastreia colunas adicionais (ex.: statements, dirty). Este servidor MCP usa o esquema mínimo (versão + nome + inserted_at) que é compatível com o fluxo de trabalho de desenvolvimento local do Supabase CLI. Se sua tabela existente tiver colunas extras, elas são simplesmente ignoradas.

Configuração e Instalação

Instalando via Smithery

Para instalar o Self-Hosted Supabase MCP Server para Claude Desktop automaticamente via Smithery:

npx -y @smithery/cli install @HenkDz/selfhosted-supabase-mcp --client claude

Pré-requisitos

  • Bun v1.1 ou posterior (substitui Node.js/npm — usado para runtime e builds)
  • Acesso à sua instância Supabase auto-hospedada (URL, chaves e, opcionalmente, uma string de conexão PostgreSQL direta).

Passos

  1. Clone o repositório:
    git clone <repository-url>
    cd selfhosted-supabase-mcp
    
  2. Instale as dependências:
    bun install
    
  3. Compile o projeto:
    bun run build
    
    Isso compila o código-fonte TypeScript para JavaScript no diretório dist.

Configuração

O servidor requer detalhes de configuração para sua instância Supabase. Eles podem ser fornecidos via argumentos de linha de comando ou variáveis de ambiente. Argumentos de CLI têm precedência.

Obrigatório:

  • --url <url> ou SUPABASE_URL=<url>: A URL HTTP principal do seu projeto Supabase (ex.: http://localhost:8000).
  • --anon-key <key> ou SUPABASE_ANON_KEY=<key>: A chave anônima do seu projeto Supabase.

Opcional (mas Recomendado/Obrigatório para certas ferramentas):

  • --service-key <key> ou SUPABASE_SERVICE_ROLE_KEY=<key>: A chave de função de serviço do seu projeto Supabase. Necessária para ferramentas privilegiadas e para criar automaticamente a função auxiliar execute_sql na inicialização.
  • --db-url <url> ou DATABASE_URL=<url>: A string de conexão PostgreSQL direta para seu banco de dados Supabase (ex.: postgresql://postgres:password@localhost:5432/postgres). Necessária para ferramentas que exigem acesso direto ao banco de dados (apply_migration, ferramentas de Auth, ferramentas de Storage, consultas pg_catalog).
  • --jwt-secret <secret> ou SUPABASE_AUTH_JWT_SECRET=<secret>: O segredo JWT do seu projeto Supabase. Necessário ao usar --transport http e exigido pela ferramenta verify_jwt_secret.
  • --tools-config <path>: Caminho para um arquivo JSON especificando quais ferramentas habilitar (whitelist). Se omitido, todas as ferramentas são habilitadas. Formato: {"enabledTools": ["tool_name_1", "tool_name_2"]}.

Opções de transporte HTTP (ao usar --transport http):

  • --port <number>: Porta do servidor HTTP (padrão: 3000).
  • --host <string>: Host do servidor HTTP (padrão: 127.0.0.1).
  • --cors-origins <origins>: Lista separada por vírgulas de origens CORS permitidas. Padrão: apenas localhost.
  • --rate-limit-window <ms>: Janela de limite de taxa em milissegundos (padrão: 60000).
  • --rate-limit-max <count>: Máximo de solicitações por janela de limite de taxa (padrão: 100).
  • --request-timeout <ms>: Tempo limite de solicitação em milissegundos (padrão: 30000).

Notas Importantes:

  • Função Auxiliar execute_sql: Muitas ferramentas dependem de uma função public.execute_sql dentro do seu banco de dados Supabase para execução SQL via RPC. O servidor tenta verificar essa função na inicialização. Se estiver ausente e um service-key e db-url forem fornecidos, ele tentará criar a função automaticamente. Se a criação falhar ou as chaves não forem fornecidas, ferramentas que dependem exclusivamente de RPC podem falhar.
  • Acesso Direto ao Banco de Dados: Ferramentas que interagem diretamente com esquemas privilegiados (auth, storage) ou catálogos do sistema (pg_catalog) geralmente exigem que DATABASE_URL esteja configurado.
  • Implantações Coolify / proxy reverso:
    • O DATABASE_URL deve usar o nome de host interno alcançável de onde o processo do servidor MCP é executado, não o domínio público.
    • Um erro ECONNRESET durante a inicialização significa que o DATABASE_URL não pode ser alcançado a partir do contexto de rede do servidor.
    • O servidor ainda iniciará com sucesso e todas as ferramentas que não exigem conexão direta com o banco continuarão funcionando normalmente.

Segurança

Transporte HTTP (recomendado para acesso remoto)

Ao executar com --transport http, o servidor aplica:

  • Autenticação JWT em todos os endpoints /mcp usando seu SUPABASE_AUTH_JWT_SECRET.
  • Controle de acesso baseado em privilégios (RBAC) — a declaração role no JWT determina quais ferramentas são acessíveis:
    • service_role: Acesso total (todas as ferramentas, incluindo privilegiadas).
    • authenticated: Apenas ferramentas regulares.
    • anon: Sem acesso a ferramentas.
  • Limite de taxa — limite de taxa de solicitação configurável por endereço IP.
  • CORS — lista de origens permitidas configurável (padrão: apenas localhost).
  • Cabeçalhos de segurança — X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, etc.
  • Tempos limite de solicitação — tempo limite configurável para evitar esgotamento de recursos.

Transporte Stdio (desenvolvimento local)

O modo Stdio não tem autenticação — todas as ferramentas (incluindo as privilegiadas) são acessíveis. Ele é destinado apenas a clientes locais confiáveis (ex.: uma extensão de IDE executando em sua máquina local). Um aviso é exibido na inicialização quando este modo é usado.

Tratamento de senha para ferramentas de usuário de autenticação

create_auth_user e update_auth_user aceitam uma senha em texto puro do cliente MCP e, em seguida, a transformam imediatamente em hash com bcrypt (por meio da extensão pgcrypto do PostgreSQL: crypt($password, gen_salt('bf'))) antes de armazená-la em auth.users. A senha em texto puro nunca é armazenada. As senhas são passadas como parâmetros de consulta (não interpoladas como string no SQL), prevenindo injeção de SQL.

Nota: A senha trafega pelo transporte MCP em texto puro entre o cliente e o servidor MCP. Isso é inerente à interface do protocolo MCP e inevitável nesta camada. Use o transporte HTTP com terminação TLS (por exemplo, atrás de Kong/nginx) para proteção de rede.

Segurança da execução de SQL

Todas as operações de banco de dados no servidor MCP usam consultas parametrizadas ($1, $2, ...) para prevenir injeção de SQL. A ferramenta execute_sql é uma exceção intencional — ela executa SQL arbitrário por design (é o propósito da ferramenta). Esta ferramenta é restrita ao nível de privilégio service_role para limitar a exposição.

Uso

Modo Stdio (clientes MCP locais)

Execute o servidor usando Bun, fornecendo a configuração necessária:

# Using CLI arguments (stdio mode — default)
bun run dist/index.js --url http://localhost:8000 --anon-key <your-anon-key> \
  --db-url postgresql://postgres:password@localhost:5432/postgres \
  --service-key <your-service-key>

# Example with tool whitelisting via config file
bun run dist/index.js --url http://localhost:8000 --anon-key <your-anon-key> \
  --tools-config ./mcp-tools.json

# Or configure using environment variables and run:
# export SUPABASE_URL=http://localhost:8000
# export SUPABASE_ANON_KEY=<your-anon-key>
# export DATABASE_URL=postgresql://postgres:password@localhost:5432/postgres
# export SUPABASE_SERVICE_ROLE_KEY=<your-service-key>
bun run dist/index.js

Modo HTTP (Docker / acesso remoto)

bun run dist/index.js \
  --transport http \
  --port 3100 \
  --host 0.0.0.0 \
  --url http://kong:8000 \
  --anon-key <your-anon-key> \
  --service-key <your-service-key> \
  --jwt-secret <your-jwt-secret> \
  --db-url postgresql://postgres:password@db:5432/postgres

O modo HTTP requer --jwt-secret. Todas as requisições /mcp devem incluir um JWT Supabase válido no cabeçalho Authorization: Bearer <token>.

O servidor se comunica via stdio (padrão) ou HTTP (Streamable HTTP Transport) e é projetado para ser invocado por um aplicativo cliente MCP (por exemplo, uma extensão de IDE como o Cursor). O cliente se conectará ao fluxo stdio ou ao endpoint HTTP do servidor para listar e chamar as ferramentas disponíveis.

Exemplos de Configuração de Cliente

Abaixo estão exemplos de como configurar clientes MCP populares para usar este servidor auto-hospedado.

Importante:

  • Substitua os placeholders como <your-supabase-url>, <your-anon-key>, <your-db-url>, <path-to-dist/index.js> etc., pelos seus valores reais.
  • Certifique-se de que o caminho para o arquivo compilado do servidor (dist/index.js) esteja correto para o seu sistema.
  • Tenha cuidado ao armazenar chaves sensíveis diretamente em arquivos de configuração, especialmente se forem commitadas no controle de versão. Considere usar variáveis de ambiente ou métodos mais seguros quando suportados pelo cliente.

Cursor

  1. Crie ou abra o arquivo .cursor/mcp.json na raiz do seu projeto.

  2. Adicione a seguinte configuração:

    {
      "mcpServers": {
        "selfhosted-supabase": { 
          "command": "bun",
          "args": [
            "run",
            "<path-to-dist/index.js>", // e.g., "/home/user/selfhosted-supabase-mcp/dist/index.js"
            "--url",
            "<your-supabase-url>", // e.g., "http://localhost:8000"
            "--anon-key",
            "<your-anon-key>",
            // Optional - Add these if needed by the tools you use
            "--service-key",
            "<your-service-key>",
            "--db-url",
            "<your-db-url>", // e.g., "postgresql://postgres:password@host:port/postgres"
            "--jwt-secret",
            "<your-jwt-secret>",
            // Optional - Whitelist specific tools
            "--tools-config",
            "<path-to-your-mcp-tools.json>" // e.g., "./mcp-tools.json"
          ]
        }
      }
    }
    

Visual Studio Code (Copilot)

O VS Code Copilot permite usar variáveis de ambiente preenchidas por meio de entradas solicitadas, o que é mais seguro para chaves.

  1. Crie ou abra o arquivo .vscode/mcp.json na raiz do seu projeto.

  2. Adicione a seguinte configuração:

    {
      "inputs": [
        { "type": "promptString", "id": "sh-supabase-url", "description": "Self-Hosted Supabase URL", "default": "http://localhost:8000" },
        { "type": "promptString", "id": "sh-supabase-anon-key", "description": "Self-Hosted Supabase Anon Key", "password": true },
        { "type": "promptString", "id": "sh-supabase-service-key", "description": "Self-Hosted Supabase Service Key (Optional)", "password": true, "required": false },
        { "type": "promptString", "id": "sh-supabase-db-url", "description": "Self-Hosted Supabase DB URL (Optional)", "password": true, "required": false },
        { "type": "promptString", "id": "sh-supabase-jwt-secret", "description": "Self-Hosted Supabase JWT Secret (Optional)", "password": true, "required": false },
        { "type": "promptString", "id": "sh-supabase-server-path", "description": "Path to self-hosted-supabase-mcp/dist/index.js" },
        { "type": "promptString", "id": "sh-supabase-tools-config", "description": "Path to tools config JSON (Optional, e.g., ./mcp-tools.json)", "required": false }
      ],
      "servers": {
        "selfhosted-supabase": {
          "command": "bun",
          "args": [
            "run",
            "${input:sh-supabase-server-path}",
            "--tools-config", "${input:sh-supabase-tools-config}"
           ],
          "env": {
            "SUPABASE_URL": "${input:sh-supabase-url}",
            "SUPABASE_ANON_KEY": "${input:sh-supabase-anon-key}",
            "SUPABASE_SERVICE_ROLE_KEY": "${input:sh-supabase-service-key}",
            "DATABASE_URL": "${input:sh-supabase-db-url}",
            "SUPABASE_AUTH_JWT_SECRET": "${input:sh-supabase-jwt-secret}"
          }
        }
      }
    }
    
  3. Quando você usar o Copilot Chat no modo Agente (@workspace), ele deve detectar o servidor. Você será solicitado a inserir os detalhes (URL, chaves, caminho) quando o servidor for invocado pela primeira vez.

Outros Clientes (Windsurf, Cline, Claude)

Adapte a estrutura de configuração mostrada para o Cursor ou a documentação oficial do Supabase, substituindo o command e o args pelo comando bun run e os argumentos para este servidor, semelhante ao exemplo do Cursor:

{
  "mcpServers": {
    "selfhosted-supabase": { 
      "command": "bun",
      "args": [
        "run",
        "<path-to-dist/index.js>", 
        "--url", "<your-supabase-url>", 
        "--anon-key", "<your-anon-key>", 
        "--service-key", "<your-service-key>", 
        "--db-url", "<your-db-url>", 
        "--jwt-secret", "<your-jwt-secret>",
        "--tools-config", "<path-to-your-mcp-tools.json>"
      ]
    }
  }
}

Consulte a documentação específica de cada cliente sobre onde colocar o mcp.json ou o arquivo de configuração equivalente.

Integração Docker com Supabase Auto-Hospedado

Este servidor MCP pode ser integrado diretamente a uma stack Docker Compose do Supabase auto-hospedado, tornando-o disponível junto com outros serviços do Supabase por meio do gateway de API Kong.

Visão Geral da Arquitetura

Quando integrado com Docker:

  • O servidor MCP executa em modo de transporte HTTP (não stdio)
  • Ele é exposto por meio do Kong em /mcp/v1/*
  • A autenticação JWT é tratada pelo próprio servidor MCP
  • O servidor tem acesso direto ao banco de dados e a todas as chaves do Supabase

Etapas de Configuração

1. Adicione o Servidor MCP como um Submódulo Git

A partir do seu diretório Docker do Supabase:

git submodule add https://github.com/HenkDz/selfhosted-supabase-mcp.git selfhosted-supabase-mcp

2. Crie o Dockerfile

Crie volumes/mcp/Dockerfile:

# Dockerfile for selfhosted-supabase-mcp HTTP mode
# Multi-stage build using Bun runtime for self-hosted Supabase

FROM oven/bun:1.1-alpine AS builder

WORKDIR /app

# Copy package files from submodule
COPY selfhosted-supabase-mcp/package.json selfhosted-supabase-mcp/bun.lock* ./

# Install dependencies
RUN bun install --frozen-lockfile || bun install

# Copy source code
COPY selfhosted-supabase-mcp/src ./src
COPY selfhosted-supabase-mcp/tsconfig.json ./

# Build the application
RUN bun build src/index.ts --outdir dist --target bun

# Production stage
FROM oven/bun:1.1-alpine AS runner

WORKDIR /app

# Create non-root user for security
RUN addgroup --system --gid 1001 mcp && \
    adduser --system --uid 1001 --ingroup mcp mcp

# Copy built application from builder
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

# Set ownership
RUN chown -R mcp:mcp /app

USER mcp

# Default environment variables
ENV NODE_ENV=production

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:3100/health || exit 1

# Expose HTTP port
EXPOSE 3100

# Start the MCP server in HTTP mode
CMD ["bun", "run", "dist/index.js"]

3. Adicione o Serviço MCP ao docker-compose.yml

Adicione esta definição de serviço ao seu docker-compose.yml:

## MCP Server - Model Context Protocol for AI integrations
## DISABLED BY DEFAULT - Add 'mcp' to COMPOSE_PROFILES to enable
mcp:
  container_name: ${COMPOSE_PROJECT_NAME:-supabase}-mcp
  profiles:
    - mcp
  build:
    context: .
    dockerfile: ./volumes/mcp/Dockerfile
  restart: unless-stopped
  healthcheck:
    test:
      [
        "CMD",
        "wget",
        "--no-verbose",
        "--tries=1",
        "--spider",
        "http://localhost:3100/health"
      ]
    timeout: 5s
    interval: 10s
    retries: 3
  depends_on:
    db:
      condition: service_healthy
    rest:
      condition: service_started
  environment:
    SUPABASE_URL: http://kong:8000
    SUPABASE_ANON_KEY: ${ANON_KEY}
    SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
    SUPABASE_AUTH_JWT_SECRET: ${JWT_SECRET}
    DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
  command:
    [
      "bun",
      "run",
      "dist/index.js",
      "--transport", "http",
      "--port", "3100",
      "--host", "0.0.0.0",
      "--url", "http://kong:8000",
      "--anon-key", "${ANON_KEY}",
      "--service-key", "${SERVICE_ROLE_KEY}",
      "--jwt-secret", "${JWT_SECRET}",
      "--db-url", "postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
    ]

4. Adicione Rotas do Gateway de API Kong

Adicione as rotas MCP ao volumes/api/kong.yml na seção services:

## MCP Server routes - Model Context Protocol for AI integrations
## Authentication is handled by the MCP server itself (JWT validation)
- name: mcp-v1
  _comment: 'MCP Server: /mcp/v1/* -> http://mcp:3100/*'
  url: http://mcp:3100/
  routes:
    - name: mcp-v1-all
      strip_path: true
      paths:
        - /mcp/v1/
  plugins:
    - name: cors
      config:
        origins:
          - "$SITE_URL_PATTERN"
          - "http://localhost:3000"
          - "http://127.0.0.1:3000"
        methods:
          - GET
          - POST
          - DELETE
          - OPTIONS
        headers:
          - Accept
          - Authorization
          - Content-Type
          - X-Client-Info
          - apikey
          - Mcp-Session-Id
        exposed_headers:
          - Mcp-Session-Id
        credentials: true
        max_age: 3600

5. Habilite o Serviço MCP

O serviço MCP usa perfis do Docker Compose, portanto, ele fica desabilitado por padrão. Para habilitá-lo:

Opção A: Defina no arquivo .env:

COMPOSE_PROFILES=mcp

Opção B: Habilite em tempo de execução:

docker compose --profile mcp up -d

Acessando o Servidor MCP

Uma vez em execução, o servidor MCP está disponível em:

  • Interno (de outros contêineres): http://mcp:3100
  • Externo (via Kong): http://localhost:8000/mcp/v1/

Autenticação

Quando executado em modo HTTP, o servidor MCP valida JWTs usando o JWT_SECRET configurado. Os clientes devem incluir um JWT Supabase válido no cabeçalho Authorization:

Authorization: Bearer <supabase-jwt>

A claim role do JWT determina o acesso:

  • service_role: Acesso total a todas as ferramentas (regulares + privilegiadas)
  • authenticated: Acesso apenas às ferramentas regulares
  • anon: Sem acesso às ferramentas

Verificação de Saúde

O servidor MCP expõe um endpoint de saúde:

curl http://localhost:8000/mcp/v1/health

Considerações de Segurança

Ao implantar via Docker:

  1. O servidor MCP executa como um usuário não-root (mcp:mcp)
  2. A autenticação JWT é aplicada para todas as chamadas de ferramentas
  3. Ferramentas privilegiadas (como execute_sql) exigem JWT service_role
  4. O CORS é configurado via Kong - ajuste as origens para a sua implantação

Desenvolvimento

  • Linguagem: TypeScript
  • Build: bun build (via bun run build)
  • Runtime: Bun v1.1+
  • Executor de testes: bun test
  • Dependências: Gerenciadas via bun (bun.lock)
  • Bibliotecas Principais: @supabase/supabase-js, pg (node-postgres), zod (validação), commander (argumentos de CLI), @modelcontextprotocol/sdk (framework de servidor MCP), express, jsonwebtoken.

Licença

Este projeto é licenciado sob a Licença MIT. Consulte o arquivo LICENSE para obter detalhes.