> ## Documentation Index
> Fetch the complete documentation index at: https://docs.routemcp.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Supabase

> Connect a Supabase account with OAuth and ask questions in plain English over your project's database. RouteMCP introspects the schema and runs read-only analytics queries on your behalf — 3 tools, OAuth auth, with automatic redaction of sensitive and encrypted data.

<img src="https://icon.horse/icon/supabase.com" alt="Supabase" style={{ width: "48px", height: "48px", marginBottom: "16px" }} />

## Overview

| Property   | Value                                               |
| ---------- | --------------------------------------------------- |
| Slug       | `supabase`                                          |
| Category   | Database                                            |
| Auth       | OAuth 2.0 (Supabase Management API)                 |
| Connection | Account-level OAuth grant, tokens encrypted at rest |
| Tool count | 3                                                   |
| Access     | **Read-only** (SELECT / WITH only)                  |

## Tool catalogue

Supabase exposes three tools — one to choose a project and two native SQL tools. In router mode the model discovers them with `SEARCH_TOOLS` and never needs you to bind a fixed resource ahead of time.

| Slug                       | Purpose                                                                                                                                                                                                                                                              |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SUPABASE_LIST_PROJECTS`   | Lists the connected account's projects (name, region, status, ref) so a project can be chosen to query.                                                                                                                                                              |
| `SUPABASE_DESCRIBE_SCHEMA` | Returns the project's tables, columns (with types), primary keys, and relationships. The model calls this first so it uses exact identifiers. Covers the public (application) schema only, and uses the connected project automatically when only one is accessible. |
| `SUPABASE_RUN_QUERY`       | Executes a single read-only SQL statement (SELECT / WITH) and returns rows. DDL/DML is rejected, a row limit is applied automatically, and the query runs as Supabase's `supabase_read_only_user` role.                                                              |

## Connect setup

Unlike the connection-string PostgreSQL connector, Supabase connects with **OAuth 2.0** — a redirect-and-consent flow, no connection string. When the agent needs Supabase and it isn't connected yet, it surfaces a **Connect** action; the user authorizes their Supabase account in a popup.

<Steps>
  <Step title="Open the connect popup">
    In the playground (or wherever a connect link is surfaced), click **Connect Supabase** to open Supabase's authorize screen. The OAuth App is registered once in the Supabase dashboard (**Organization settings → OAuth Apps**) with this callback URL:

    ```
    https://api.routemcp.io/api/v1/connect/oauth/callback
    ```
  </Step>

  <Step title="Authorize and validate">
    Sign in to Supabase and approve access (Database read + Projects read). On return, RouteMCP validates the grant and marks the connection **active**. If authorization fails, the popup returns an error and nothing is stored.
  </Step>

  <Step title="Stored encrypted">
    OAuth access and refresh tokens are encrypted at rest (AES-256-GCM) and refreshed automatically. Only read-only queries are ever issued against the connection. Use **Disconnect** to remove it.
  </Step>
</Steps>

<Note>
  For least privilege, grant only the **Database (read)** and **Projects (read)** scopes on your Supabase OAuth App. RouteMCP also enforces read-only at query time and runs every query as Supabase's `supabase_read_only_user` role, but minimal scopes are the strongest guarantee.
</Note>

## Usage

### Through the chat endpoint (recommended)

```bash theme={null}
curl -N -X POST "https://api.routemcp.io/api/v1/mcp/<workspace_id>/chat" \
  -H "x-api-key: sk_live_your_key" \
  -H "x-session-id: user-42" \
  -H "content-type: application/json" \
  -d '{"message": "How many users signed up this week?"}'
```

The agent calls `SUPABASE_DESCRIBE_SCHEMA` to learn the shape, writes a query such as `SELECT count(*) FROM "users" WHERE created_at >= date_trunc('week', now())`, runs it via `SUPABASE_RUN_QUERY`, and streams back a plain-language answer. The generated SQL is visible in the tool-call trace but never shown in the chat reply.

### Direct MCP JSON-RPC (Claude Desktop / Cursor / custom MCP clients)

```json theme={null}
{
  "mcpServers": {
    "routemcp": {
      "url": "https://api.routemcp.io/api/v1/mcp/<workspace_id>",
      "headers": {
        "x-api-key": "<YOUR_API_KEY>",
        "x-session-id": "<SESSION_ID>"
      }
    }
  }
}
```

## Data handling & security

Supabase reuses the same read-only guardrails as the PostgreSQL connector, applied automatically — you don't configure anything.

* **Read-only only.** `SUPABASE_RUN_QUERY` accepts a single `SELECT`/`WITH` statement. `INSERT`, `UPDATE`, `DELETE`, DDL, multi-statement input, and dangerous functions are rejected, and queries execute as Supabase's `supabase_read_only_user` role so writes are blocked at the database level too. The assistant will not offer or attempt writes (no "force password reset", "rotate credentials", etc.) — it can only read and analyze.
* **Application schema only.** Introspection and queries target your project's public (application) schema. Supabase-internal schemas (`auth`, `storage`, `realtime`, `vault`) are excluded — a "users" question counts your own table, not `auth.users`, unless you explicitly ask about login accounts.
* **Sensitive columns are redacted.** Columns whose names indicate secrets — `password`, `password_hash`, `secret`, `api_key`, `token`, `private_key`, `ssn`, `cvv`, `card_number`, and similar — are returned as `[restricted]` and are marked restricted in the schema, regardless of how the query selects them or of Row Level Security (which the read-only role may bypass).
* **Encrypted data is detected.** When a column's values look encrypted or hashed (bcrypt/argon prefixes, high-entropy base64/hex, `iv:ciphertext:tag`), they are returned as `[encrypted]` and the assistant tells you the data is encrypted at rest rather than presenting unreadable values.

<Note>
  Row results are capped (default 1000 rows) and queries run under a statement timeout. Ask for a `count(*)` or an aggregate when you want totals rather than every row.
</Note>
