0

Supabase Authentication

awesome-llm-appsauthentication

Setting up OAuth with Supabase.

Sign in to save downloads to your library and vote.

Preview

Supabase Authentication

Setting up OAuth with Supabase.

Learn more: Supabase MCP Authentication


Quick Start

import { MCPServer, oauthSupabaseProvider, object } from "mcp-use/server";

const server = new MCPServer({
  name: "my-server",
  version: "1.0.0",
  oauth: oauthSupabaseProvider(),
});

server.tool(
  { name: "whoami", description: "Get authenticated user info" },
  async (_args, ctx) =>
    object({
      userId: ctx.auth.user.userId,
      email: ctx.auth.user.email,
    }),
);

server.listen();

With a .env file:

MCP_USE_OAUTH_SUPABASE_PROJECT_ID=your-project-id

JWT verification, OAuth discovery, and token proxying are handled automatically.


Environment Variables

VariableRequiredDescription
MCP_USE_OAUTH_SUPABASE_PROJECT_IDYesYour Supabase project ID
MCP_USE_OAUTH_SUPABASE_JWT_SECRETNoJWT secret for HS256 token verification

NEXT_PUBLIC_SUPABASE_ANON_KEY is not read by the SDK. It's a user-defined env var you'll need if your tools make Supabase REST API calls (see Making Supabase API Calls).

Finding Your Credentials

  • Project ID: Supabase Dashboard → Project Settings → General → Reference ID
  • JWT Secret: Supabase Dashboard → Project Settings → JWT Settings (Legacy section)
  • Anon Key: Supabase Dashboard → Project Settings → API Keys

Configuration Options

Zero-config (reads from env vars):

oauth: oauthSupabaseProvider();

Explicit config (overrides env vars):

oauth: oauthSupabaseProvider({
  projectId: "my-project-id",
  jwtSecret: process.env.SUPABASE_JWT_SECRET,
  skipVerification: false,
});
OptionTypeDefaultDescription
projectIdstringenv varSupabase project ID
jwtSecretstring?env varJWT secret for HS256 tokens
skipVerificationboolean?falseSkip JWT verification (development only)

JWT Signing: HS256 vs ES256

Supabase supports two JWT signing algorithms:

ES256 (Newer Projects)

Asymmetric signing using elliptic curve keys. Tokens are verified via Supabase's JWKS endpoint automatically. No jwtSecret needed.

HS256 (Legacy Projects)

Symmetric signing using a shared secret. You must provide MCP_USE_OAUTH_SUPABASE_JWT_SECRET for verification.

The provider auto-detects the algorithm from the token header. If your project uses HS256, make sure the JWT secret is configured. If it uses ES256, you can omit it.


User Context

Supabase populates these fields on ctx.auth.user:

FieldTypeSource
userIdstringsub or user_id claim
emailstring?email claim
namestring?user_metadata.name or user_metadata.full_name
usernamestring?user_metadata.username
picturestring?user_metadata.avatar_url
rolesstring[]role claim (e.g., ["authenticated"])
permissionsstring[]Derived from AAL (e.g., ["aal:aal1"])
aalstring?Authentication Assurance Level
amrarray?Authentication Methods References
session_idstring?Supabase session ID

Making Supabase API Calls

Use ctx.auth.accessToken as the bearer token for Supabase REST API calls. This ensures Row Level Security (RLS) policies apply to the authenticated user:

const SUPABASE_ANON_KEY = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

server.tool(
  { name: "get-notes", description: "Fetch user's notes from Supabase" },
  async (_args, ctx) => {
    const projectId = process.env.MCP_USE_OAUTH_SUPABASE_PROJECT_ID;

    if (!projectId || !SUPABASE_ANON_KEY) {
      return error("Supabase credentials not configured");
    }

    const res = await fetch(`https://${projectId}.supabase.co/rest/v1/notes`, {
      headers: {
        Authorization: `Bearer ${ctx.auth.accessToken}`,
        apikey: SUPABASE_ANON_KEY,
      },
    });

    if (!res.ok) {
      return error(`Supabase API failed: ${res.status}`);
    }

    return object(await res.json());
  },
);

Key point: The Authorization header uses the user's access token (for RLS), while the apikey header uses the anon key (for API access).


Example .env

# Required: Supabase project ID (Dashboard → Project Settings → General)
MCP_USE_OAUTH_SUPABASE_PROJECT_ID=your-project-id

# Optional: JWT secret for HS256 verification (Dashboard → Project Settings → JWT Settings)
MCP_USE_OAUTH_SUPABASE_JWT_SECRET=your-jwt-secret

# Optional: Anon key for Supabase REST API calls (Dashboard → Project Settings → API Keys)
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

Next Steps

Ingestion metadata

Source catalog
awesome-llm-apps
File path
generative_ui_agents/ai-mcp-app-builder/apps/mcp-use-server/.agent/skills/mcp-apps-builder/references/authentication/supabase.md
Last refreshed
10/24/2026, 3:00:14 AM (5h ago)
Refresh schedule
Daily · 03:00 UTC
Dedupe status
Unique · deduped by (source, url)