Authentication
Supabase
Connect Supabase OAuth, sign in from an MCP client, and use ctx.user in tools.
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:
- Open Authentication → Sign In / Providers → OAuth Server
- Enable the OAuth 2.1 server
- Enable Allow Dynamic OAuth Apps so MCP clients can register
- Set the consent URL to a route your app implements (for example
http://localhost:3000/auth/consent) - 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-idShared production vars (MCP_URL, BITMCP_STATE_KEY): see Installation → Environment variables.
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, notes: [] };
},
});Verify
- Run the server with
pnpm devorpnpm start - Connect from an OAuth-capable MCP client
- Complete Supabase login
- Call a tool and confirm
ctx.useris populated - Call
/mcpwithout a Bearer token and confirm401
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:
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(url, anonKey, {
global: { headers: { Authorization: `Bearer ${accessToken}` } },
});bitmcp does not put the raw token on ctx.user. Read it from your auth layer or scope queries 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;
})| Variable | When |
|---|---|
SUPABASE_PROJECT_ID | Default project id |
SUPABASE_URL | Local or self-hosted Supabase instead of projectId |
SUPABASE_JWT_SECRET | Legacy HS256 tokens (32+ bytes) |
MCP_URL and BITMCP_STATE_KEY: Installation → Environment variables.
ctx.user fields: id, email, name, fullName, username, avatarUrl, role, aal, amr, sessionId. Other providers expose the same base fields (id, email, name) plus provider-specific claims.
Options passed to the factory override environment variables.