Skip to main content
Glama
dedalus-labs

Supabase MCP Server

by dedalus-labs
README.md
# Supabase MCP Server

A Supabase MCP server built with the [Dedalus MCP framework](https://dedaluslabs.ai). Provides secure access to Supabase databases via the PostgREST API with credential encryption and JIT token exchange.

## Features

### Available Tools

#### Read Operations

| Tool | Description |
|------|-------------|
| `db_select` | Select rows from a table with optional filters, ordering, and pagination |
| `db_get_by_id` | Get a single row by primary key |

#### Write Operations

| Tool | Description |
|------|-------------|
| `db_insert` | Insert one or more rows into a table |
| `db_update` | Update rows matching specified filters |
| `db_delete` | Delete rows matching specified filters |
| `db_upsert` | Insert or update rows on conflict |

#### RPC

| Tool | Description |
|------|-------------|
| `db_rpc` | Call a Supabase stored procedure/function |

## Prerequisites

- Python 3.10+
- [uv](https://docs.astral.sh/uv/) package manager
- Supabase project URL and API key
- Dedalus API Key

## Setup

1. **Clone the repository**

```bash
git clone https://github.com/dedalus-labs/supabase-mcp.git
cd supabase-mcp
```

2. **Install dependencies**

```bash
uv sync
```

3. **Configure environment variables**

Create a `.env` file based on .env.example.

## Client Usage

```python
import asyncio
import os

from dotenv import load_dotenv
from dedalus_labs import AsyncDedalus, DedalusRunner
from dedalus_mcp.auth import Connection, SecretKeys, SecretValues

load_dotenv()

SUPABASE_URL = os.getenv("SUPABASE_URL")

# Define the Supabase connection
supabase = Connection(
    name="supabase-mcp",
    secrets=SecretKeys(key="SUPABASE_SECRET_KEY"),
    base_url=f"{SUPABASE_URL}/rest/v1",
    auth_header_name="apikey",
    auth_header_format="{api_key}",
)

# Bind credentials (encrypted client-side, decrypted at dispatch time)
supabase_secrets = SecretValues(supabase, key=os.getenv("SUPABASE_SECRET_KEY", ""))

async def main():
    client = AsyncDedalus(
        api_key=os.getenv("DEDALUS_API_KEY"),
        base_url=os.getenv("DEDALUS_API_URL"),
        as_base_url=os.getenv("DEDALUS_AS_URL"),
    )
    runner = DedalusRunner(client)

    result = await runner.run(
        input="Select all rows from the users table, limit to 5.",
        model="openai/gpt-5",
        mcp_servers=["issac/supabase-mcp"],
        credentials=[supabase_secrets],
    )

    print(result.output)

if __name__ == "__main__":
    asyncio.run(main())
```

## License

MIT License - see [LICENSE](LICENSE) for details.