mcp-supabase-selfhosted 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,9 @@
1
+ # URL de tu instancia Self-Hosted de Supabase (ej. http://localhost:8000 o https://api.midominio.com)
2
+ SUPABASE_URL="http://localhost:8000"
3
+
4
+ # Service Role Key para hacer bypass de RLS (necesario para gestionar usuarios/buckets)
5
+ SUPABASE_SERVICE_ROLE_KEY="tu_service_role_key_aqui"
6
+
7
+ # URL de conexión directa a PostgreSQL (para queries directas y gestión de tablas)
8
+ # Generalmente: postgresql://postgres:postgres@localhost:5432/postgres
9
+ DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: supabase-selfhosted
3
+ description: Use when you need to interact with a self-hosted Supabase instance to configure Auth, Storage, manage the database schema, apply RLS policies, or debug performance.
4
+ ---
5
+
6
+ # Skill: Supabase Self-Hosted MCP
7
+
8
+ This skill guides the agent on how to correctly and safely utilize the `supabase-selfhosted` MCP server tools to interact with a self-hosted Supabase environment.
9
+
10
+ ## 1. When to Use
11
+ Activate this skill whenever the user asks to:
12
+ - "Configurar un usuario de prueba en auth."
13
+ - "Crear un bucket para mis imágenes."
14
+ - "Revisar las políticas de seguridad RLS."
15
+ - "Corregir problemas de rendimiento de la base de datos."
16
+ - "Ver qué columnas tiene una tabla en mi Supabase."
17
+
18
+ ## 2. Security and RLS (Row Level Security) Mandates
19
+ **Critical:** Because this MCP uses the `SUPABASE_SERVICE_ROLE_KEY` and direct PostgreSQL connections, **it bypasses Row Level Security (RLS) entirely.**
20
+ - When you create tables or schemas using `execute_sql`, you MUST strongly recommend or automatically apply RLS policies unless explicitly told otherwise.
21
+ - Use `list_rls_policies` to audit existing security rules.
22
+ - If the `get_advisors` tool flags tables without RLS, you should proactively offer to write the SQL to secure them.
23
+
24
+ ## 3. Recommended Workflows
25
+
26
+ ### A. Exploring the Database
27
+ 1. Run `list_tables` to see what exists.
28
+ 2. Run `get_schema({ table_name: "X" })` to understand the columns before writing any SQL.
29
+ 3. Run `get_advisors()` to check if there are missing indexes or security gaps.
30
+
31
+ ### B. Configuring Auth
32
+ 1. Use `list_users` to see who is registered.
33
+ 2. Use `create_user({ email, password, email_confirm: true })` to bootstrap administrative or test accounts without needing an email SMTP server configured locally.
34
+ 3. If asked to clean up, use `delete_user({ user_id })`.
35
+
36
+ ### C. Configuring Storage (Buckets)
37
+ 1. Use `list_buckets()` to check existing buckets.
38
+ 2. Use `create_bucket({ bucket: "name", public: true/false })` to make a new one. Remember: making a bucket public allows read access without auth, but RLS policies are still recommended via `storage.objects` table.
39
+ 3. Use `list_files({ bucket: "name" })` to verify uploads.
40
+
41
+ ### D. Debugging and Infrastructure
42
+ - If the user complains about "Too many connections" or database hanging, immediately run `get_active_connections()` to identify locked processes or long-running queries.
43
+ - Run `get_advisors()` and report the `cache_health` and `unused_indexes` so the user can optimize their self-hosted VPS resources.
44
+
45
+ ## 4. Examples
46
+
47
+ **Creating a Secure Table with RLS:**
48
+ If asked to create a `posts` table, execute:
49
+ ```sql
50
+ CREATE TABLE posts (
51
+ id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
52
+ title text,
53
+ user_id uuid REFERENCES auth.users(id)
54
+ );
55
+ ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
56
+ CREATE POLICY "Users can read own posts" ON posts FOR SELECT USING (auth.uid() = user_id);
57
+ ```
58
+ *(Always use `execute_sql` with robust SQL strings).*
@@ -0,0 +1,36 @@
1
+ name: Bug report
2
+ description: Create a report to help us improve
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to fill out this bug report!
9
+ - type: textarea
10
+ id: what-happened
11
+ attributes:
12
+ label: What happened?
13
+ description: Also tell us what you expected to happen
14
+ placeholder: Tell us what you see!
15
+ validations:
16
+ required: true
17
+ - type: textarea
18
+ id: reproduction-steps
19
+ attributes:
20
+ label: Steps to reproduce
21
+ description: How can we reproduce this?
22
+ placeholder: |
23
+ 1. Setup MCP with ...
24
+ 2. Run tool ...
25
+ 3. See error ...
26
+ validations:
27
+ required: true
28
+ - type: textarea
29
+ id: environment
30
+ attributes:
31
+ label: Environment
32
+ description: Operating System, Node version, Docker version, etc.
33
+ placeholder: |
34
+ - OS: Linux/macOS/Windows
35
+ - Node: v20.x
36
+ - MCP Client: Cursor/Claude Desktop
@@ -0,0 +1,23 @@
1
+ name: Feature request
2
+ description: Suggest an idea for this project
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Is your feature request related to a problem?
9
+ description: A concise description of what the problem is. Ex. I'm always frustrated when [...]
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: solution
14
+ attributes:
15
+ label: Describe the solution you'd like
16
+ description: A concise description of what you want to happen.
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: context
21
+ attributes:
22
+ label: Additional context
23
+ description: Add any other context or screenshots about the feature request here.
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+
13
+ strategy:
14
+ matrix:
15
+ node-version: [18.x, 20.x, 22.x]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - name: Use Node.js ${{ matrix.node-version }}
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: ${{ matrix.node-version }}
23
+ cache: 'npm'
24
+ - run: npm ci
25
+ - run: npm run lint
26
+ - run: npm run build
27
+ - run: npm test
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "all",
4
+ "singleQuote": true,
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-06-01
9
+
10
+ ### Added
11
+ - Initial release of the Supabase Self-Hosted MCP server.
12
+ - Database tools: `list_tables`, `get_schema`, `execute_sql`.
13
+ - Infrastructure tools: `get_advisors`, `get_active_connections`, `list_rls_policies`.
14
+ - Auth tools: `list_users`, `create_user`, `delete_user`.
15
+ - Storage tools: `list_buckets`, `create_bucket`, `delete_bucket`, `list_files`.
16
+ - Docker support with Multi-stage builds.
17
+ - One-command execution support via `npx`.
18
+ - Initial test suite and linting configuration.
19
+ - MIT License and community health files.
@@ -0,0 +1,34 @@
1
+ # Contributing to Supabase Self-Hosted MCP
2
+
3
+ First off, thank you for considering contributing to this project! It's people like you that make the open-source community such a great place to learn, inspire, and create.
4
+
5
+ ## Code of Conduct
6
+
7
+ By participating in this project, you are expected to uphold our Code of Conduct.
8
+
9
+ ## How Can I Contribute?
10
+
11
+ ### Reporting Bugs
12
+ - Use the [GitHub Bug Report template](.github/ISSUE_TEMPLATE/bug_report.md).
13
+ - Provide a clear and descriptive title.
14
+ - Describe the exact steps which reproduce the problem.
15
+
16
+ ### Suggesting Enhancements
17
+ - Use the [GitHub Feature Request template](.github/ISSUE_TEMPLATE/feature_request.md).
18
+ - Explain why this enhancement would be useful to most users.
19
+
20
+ ### Pull Requests
21
+ 1. Fork the repo and create your branch from `main`.
22
+ 2. If you've added code that should be tested, add tests.
23
+ 3. Ensure the test suite passes (`npm test`).
24
+ 4. Make sure your code lints (`npm run lint`).
25
+ 5. Issue that pull request!
26
+
27
+ ## Styleguide
28
+
29
+ - Use TypeScript for all logic.
30
+ - Follow the existing Prettier and ESLint configurations.
31
+ - Document new tools in the `README.md` and provide examples in the `SKILL.md` if applicable.
32
+
33
+ ## License
34
+ By contributing, you agree that your contributions will be licensed under its MIT License.
package/Dockerfile ADDED
@@ -0,0 +1,36 @@
1
+ # Construcción
2
+ FROM node:20-slim AS builder
3
+
4
+ WORKDIR /app
5
+
6
+ # Copiar configuración
7
+ COPY package*.json ./
8
+ COPY tsconfig.json ./
9
+
10
+ # Instalar dependencias
11
+ RUN npm ci
12
+
13
+ # Copiar código fuente
14
+ COPY src/ ./src/
15
+
16
+ # Compilar TypeScript
17
+ RUN npm run build
18
+
19
+ # Producción
20
+ FROM node:20-slim AS runner
21
+
22
+ WORKDIR /app
23
+
24
+ # Copiar archivos compilados y dependencias de producción
25
+ COPY package*.json ./
26
+ RUN npm ci --omit=dev
27
+
28
+ COPY --from=builder /app/dist ./dist
29
+
30
+ # Variables de entorno por defecto
31
+ ENV SUPABASE_URL=""
32
+ ENV SUPABASE_SERVICE_ROLE_KEY=""
33
+ ENV DATABASE_URL=""
34
+
35
+ # Ejecutar usando stdio (por eso no exponemos puertos HTTP)
36
+ ENTRYPOINT ["node", "dist/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Open Source Community
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do action so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Supabase Self-Hosted MCP Server
2
+
3
+ Un servidor [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) diseñado específicamente para instancias **Self-Hosted de Supabase**.
4
+
5
+ A diferencia del servidor MCP oficial que depende en gran medida de las APIs de la nube de Supabase y del `project-ref`, esta versión se conecta directamente a tu base de datos PostgreSQL local y a las APIs locales (Auth/Storage) usando tu `SUPABASE_URL` y tu `SERVICE_ROLE_KEY`.
6
+
7
+ ## Características
8
+
9
+ - **Introspección de Base de Datos:** Lista tablas y esquemas de tu Postgres.
10
+ - **Ejecución SQL Raw:** Ejecuta consultas SQL directamente, permitiendo a la IA leer datos o modificar la estructura (bypass de RLS).
11
+ - **Gestión de Autenticación:** Lista usuarios registrados en tu instancia.
12
+ - **Gestión de Storage:** Lista buckets de almacenamiento.
13
+
14
+ ## Requisitos
15
+
16
+ - Node.js >= 18
17
+ - Docker (opcional, pero recomendado)
18
+
19
+ ## Instalación y Uso (Local)
20
+
21
+ 1. Clona el repositorio:
22
+ ```bash
23
+ git clone https://github.com/tu-usuario/mcp-supabase-selfhosted.git
24
+ cd mcp-supabase-selfhosted
25
+ ```
26
+
27
+ 2. Instala las dependencias y compila:
28
+ ```bash
29
+ npm install
30
+ npm run build
31
+ ```
32
+
33
+ 3. Crea tu archivo de entorno:
34
+ ```bash
35
+ cp .env.example .env
36
+ ```
37
+ Rellena tus credenciales (asegúrate de usar la **Service Role Key**, ¡nunca la anónima!).
38
+
39
+ ## Uso con Docker (Recomendado)
40
+
41
+ La forma más limpia de utilizar este servidor en clientes IA (Cursor, Claude, Gemini) sin ensuciar tu entorno local es usar la imagen de Docker.
42
+
43
+ 1. Construye la imagen localmente:
44
+ ```bash
45
+ docker build -t supabase-selfhosted-mcp .
46
+ ```
47
+
48
+ ### Configuración en Claude Desktop / Cursor
49
+ Añade lo siguiente a tu archivo `claude_desktop_config.json` o configuración de Cursor:
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "supabase-selfhosted": {
55
+ "command": "docker",
56
+ "args": [
57
+ "run",
58
+ "-i",
59
+ "--rm",
60
+ "-e", "SUPABASE_URL=http://host.docker.internal:8000",
61
+ "-e", "SUPABASE_SERVICE_ROLE_KEY=tu-clave-aqui",
62
+ "-e", "DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/postgres",
63
+ "supabase-selfhosted-mcp"
64
+ ]
65
+ }
66
+ }
67
+ }
68
+ ```
69
+ *(Nota: usa `host.docker.internal` en lugar de `localhost` si tu base de datos corre en tu máquina host).*
70
+
71
+ ### Configuración en Gemini CLI
72
+ Puedes añadirlo en tu archivo `~/.gemini/settings.json`:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "supabase-selfhosted": {
78
+ "command": "docker",
79
+ "args": [
80
+ "run",
81
+ "-i",
82
+ "--rm",
83
+ "-e", "SUPABASE_URL=...",
84
+ "-e", "SUPABASE_SERVICE_ROLE_KEY=...",
85
+ "-e", "DATABASE_URL=...",
86
+ "supabase-selfhosted-mcp"
87
+ ]
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## Seguridad y Buenas Prácticas
94
+
95
+ - **Acceso Directo:** Este MCP utiliza conexiones directas a DB y la `SERVICE_ROLE_KEY`. Esto significa que la IA conectada tendrá acceso **total y sin restricciones (bypassing RLS)** a tu instancia.
96
+ - **Entornos:** Se recomienda encarecidamente utilizar esto **sólo en entornos de desarrollo local**, nunca apuntando a una base de datos de producción con datos reales sensibles.
97
+ - **Transporte:** El servidor usa `stdio` (entrada/salida estándar), lo cual es el protocolo de seguridad predeterminado en aplicaciones de escritorio como Cursor y Claude.
98
+
99
+ ## Contribuir
100
+
101
+ ¡Las contribuciones son bienvenidas! Sientete libre de abrir Issues o Pull Requests. Si planeas añadir una herramienta nueva, añádela en el directorio `src/tools/`.
102
+
103
+ ## Licencia
104
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,22 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Currently, only the latest version of the Supabase Self-Hosted MCP server is supported with security updates.
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 1.0.x | :white_check_mark: |
10
+ | < 1.0 | :x: |
11
+
12
+ ## Reporting a Vulnerability
13
+
14
+ We take security seriously. If you discover a security vulnerability within this project, please **do not open a public issue**. Instead, please report it via GitHub's Private Vulnerability Reporting feature or by contacting the maintainers directly.
15
+
16
+ ### Our Commitment
17
+ - We will acknowledge receipt of your report within 48 hours.
18
+ - We will provide an estimated timeframe for a fix.
19
+ - We will notify the community once a patch is available.
20
+
21
+ ### Bypassing RLS Note
22
+ Please note that this MCP server is designed for **administrative and development purposes**. By definition, using a `Service Role Key` bypasses Row Level Security. This is an intended feature of the tool and not considered a vulnerability in itself. However, exposures of credentials or remote execution flaws are critical bugs.
@@ -0,0 +1,5 @@
1
+ export declare function getConfig(): {
2
+ SUPABASE_URL?: string | undefined;
3
+ SUPABASE_SERVICE_ROLE_KEY?: string | undefined;
4
+ DATABASE_URL?: string | undefined;
5
+ };
@@ -0,0 +1,36 @@
1
+ import dotenv from 'dotenv';
2
+ import { z } from 'zod';
3
+ // Cargar variables de entorno del archivo .env si existe
4
+ dotenv.config();
5
+ // Esquema de validación para las variables de entorno
6
+ const envSchema = z
7
+ .object({
8
+ SUPABASE_URL: z.string().url('La URL de Supabase debe ser válida').optional(),
9
+ SUPABASE_SERVICE_ROLE_KEY: z.string().optional(),
10
+ DATABASE_URL: z
11
+ .string()
12
+ .url('La URL de la base de datos (Postgres) debe ser válida')
13
+ .optional(),
14
+ })
15
+ .refine((data) => {
16
+ // Al menos una de las dos formas de conexión debe estar configurada
17
+ const hasSupabaseAPI = !!(data.SUPABASE_URL && data.SUPABASE_SERVICE_ROLE_KEY);
18
+ const hasDBConnection = !!data.DATABASE_URL;
19
+ return hasSupabaseAPI || hasDBConnection;
20
+ }, {
21
+ message: 'Debes configurar al menos DATABASE_URL o (SUPABASE_URL y SUPABASE_SERVICE_ROLE_KEY)',
22
+ });
23
+ export function getConfig() {
24
+ try {
25
+ const config = envSchema.parse(process.env);
26
+ return config;
27
+ }
28
+ catch (error) {
29
+ if (error instanceof z.ZodError) {
30
+ console.error(' Error de configuración. Faltan variables de entorno o son inválidas:');
31
+ error.issues.forEach((e) => console.error(` - ${e.message}`));
32
+ process.exit(1);
33
+ }
34
+ throw error;
35
+ }
36
+ }
@@ -0,0 +1,9 @@
1
+ import { Pool } from 'pg';
2
+ /**
3
+ * Inicializa y retorna el pool de conexiones de Postgres si DATABASE_URL está configurada.
4
+ */
5
+ export declare function getDbPool(): Promise<Pool>;
6
+ /**
7
+ * Ejecuta una query segura usando el pool.
8
+ */
9
+ export declare function query(sql: string, params?: unknown[]): Promise<any[]>;
@@ -0,0 +1,50 @@
1
+ import { Pool } from 'pg';
2
+ import { getConfig } from '../config/env.js';
3
+ let pgPool = null;
4
+ /**
5
+ * Inicializa y retorna el pool de conexiones de Postgres si DATABASE_URL está configurada.
6
+ */
7
+ export async function getDbPool() {
8
+ if (pgPool) {
9
+ return pgPool;
10
+ }
11
+ const config = getConfig();
12
+ if (!config.DATABASE_URL) {
13
+ throw new Error('DATABASE_URL no está configurada. Las herramientas de base de datos directa no funcionarán.');
14
+ }
15
+ pgPool = new Pool({
16
+ connectionString: config.DATABASE_URL,
17
+ max: 10, // Límite máximo de conexiones activas para este MCP
18
+ idleTimeoutMillis: 30000, // Cerrar conexiones inactivas después de 30s
19
+ connectionTimeoutMillis: 5000, // Abortar intentos de conexión lentos
20
+ statement_timeout: 10000, // (10s) Abortar consultas pesadas/erróneas generadas por la IA
21
+ });
22
+ try {
23
+ // Verificamos la conexión con una consulta sencilla
24
+ const client = await pgPool.connect();
25
+ client.release();
26
+ console.error(' Conectado exitosamente a PostgreSQL (Pool con timeouts configurados).');
27
+ return pgPool;
28
+ }
29
+ catch (error) {
30
+ pgPool = null;
31
+ const msg = error instanceof Error ? error.message : String(error);
32
+ console.error(' Error conectando a PostgreSQL:', msg);
33
+ throw error;
34
+ }
35
+ }
36
+ /**
37
+ * Ejecuta una query segura usando el pool.
38
+ */
39
+ export async function query(sql, params = []) {
40
+ const pool = await getDbPool();
41
+ try {
42
+ const result = await pool.query(sql, params);
43
+ return result.rows;
44
+ }
45
+ catch (error) {
46
+ const msg = error instanceof Error ? error.message : String(error);
47
+ console.error(' Error ejecutando query:', msg);
48
+ throw error;
49
+ }
50
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
+ import { getConfig } from './config/env.js';
6
+ import { toolsDefinitions, handleExecuteSql, handleListBuckets, handleCreateBucket, handleDeleteBucket, handleListTables, handleListUsers, handleCreateUser, handleDeleteUser, handleGetSchema, handleGetAdvisors, handleListFiles, handleListRlsPolicies, handleGetActiveConnections, } from './tools/index.js';
7
+ async function main() {
8
+ // 1. Validar la configuración al inicio
9
+ getConfig();
10
+ // 2. Inicializar el servidor MCP
11
+ const server = new Server({
12
+ name: 'supabase-selfhosted-mcp',
13
+ version: '1.0.0',
14
+ }, {
15
+ capabilities: {
16
+ tools: {},
17
+ },
18
+ });
19
+ // 3. Registrar el manejador para listar herramientas (Tools)
20
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
21
+ return {
22
+ tools: toolsDefinitions,
23
+ };
24
+ });
25
+ // 4. Registrar el manejador para ejecutar herramientas
26
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
27
+ const { name, arguments: params } = request.params;
28
+ switch (name) {
29
+ case 'get_schema':
30
+ return await handleGetSchema(params);
31
+ case 'get_advisors':
32
+ return await handleGetAdvisors();
33
+ case 'list_tables':
34
+ return await handleListTables(params);
35
+ case 'execute_sql':
36
+ return await handleExecuteSql(params);
37
+ case 'list_users':
38
+ return await handleListUsers(params);
39
+ case 'create_user':
40
+ return await handleCreateUser(params);
41
+ case 'delete_user':
42
+ return await handleDeleteUser(params);
43
+ case 'list_buckets':
44
+ return await handleListBuckets();
45
+ case 'create_bucket':
46
+ return await handleCreateBucket(params);
47
+ case 'delete_bucket':
48
+ return await handleDeleteBucket(params);
49
+ case 'list_files':
50
+ return await handleListFiles(params);
51
+ case 'list_rls_policies':
52
+ return await handleListRlsPolicies(params);
53
+ case 'get_active_connections':
54
+ return await handleGetActiveConnections();
55
+ default:
56
+ throw new Error(`Tool not found: ${name}`);
57
+ }
58
+ });
59
+ // 5. Configurar el transporte stdio (entrada/salida estándar)
60
+ const transport = new StdioServerTransport();
61
+ await server.connect(transport);
62
+ console.error(' Servidor MCP de Supabase Self-Hosted iniciado correctamente.');
63
+ }
64
+ main().catch((error) => {
65
+ console.error(' Error fatal al iniciar el servidor MCP:', error);
66
+ process.exit(1);
67
+ });
@@ -0,0 +1,5 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ /**
3
+ * Inicializa y retorna el cliente de Supabase (usando la Service Role Key para bypassing de RLS).
4
+ */
5
+ export declare function getSupabaseClient(): SupabaseClient;
@@ -0,0 +1,26 @@
1
+ import { createClient } from '@supabase/supabase-js';
2
+ import { getConfig } from '../config/env.js';
3
+ let supabaseClient = null;
4
+ /**
5
+ * Inicializa y retorna el cliente de Supabase (usando la Service Role Key para bypassing de RLS).
6
+ */
7
+ export function getSupabaseClient() {
8
+ if (supabaseClient) {
9
+ return supabaseClient;
10
+ }
11
+ const config = getConfig();
12
+ if (!config.SUPABASE_URL || !config.SUPABASE_SERVICE_ROLE_KEY) {
13
+ throw new Error('SUPABASE_URL y SUPABASE_SERVICE_ROLE_KEY son obligatorias para utilizar las herramientas de Auth y Storage.');
14
+ }
15
+ // Creamos el cliente usando la service role key.
16
+ // IMPORTANTE: En el contexto de un MCP (que actúa como un super admin), es seguro
17
+ // y necesario usar la service role key, pero el usuario debe estar consciente de esto.
18
+ supabaseClient = createClient(config.SUPABASE_URL, config.SUPABASE_SERVICE_ROLE_KEY, {
19
+ auth: {
20
+ autoRefreshToken: false,
21
+ persistSession: false,
22
+ },
23
+ });
24
+ console.error(' Cliente Supabase API inicializado.');
25
+ return supabaseClient;
26
+ }