Skip to main content
customProvider builds a complete OAuthConfig from an identity provider’s OAuth discovery document: it reads the provider’s metadata at boot and verifies access tokens against its JWKS. Reach for it when no branded provider fits, for any IdP that publishes discovery metadata and signs JWT access tokens.

Example

server.ts
import { McpServer, customProvider } from "skybridge/server";

const server = new McpServer(
  { name: "personal-shopper", version: "0.0.1" },
  { capabilities: {} },
  {
    oauth: await customProvider({
      issuer: "https://auth.myshop.com",
      audience: process.env.SERVER_URL,
      scopes: ["openid", "profile", "checkout"],
      requiredScopes: ["openid"],
    }),
  },
);
customProvider fetches https://auth.myshop.com’s discovery document at boot, then the oauth option mounts the well-known metadata and JWKS bearer verification on /mcp. audience is the value the IdP binds into the token’s aud claim, here this server’s public URL.

Signature

customProvider(opts: CustomProviderOptions): Promise<OAuthConfig>;

Parameters

opts

type CustomProviderOptions = {
  issuer: string;
  audience?: string;
  baseUrl?: string;
  serverUrl?: string;
  scopes?: string[];
  requiredScopes?: string[];
  metadataOverrides?: Omit<Partial<OAuthMetadata>, "issuer">;
};
FieldDescription
issuerThe only required option: the IdP base URL whose discovery document is fetched at boot. It must serve a jwks_uri, or the call throws.
audienceChecked against each token’s aud claim. Omit it only for an IdP that binds no audience (Clerk): the aud check is then skipped.
baseUrlThis server’s public URL. Set it and the resource URLs are baked once at boot; omit it and they resolve per request from the x-forwarded-host / x-forwarded-proto / host headers.
serverUrlAdvertises this server as the authorization server: the served AS metadata issuer and the PRM authorization_servers use this URL instead of the IdP’s, while verification still trusts the IdP’s real iss. Needed when this server must sit in the auth path, as auth0Provider does, or behind the Alpic DCR proxy.
scopesScopes advertised in the served metadata; defaults to the IdP’s.
requiredScopesServer-wide scope floor enforced before any handler, layered under each tool’s securitySchemes; a token missing one gets a 403.
metadataOverridesAdjusts advertised metadata only.

Returns

A Promise (discovery is a boot-time network call) for the OAuthConfig you pass to the oauth constructor option.
type OAuthConfig = {
  baseUrl?: string;
  oauthMetadata: OAuthMetadata;
  verify: { issuer: string; audience?: string; jwksUri?: string };
  scopesSupported?: string[];
  requiredScopes?: string[];
};
FieldDescription
baseUrlEchoes the baseUrl option.
oauthMetadataAS metadata served at /.well-known/oauth-authorization-server.
verifyJWKS token-verification config.
scopesSupportedScopes advertised in protected-resource metadata.
requiredScopesServer-wide required-scope floor.
Build this object by hand only to wire an IdP whose metadata customProvider can’t discover: supply verify.issuer and verify.jwksUri yourself and the oauth option mounts the same endpoints.

Connect an Identity Provider

Set up sign-in with a hosted provider

Authenticate Users

Add sign-in to your app end to end

McpServer

Pass the config to the oauth option