Authentication
Custom
Wire any OAuth authorization server with custom() or jwtOAuthProvider().
Use a custom provider when your identity provider is not covered by a built-in plugin, you need token introspection instead of JWT verification, or claim mapping differs from the defaults.
Choose an integration style
- JWT providers — use
jwtOAuthProvider()with issuer, JWKS, andmapUser - Non-standard verification — use
custom()withcreateTokenVerifier
Set environment variables
Tokens must target your MCP server. Set MCP_URL to your public MCP endpoint. See Installation → Environment variables.
Configure bitmcp
JWT identity providers:
import { defineConfig } from "bitmcp";
import { jwtOAuthProvider } from "bitmcp/oauth";
export default defineConfig({
auth: jwtOAuthProvider({
name: "my-provider",
resolveIssuer: () => "https://auth.example.com",
jwksUrl: (issuer) => new URL(`${issuer}/.well-known/jwks.json`),
oauthMetadata: (issuer) => ({
issuer,
authorization_endpoint: `${issuer}/oauth/authorize`,
token_endpoint: `${issuer}/oauth/token`,
registration_endpoint: `${issuer}/oauth/register`,
response_types_supported: ["code"],
grant_types_supported: ["authorization_code", "refresh_token"],
code_challenge_methods_supported: ["S256"],
}),
mapUser: (payload) => ({
id: String(payload.sub),
email: typeof payload.email === "string" ? payload.email : undefined,
}),
audience: "https://mcp.example.com/mcp",
}),
});Full control with custom():
import { custom, createJwtVerifier } from "bitmcp/oauth";
auth: custom({
createTokenVerifier: (resource) =>
createJwtVerifier({
issuer: "https://auth.example.com",
jwksUrl: new URL("https://auth.example.com/.well-known/jwks.json"),
resource,
audience: resource.href,
}),
oauthMetadata: {
issuer: "https://auth.example.com",
authorization_endpoint: "https://auth.example.com/oauth/authorize",
token_endpoint: "https://auth.example.com/oauth/token",
response_types_supported: ["code"],
},
mapUser: (authInfo) => ({
id: String(authInfo.extra?.payload?.sub ?? authInfo.clientId),
}),
});Verify
- Start the server with
pnpm devorpnpm start - Connect from an OAuth-capable MCP client
- Complete login through your provider
- Call a tool and confirm
ctx.useris populated - Call
/mcpwithout a token and confirm401
OAuth requires HTTP. app.stdio() throws when auth is set.
Options
custom(options: {
createTokenVerifier: (resource: URL) => OAuthTokenVerifier;
oauthMetadata: OAuthMetadata;
mapUser: (authInfo: AuthInfo) => BitmcpUser;
resource?: URL | string;
requiredScopes?: string[];
scopesSupported?: string[];
resourceName?: string;
})Options passed to a factory override environment variables. Shared vars: Installation → Environment variables.