Supabase MCP Server

repository·main·Indexed 25 days ago

https://github.com/supabase/mcp

Connect Supabase projects to AI assistants like Cursor, Claude, and Windsurf using the Model Context Protocol. Includes @supabase/mcp-server-postgrest for CRUD operations via REST API, @supabase/mcp-utils for StreamTransport connectivity, and @supabase/mcp-server-supabase for Vercel AI SDK integration. Features tools for managing tables, querying data, and handling a branching workflow for schema changes and migrations.

Tokens
18.7K
Snippets
30
Records
137
Agent score
84%

What's inside supabase-mcp

  1. Configure @supabase/mcp-server-postgrest with Claude Desktop

    main

    To use this server with Claude Desktop, add it to your mcpServers configuration file.

    Config File Locations:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json

    Configuration Options:

    • apiUrl: The base URL of your PostgREST endpoint (e.g., https://your-project-ref.supabase.co/rest/v1).
    • apiKey: Your API key for authentication (optional).
    • schema: The Postgres schema to serve the API from (e.g., public).
    {
      "mcpServers": {
        "todos": {
          "command": "npx",
          "args": [
            "-y",
            "@supabase/mcp-server-postgrest@latest",
            "--apiUrl",
            "https://your-project-ref.supabase.co/rest/v1",
            "--apiKey",
            "your-anon-key",
            "--schema",
            "public"
          ]
        }
      }
    }
  2. Configure the Supabase MCP server in an MCP client

    main

    To connect AI assistants like Cursor, Claude, or Windsurf to your Supabase projects, configure your MCP client using the HTTP transport. Most clients require a JSON configuration. You can also generate a custom MCP URL via the MCP connection tab in your Supabase dashboard.

    Cloud (Production): Use https://mcp.supabase.com/mcp.

    Local Development (Supabase CLI): If running Supabase locally, use http://localhost:54321/mcp. Note that the CLI version offers a limited subset of tools and does not support OAuth 2.1.

    Self-hosted: For Docker-based self-hosted environments, check the Supabase documentation for enabling the MCP server. These environments also offer a limited subset of tools and no OAuth 2.1.

    {
      "mcpServers": {
        "supabase": {
          "type": "http",
          "url": "https://mcp.supabase.com/mcp"
        }
      }
    }
  3. Manage development and production branches

    main

    The Supabase MCP server supports a branching workflow to safely experiment with schema changes. You can use a development branch to clone your production branch by applying the same migrations.

    Core Workflow Tools:

    • create_branch: Creates a development branch by cloning the production branch using migrations from list_migrations.
    • merge_branch: Merges a development branch into production by applying new migrations incrementally. If a merge fails, the status becomes MIGRATIONS_FAILED; use get_logs to diagnose.
    • rebase_branch: Synchronizes a development branch with production when production is ahead (e.g., after a hotfix or when multiple developers merge branches in different orders).
    • delete_branch: Deletes a development branch to save on resource costs ($0.01344 per hour per active branch).
    • reset_branch: An escape hatch to reset the development branch. It can reset to the latest migration (dropping untracked data) or to a specific migration version.
  4. Revert migrations on a development branch

    main

    If testing reveals issues, you can revert migrations on your development branch using the reset_branch tool.

    How to revert:

    1. Find the target version using list_migrations.
    2. Ask the LLM to reset to the last n migrations or a specific version number (e.g., 20250401000000).
    3. The tool will clear all untracked data and schema changes. Once complete, the status updates to FUNCTIONS_DEPLOYED.

    Important: To rollback a migration that has already been applied to production, do NOT use reset_branch. Instead, create a new migration that explicitly reverts the changes made by the prior migration to ensure the production history only moves forward.

  5. Create and apply migrations in a development branch

    main

    To build new features safely, use the apply_migration tool on your development branch. This tracks schema or data changes as migrations that can be replayed on production.

    Best Practices:

    • Avoid Hardcoded Foreign Keys: When inserting static data, do not hardcode foreign key references. Foreign keys are tied to the specific data in your development branch and will fail when applied to production.
    • Review Destructive Changes: When dropping columns or tables, manually review the generated SQL to ensure data loss is intentional.
    • Testing: After applying migrations, fetch your development branch credentials using get_project_url and get_publishable_keys to connect your app for testing.
  6. Use Supabase MCP tools effectively

    main

    The Supabase MCP server includes built-in instructions for AI agents to follow. Key guidelines include:

    • Schema Discovery: Before making schema changes, use list_tables to understand the existing structure.
    • Debugging: When debugging issues, start with get_logs and get_advisors before making changes.
    • Configuration: Use get_project_url and get_publishable_api_key when helping users configure client-side integrations.
    • Local Development: If you have a filesystem/shell, prefer using the Supabase CLI (supabase) and consider installing the Supabase agent skill via npx skills add supabase/agent-skills.
    • Remote Environments: In web-only environments without shell access, rely on MCP tools directly. Use apply_migration with caution as it affects the remote project immediately.
  7. Resolve migration merge failures

    main

    If merge_branch fails, the production branch status will be set to MIGRATIONS_FAILED. Follow these steps to recover:

    1. Use the get_logs tool to identify the exact error causing the failure.
    2. Reset the problematic migration on your development branch.
    3. Apply a new migration containing the fix on your development branch.
    4. Attempt to merge_branch again.

    Only successful migrations are tracked, so it is safe to attempt merging the same development branch multiple times after fixes.

  8. Use StreamTransport to connect MCP clients and servers

    main

    The StreamTransport utility allows you to connect an MCP client and an MCP server directly in-memory or over a custom stream-based transport. It implements a duplex stream interface using standard Web ReadableStream and WritableStream objects.

    To connect a client and server in-memory, create two StreamTransport instances and use pipeTo to connect the client's readable stream to the server's writable stream, and vice versa.

    import { Client } from '@modelcontextprotocol/sdk/client/index.js';
    import { StreamTransport } from '@supabase/mcp-utils';
    import { PostgrestMcpServer } from '@supabase/mcp-server-postgrest';
    
    // Create a stream transport for both client and server
    const clientTransport = new StreamTransport();
    const serverTransport = new StreamTransport();
    
    // Connect the streams together
    clientTransport.readable.pipeTo(serverTransport.writable);
    serverTransport.readable.pipeTo(clientTransport.writable);
    
    const client = new Client(
      {
        name: 'MyClient',
        version: '0.1.0',
      },
      {
        capabilities: {},
      }
    );
    
    const server = new PostgrestMcpServer({
      apiUrl: API_URL,
      schema: 'public',
    });
    
    // Connect the client and server to their respective transports
    await server.connect(serverTransport);
    await client.connect(clientTransport);
  9. Connect to @supabase/mcp-server-postgrest programmatically

    main

    If building a custom MCP client, you can use createPostgrestMcpServer from @supabase/mcp-server-postgrest. For in-memory connections or custom piping, use StreamTransport from @supabase/mcp-utils to connect the client and server transports.

    import { Client } from '@modelcontextprotocol/sdk/client/index.js';
    import { StreamTransport } from '@supabase/mcp-utils';
    import { createPostgrestMcpServer } from '@supabase/mcp-server-postgrest';
    
    // Create a stream transport for both client and server
    const clientTransport = new StreamTransport();
    const serverTransport = new StreamTransport();
    
    // Connect the streams together
    clientTransport.readable.pipeTo(serverTransport.writable);
    serverTransport.readable.pipeTo(clientTransport.writable);
    
    const client = new Client(
      {
        name: 'MyClient',
        version: '0.1.0',
      },
      {
        capabilities: {},
      }
    );
    
    const supabaseUrl = 'https://your-project-ref.supabase.co'; // http://127.0.0.1:54321 for local
    const apiKey = 'your-anon-key'; // or service role, or user JWT
    const schema = 'public'; // or any other exposed schema
    
    const server = createPostgrestMcpServer({
      apiUrl: `${supabaseUrl}/rest/v1`,
      apiKey,
      schema,
    });
    
    // Connect the client and server to their respective transports
    await server.connect(serverTransport);
    await client.connect(clientTransport);
    
    // Call tools, etc
    const output = await client.callTool({
      name: 'postgrestRequest',
      arguments: {
        method: 'GET',
        path: '/todos',
      },
    });
  10. Use Supabase MCP tools with Vercel AI SDK

    main

    The @supabase/mcp-server-supabase package provides createToolSchemas() to enable static tool usage with the Vercel AI SDK's MCP client. This provides client-side validation and inferred TypeScript types for tool inputs and outputs.

    To use it, initialize an MCPClient with the Supabase HTTP transport and pass the result of createToolSchemas() to the .tools() method.

    import { createToolSchemas } from '@supabase/mcp-server-supabase';
    import { createMCPClient } from '@ai-sdk/mcp';
    import { streamText } from 'ai';
    
    const mcpClient = await createMCPClient({
      transport: {
        type: 'http',
        url: 'https://mcp.supabase.com/mcp',
      },
    });
    
    const tools = await mcpClient.tools({
      schemas: createToolSchemas(),
    });
    
    const result = streamText({ model, tools, prompt: '...' });
    
    for (const step of await result.steps) {
      for (const toolResult of step.staticToolResults) {
        if (toolResult.toolName === 'get_project_url') {
          toolResult.input;  // { project_id: string }
          toolResult.output; // { url: string }
        }
      }
    }