Skip to main content
Glama
MisterSandFR

Supabase MCP Server - Self-Hosted Edition

by MisterSandFR
server.py8.71 kB
#!/usr/bin/env python3 """ Supabase MCP Server (FastMCP + Smithery) """ from typing import Optional import os from pydantic import BaseModel, Field from mcp.server.fastmcp import Context, FastMCP from smithery.decorators import smithery class ConfigSchema(BaseModel): SUPABASE_URL: str = Field("", description="URL de votre projet Supabase") SUPABASE_ANON_KEY: str = Field("", description="Clé anonyme Supabase") SUPABASE_SERVICE_ROLE_KEY: Optional[str] = Field(None, description="Clé service (optionnel)") SUPABASE_AUTH_JWT_SECRET: Optional[str] = Field(None, description="JWT secret (optionnel)") @smithery.server(config_schema=ConfigSchema) def create_server() -> FastMCP: server = FastMCP("Supabase MCP Server") def effective_config(ctx: Context): cfg = ctx.session_config supabase_url = getattr(cfg, "SUPABASE_URL", None) or os.getenv("SUPABASE_URL", "") anon_key = getattr(cfg, "SUPABASE_ANON_KEY", None) or os.getenv("SUPABASE_ANON_KEY", "") service_key = getattr(cfg, "SUPABASE_SERVICE_ROLE_KEY", None) or os.getenv("SUPABASE_SERVICE_ROLE_KEY", "") jwt_secret = getattr(cfg, "SUPABASE_AUTH_JWT_SECRET", None) or os.getenv("SUPABASE_AUTH_JWT_SECRET", "") return supabase_url, anon_key, service_key, jwt_secret @server.tool() def execute_sql(sql: str, ctx: Context) -> str: supabase_url, anon_key, _, _ = effective_config(ctx) if not supabase_url or not anon_key: return "Configuration Supabase manquante (SUPABASE_URL, SUPABASE_ANON_KEY)." return f"SQL reçu ({len(sql)} chars). Connexion prête pour {supabase_url}." @server.tool() def list_tables(ctx: Context) -> str: supabase_url, _, _, _ = effective_config(ctx) if not supabase_url: return "Configuration Supabase manquante." return "Tables listées (démo)." @server.tool() def check_health(ctx: Context) -> str: supabase_url, _, _, _ = effective_config(ctx) if not supabase_url: return "Configuration Supabase manquante." return "OK" # --- Database / Extensions / Stats --- @server.tool() def list_extensions(ctx: Context) -> str: cfg = ctx.session_config if not cfg.SUPABASE_URL: return "Configuration Supabase manquante." return "Extensions listées (démo)." @server.tool() def get_database_stats(ctx: Context) -> str: return "Stats DB (démo)." @server.tool() def get_database_connections(ctx: Context) -> str: return "Connexions DB (démo)." @server.tool() def apply_migration(version: str, ctx: Context) -> str: return f"Migration appliquée: {version} (démo)." @server.tool() def list_migrations(ctx: Context) -> str: return "Migrations listées (démo)." @server.tool() def create_migration(name: str, ctx: Context) -> str: return f"Migration créée: {name} (démo)." @server.tool() def validate_migration(version: str, ctx: Context) -> str: return f"Migration validée: {version} (démo)." @server.tool() def push_migrations(ctx: Context) -> str: return "Migrations poussées (démo)." @server.tool() def smart_migration(ctx: Context) -> str: return "Migration intelligente (démo)." @server.tool() def auto_migrate(ctx: Context) -> str: return "Auto-migrate (démo)." @server.tool() def sync_schema(ctx: Context) -> str: return "Schéma synchronisé (démo)." @server.tool() def inspect_schema(ctx: Context) -> str: return "Schéma inspecté (démo)." @server.tool() def import_schema(sql: str, ctx: Context) -> str: return "Schéma importé (démo)." @server.tool() def execute_psql(command: str, ctx: Context) -> str: return f"psql exécuté: {command[:80]} (démo)." @server.tool() def auto_create_indexes(ctx: Context) -> str: return "Index auto-créés (démo)." @server.tool() def vacuum_analyze(ctx: Context) -> str: return "VACUUM ANALYZE (démo)." # --- Types & Codegen --- @server.tool() def generate_typescript_types(ctx: Context) -> str: return "Types TypeScript générés (démo)." @server.tool() def generate_crud_api(ctx: Context) -> str: return "API CRUD générée (démo)." # --- Logs & Docs & Monitoring --- @server.tool() def get_logs(service: Optional[str] = None, ctx: Context = None) -> str: return f"Logs récupérés (service={service}) (démo)." @server.tool() def search_docs(query: str, ctx: Context) -> str: return f"Recherche docs: {query[:60]} (démo)." @server.tool() def metrics_dashboard(ctx: Context) -> str: return "Dashboard métriques (démo)." @server.tool() def analyze_performance(ctx: Context) -> str: return "Analyse performance (démo)." @server.tool() def analyze_rls_coverage(ctx: Context) -> str: return "Couverture RLS (démo)." @server.tool() def audit_security(ctx: Context) -> str: return "Audit sécurité (démo)." # --- Auth --- @server.tool() def list_auth_users(ctx: Context) -> str: return "Utilisateurs auth listés (démo)." @server.tool() def get_auth_user(id: Optional[str] = None, email: Optional[str] = None, ctx: Context = None) -> str: return f"Auth user récupéré (id={id}, email={email}) (démo)." @server.tool() def create_auth_user(email: str, password: str, ctx: Context) -> str: return f"Utilisateur créé: {email} (démo)." @server.tool() def delete_auth_user(id: str, ctx: Context) -> str: return f"Utilisateur supprimé: {id} (démo)." @server.tool() def update_auth_user(id: str, ctx: Context) -> str: return f"Utilisateur mis à jour: {id} (démo)." @server.tool() def manage_roles(ctx: Context) -> str: return "Rôles gérés (démo)." @server.tool() def manage_rls_policies(ctx: Context) -> str: return "Politiques RLS gérées (démo)." @server.tool() def verify_jwt_secret(ctx: Context) -> str: return "JWT secret présent (démo)." # --- Storage --- @server.tool() def list_storage_buckets(ctx: Context) -> str: return "Buckets listés (démo)." @server.tool() def list_storage_objects(bucket_id: str, ctx: Context) -> str: return f"Objets listés pour bucket={bucket_id} (démo)." @server.tool() def manage_storage_policies(ctx: Context) -> str: return "Politiques Storage gérées (démo)." # --- Realtime --- @server.tool() def list_realtime_publications(ctx: Context) -> str: return "Publications realtime listées (démo)." @server.tool() def manage_realtime(ctx: Context) -> str: return "Realtime géré (démo)." @server.tool() def create_subscription(channel: str, ctx: Context) -> str: return f"Subscription créée: {channel} (démo)." @server.tool() def delete_subscription(channel: str, ctx: Context) -> str: return f"Subscription supprimée: {channel} (démo)." # --- Admin / Secrets / Webhooks / Triggers / Functions --- @server.tool() def manage_extensions(ctx: Context) -> str: return "Extensions gérées (démo)." @server.tool() def manage_functions(ctx: Context) -> str: return "Fonctions gérées (démo)." @server.tool() def manage_triggers(ctx: Context) -> str: return "Triggers gérés (démo)." @server.tool() def manage_webhooks(ctx: Context) -> str: return "Webhooks gérés (démo)." @server.tool() def rebuild_hooks(ctx: Context) -> str: return "Hooks reconstruits (démo)." @server.tool() def manage_secrets(ctx: Context) -> str: return "Secrets gérés (démo)." # --- Divers utilitaires --- @server.tool() def cache_management(ctx: Context) -> str: return "Cache géré (démo)." @server.tool() def environment_management(ctx: Context) -> str: return "Environnement géré (démo)." @server.tool() def get_project_url(ctx: Context) -> str: return "URL projet (démo)." @server.tool() def get_anon_key(ctx: Context) -> str: return "Anon key (démo)." @server.tool() def get_service_key(ctx: Context) -> str: return "Service key (démo)." return server if __name__ == "__main__": srv = create_server() print("Serveur FastMCP prêt (Smithery). Outils:", list(srv._tools.keys()))

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MisterSandFR/Supabase-MCP-SelfHosted'

If you have feedback or need assistance with the MCP directory API, please join our Discord server