Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
DEPRECATED: Replaced by mcp-app-builder. Previously used to build ChatGPT apps with interactive React widgets via mcp-use.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/authentication/supabase.md
1# Supabase Authentication23Setting up OAuth with Supabase's OAuth 2.1 server. Supabase hosts `/authorize`, `/token`, `/register`, and `.well-known` discovery on your Supabase project — the MCP server only verifies the resulting JWTs.45**You host the consent UI.** Supabase redirects the browser to a URL you configure, and your route uses the Supabase JS SDK to load authorization details, render sign-in + consent, and submit the decision back to Supabase. mcp-use is not involved in that step — follow Supabase's [OAuth Server — Getting Started guide](https://supabase.com/docs/guides/auth/oauth-server/getting-started).67**Learn more:** [Supabase OAuth Server — MCP Authentication](https://supabase.com/docs/guides/auth/oauth-server/mcp-authentication) · [Standalone starter template](https://github.com/mcp-use/mcp-oauth-supabase-template) · [Runnable example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/supabase)89> This targets Supabase's **OAuth 2.1 server** — a different feature from Supabase Auth's social logins. Enable it explicitly in the dashboard under **Authentication → OAuth Server**.1011---1213## Quick Start1415```typescript16import { MCPServer, oauthSupabaseProvider, object } from "mcp-use/server";1718const server = new MCPServer({19name: "my-server",20version: "1.0.0",21oauth: oauthSupabaseProvider(),22});2324server.tool(25{ name: "whoami", description: "Get authenticated user info" },26async (_args, ctx) =>27object({28userId: ctx.auth.user.userId,29email: ctx.auth.user.email,30})31);3233server.listen();34```3536With a `.env` file:3738```bash39MCP_USE_OAUTH_SUPABASE_PROJECT_ID=your-project-id40MCP_USE_OAUTH_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...41```4243JWT verification and `.well-known` passthrough are automatic. You still need to mount your own consent route (see [Hosting the consent UI](#hosting-the-consent-ui) below).4445---4647## Setup48491. Create (or select) a project in the [Supabase Dashboard](https://app.supabase.com/). Copy the **Project ID** from **Project Settings → General**.502. **Authentication → OAuth Server** — enable the OAuth 2.1 server and set the **consent screen URL** to the route your MCP server will host (e.g. `http://localhost:3000/auth/consent`). Supabase appends `?authorization_id=<uuid>` when redirecting users there.513. **Authentication → Sign In / Providers** — enable at least one sign-in method so users can authenticate before consenting:52- **Anonymous sign-ins** — one-click guest sessions, ideal for demos53- **Email + password**, **magic links**, or **OAuth providers** (Google, GitHub, etc.) — for real apps544. Copy the **publishable key** (`sb_publishable_...`) from **Project Settings → API Keys**. You'll use it in the consent UI and in any tool that calls Supabase REST APIs.5556---5758## Environment Variables5960| Variable | Required | Description |61|----------|----------|-------------|62| `MCP_USE_OAUTH_SUPABASE_PROJECT_ID` | Yes | Your Supabase project ID |63| `MCP_USE_OAUTH_SUPABASE_PUBLISHABLE_KEY` | Recommended | Publishable key (`sb_publishable_...`) — used by the consent UI and any tools calling Supabase REST/APIs |64| `MCP_USE_OAUTH_SUPABASE_JWT_SECRET` | Only for legacy HS256 projects | JWT secret for HS256 verification |6566> New Supabase projects issue `sb_publishable_...` keys. Legacy projects using `anon` JWT keys still work, but prefer publishable keys going forward.6768### Finding Your Credentials6970- **Project ID**: Project Settings → **General** → Reference ID71- **Publishable key**: Project Settings → **API Keys**72- **JWT Secret** (legacy HS256 only): Project Settings → **JWT Settings** (Legacy)7374---7576## Configuration Options7778Zero-config (reads from env vars):7980```typescript81oauth: oauthSupabaseProvider()82```8384Explicit config (overrides env vars):8586```typescript87oauth: oauthSupabaseProvider({88projectId: "my-project-id",89jwtSecret: process.env.MCP_USE_OAUTH_SUPABASE_JWT_SECRET, // legacy HS256 only90verifyJwt: process.env.NODE_ENV === "production",91scopesSupported: ["openid", "profile", "email"],92})93```9495| Option | Type | Default | Description |96|--------|------|---------|-------------|97| `projectId` | `string` | env var | Supabase project ID |98| `jwtSecret` | `string?` | env var | JWT secret for HS256 tokens (legacy projects) |99| `verifyJwt` | `boolean?` | `true` | Set `false` to skip JWT verification (**development only**) |100| `scopesSupported` | `string[]?` | `["openid", "profile", "email"]` | Override advertised scopes |101102---103104## JWT Signing: ES256 vs HS256105106The provider auto-detects the algorithm from the token header.107108- **ES256 (new projects)** — asymmetric signing via elliptic curve keys. The provider fetches the JWKS endpoint automatically. No `jwtSecret` needed.109- **HS256 (legacy projects)** — symmetric signing via a shared secret. Provide `MCP_USE_OAUTH_SUPABASE_JWT_SECRET` or `jwtSecret` in config.110111---112113## Hosting the consent UI114115Supabase redirects the browser to the consent screen URL you configured. Your route must:1161171. Sign the user in if they aren't already (anonymous, magic link, OAuth, etc. — whatever you enabled)1182. Use the Supabase JS SDK to load the authorization details for `authorization_id`1193. Render approve/deny UI1204. Submit the decision back to Supabase and redirect to the resulting URL121122Follow Supabase's [OAuth Server — Getting Started guide](https://supabase.com/docs/guides/auth/oauth-server/getting-started) for the canonical implementation. See the [runnable example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/supabase) for a wired-up version (look at `auth-routes.ts`).123124---125126## User Context127128Supabase populates these fields on `ctx.auth.user`:129130| Field | Type | Source |131|-------|------|--------|132| `userId` | `string` | `sub` or `user_id` claim |133| `email` | `string?` | `email` claim |134| `name` | `string?` | `user_metadata.name` or `user_metadata.full_name` |135| `username` | `string?` | `user_metadata.username` |136| `picture` | `string?` | `user_metadata.avatar_url` |137| `roles` | `string[]?` | `role` claim (e.g. `["authenticated"]`) |138| `permissions` | `string[]?` | Derived from AAL (e.g. `["aal:aal1"]`) |139| `aal` | `string?` | Authentication Assurance Level |140| `amr` | `array?` | Authentication Methods References |141| `session_id` | `string?` | Supabase session ID |142143---144145## Making Supabase API Calls146147Create a Supabase client scoped to the request using the user's access token so Row Level Security (RLS) policies see the caller as the authenticated user:148149```typescript150import { createClient } from "@supabase/supabase-js";151152server.tool(153{ name: "list-notes", description: "Fetch the user's notes" },154async (_args, ctx) => {155const supabase = createClient(156`https://${process.env.MCP_USE_OAUTH_SUPABASE_PROJECT_ID}.supabase.co`,157process.env.MCP_USE_OAUTH_SUPABASE_PUBLISHABLE_KEY!,158{159auth: {160persistSession: false,161autoRefreshToken: false,162detectSessionInUrl: false,163},164global: {165headers: { Authorization: `Bearer ${ctx.auth.accessToken}` },166},167}168);169170const { data, error: queryError } = await supabase.from("notes").select();171if (queryError) return error(`Failed to fetch notes: ${queryError.message}`);172173return object({ notes: data ?? [] });174}175);176```177178**Key point:** The `Authorization` header uses the user's access token (for RLS); the publishable key is passed to `createClient` for SDK/API access.179180---181182## Example `.env`183184```bash185# Required: Supabase project ID (Dashboard → Project Settings → General)186MCP_USE_OAUTH_SUPABASE_PROJECT_ID=your-project-id187188# Recommended: Publishable key (Dashboard → Project Settings → API Keys)189# Used by the consent UI and by tools calling Supabase REST/APIs190MCP_USE_OAUTH_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...191192# Legacy HS256 projects only (Dashboard → Project Settings → JWT Settings)193# New projects use ES256 + JWKS — leave this unset194# MCP_USE_OAUTH_SUPABASE_JWT_SECRET=your-jwt-secret195```196197---198199## Next Steps200201- **Auth overview** → [overview.md](overview.md)202- **WorkOS setup** → [workos.md](workos.md)203- **Auth0 setup** → [auth0.md](auth0.md)204- **Build tools** → [../server/tools.md](../server/tools.md)205