Supabase

Supabase OAuth 2.1 server authentication for bitmcp.

Use this when Supabase Auth is your authorization server. Supabase handles login, consent, client registration, and token issuance. bitmcp verifies access tokens and maps claims to ctx.user.

Enable Supabase OAuth

In the Supabase dashboard:

  1. Open Authentication → Sign In / Providers → OAuth Server
  2. Enable the OAuth 2.1 server
  3. Enable Allow Dynamic OAuth Apps so MCP clients can register
  4. Set the consent URL to a route your app implements (for example http://localhost:3000/auth/consent)
  5. Enable at least one sign-in method

Copy your Project ID (or full project URL for local/self-hosted Supabase).

Set environment variables

SUPABASE_PROJECT_ID=your-project-id
MCP_URL=https://mcp.example.com/mcp
BITMCP_STATE_KEY=...

Set MCP_URL to your public MCP endpoint in production. Set BITMCP_STATE_KEY if you use confirm or ctx.ask.

Configure bitmcp

import { defineConfig } from "bitmcp";
import { supabase } from "bitmcp/oauth/supabase";

export default defineConfig({
  name: "notes",
  http: {
    path: "/mcp",
    allowedHosts: ["mcp.example.com"],
  },
  auth: supabase(),
});

Or pass options explicitly:

auth: supabase({
  projectId: process.env.SUPABASE_PROJECT_ID!,
  supabaseUrl: "http://127.0.0.1:54321",
}),

Use ctx.user in tools

export default defineTool({
  description: "List notes for the signed-in user",
  async execute(_input, ctx) {
    const userId = ctx.user!.id;
    return { userId };
  },
});

ctx.user includes id, email, name, and other Supabase claims when present in the token.

Verify

Run the server and connect with an OAuth-capable MCP client. Confirm the client discovers OAuth metadata, login completes through Supabase, authenticated tool calls include ctx.user, and requests without a Bearer token return 401.

Row Level Security

To query Supabase as the authenticated user, create a Supabase client in your tool using the access token from the MCP session. bitmcp does not put the raw token on ctx.user; read it from your auth layer or pass data scoped by ctx.user.id in application code.

For server-owned operations, use the Supabase service role outside the user context.

Options

supabase(options?: {
  projectId?: string;
  supabaseUrl?: URL | string;
  jwtSecret?: string;
  audience?: string;
  resource?: URL | string;
  requiredScopes?: string[];
  scopesSupported?: string[];
  resourceName?: string;
})
VariableWhen
SUPABASE_PROJECT_IDDefault project id
SUPABASE_URLLocal or self-hosted Supabase instead of projectId
SUPABASE_JWT_SECRETLegacy HS256 tokens (32+ bytes)
MCP_URLCanonical public MCP URL in production

ctx.user fields: id, email, name, fullName, username, avatarUrl, role, aal, amr, sessionId. Options passed to the factory override environment variables.