Skip to main content
FrontMCP’s four authentication modes address different deployment scenarios. Understanding when to use each mode is critical for both security and developer experience.

Mode Overview

The auth.mode literal accepts one of four values: 'public', 'transparent', 'local', 'remote'.

Mode Comparison

FeaturePublicTransparentLocalRemote
Token RequiredNoYes (external)Yes (FrontMCP-issued)Yes (FrontMCP-issued)
User IdentityAnonymousFrom upstream IdPFrom login formFrom upstream IdP
Token SigningHS256 (symmetric)Upstream IdPHS256 (symmetric, JWT_SECRET)HS256 (symmetric, JWT_SECRET)
Session ManagementMinimalPass-throughFull controlFull control
Multi-providerNoSingle providerMultiple via appsMultiple via apps
Progressive AuthNoNoYesYes
Tool-authz enforcementNoNoOptionalOptional

Public Mode

No authentication required. All requests receive an anonymous session.
const auth: AuthOptionsInput = {
  mode: 'public',
  sessionTtl: 3600, // 1 hour
  anonymousScopes: ['anonymous'],
};

How It Works

Configuration Options

OptionTypeDefaultDescription
sessionTtlnumber3600Session lifetime in seconds
anonymousScopesstring[]['anonymous']Scopes assigned to anonymous sessions
publicAccess.toolsstring[] | 'all''all'Tools accessible without auth
publicAccess.promptsstring[] | 'all''all'Prompts accessible without auth
publicAccess.rateLimitnumber60Rate limit per IP per minute

Use Cases

Development

Rapid prototyping without auth setup overhead

Public APIs

Endpoints that don’t require user identity
Do NOT use public mode when you need:
  • User identity tracking
  • Audit trails
  • Access control per user
  • Compliance requirements

Transparent Mode

Pass-through tokens from an external identity provider. FrontMCP validates tokens but doesn’t issue them.
const auth: AuthOptionsInput = {
  mode: 'transparent',
  provider: 'https://auth.example.com',
  providerConfig: {
    jwksUri: 'https://auth.example.com/.well-known/jwks.json',
  },
  expectedAudience: 'https://api.myservice.com',
  requiredScopes: ['openid'],
  allowAnonymous: false,
};

How It Works

Configuration Options

OptionTypeDefaultDescription
providerstringRequiredBase URL of the IdP
providerConfig.jwksUristringAuto-discoveredCustom JWKS endpoint
providerConfig.jwksJSONWebKeySet-Inline JWKS for offline verification
expectedAudiencestring | string[]RequiredRequired audience claim value(s) — typically the protected resource URL
requiredScopesstring[][]Scopes that must be present
allowAnonymousbooleanfalseAllow requests without tokens

Provider Examples

auth: {
  mode: 'transparent',
  provider: 'https://your-tenant.auth0.com',
  // JWKS discovered automatically from /.well-known/jwks.json
  expectedAudience: 'https://api.yourservice.com',
}

Use Cases

Existing IdP Integration

Your organization already uses Auth0, Okta, or similar

Single Provider

All users authenticate through one identity provider
Do NOT use transparent mode when you need:
  • Multiple identity providers
  • Progressive authorization (add apps over time)
  • Server-side token storage with silent refresh
  • Custom token claims

Local Mode

FrontMCP acts as a full OAuth 2.1 authorization server with a built-in login form. Self-contained auth server with built-in user management.
const auth: AuthOptionsInput = {
  mode: 'local',
  // 'memory' (default) is lost on restart. Use { sqlite: { path } } for
  // single-node persistence or { redis: ... } for multi-instance.
  tokenStorage: 'memory',
};
Local mode signs the tokens it issues with HS256 using the JWT_SECRET environment variable (no RSA/EC key pair). See Local OAuth for token signing, persistent tokenStorage (memory / sqlite / redis), the requireEmail / anonymousSubject single-operator options, and tunnel/issuer configuration. Local mode also orchestrates multiple upstream OAuth providers out of the box. Declare a providers array (GitHub, Slack, Jira, …) and FrontMCP federates them at /oauth/authorize, refuses to mint a JWT until federatedAuth.minProviders (default 1) are linked, stores each provider’s tokens encrypted server-side, and exposes them to tools via this.orchestration.getToken(id):
const auth: AuthOptionsInput = {
  mode: 'local',
  providers: [
    { id: 'github', authorizeUrl: '', tokenUrl: '', clientId: '', scopes: ['repo'] },
    { id: 'slack', authorizeUrl: '', tokenUrl: '', clientId: '' },
  ],
  federatedAuth: { minProviders: 1 }, // no JWT until ≥1 linked
};
See Multi-Provider Orchestration for the full provider schema, the minProviders / requiredProviders gate, and the this.orchestration tool API.
The built-in login page accepts any email format without validation and is intended for development. Replace with a real identity provider for production use.

Remote Mode

FrontMCP acts as an OAuth 2.1 authorization server that proxies user authentication to an upstream IdP. End users never submit credentials to FrontMCP directly — they’re redirected to the upstream IdP, and FrontMCP exchanges the resulting upstream code/tokens before issuing its own session token to the MCP client.
const auth: AuthOptionsInput = {
  mode: 'remote',
  provider: 'https://auth.example.com',
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  scopes: ['openid', 'profile', 'email'],
  consent: { enabled: true },
};

How It Works

Configuration Options

OptionTypeDefaultDescription
consentConsentConfigundefined (block optional)Tool-selection consent screen + call-time enforcement (see Local docs). When the block is present, inner enabled defaults to false.
tokenStorage'memory' | { redis: RedisConfig } | { sqlite: SqliteConfig }'memory'Storage backend (memory / sqlite / redis)
allowDefaultPublicbooleanfalseAllow unauthenticated requests
federatedAuthFederatedAuthConfig-Federated auth state validation
incrementalAuthIncrementalAuthConfigundefined (block optional)Progressive authorization. When the block is present, inner enabled defaults to true.
consent: {
  enabled: true,
  groupByApp: true,
  showDescriptions: true,
  allowSelectAll: true,
  requireSelection: true,
  excludedTools: ['ping'],          // always available, never gated
  defaultSelectedTools: ['create-note'], // pre-checked on the screen
}
When consent.enabled is true, the local flow renders an interactive tool-selection screen after login and enforces the selection at call time: the chosen tool ids are embedded in the token’s consent claim and a tools/call to an unselected tool is rejected with TOOL_NOT_CONSENTED (JSON-RPC -32003). The flags groupByApp, showDescriptions, allowSelectAll, requireSelection, customMessage, excludedTools, and defaultSelectedTools are all honored. See Local OAuth → Consent for the full table.
Tokens minted without consent (consent disabled, or created via the test/programmatic factory) carry no consent claim and are unaffected — all tools remain callable. rememberConsent (default true) persists each user’s per-client selection and reuses it on the next login, re-prompting only when a NEW tool appears; set it false to always re-show the screen.

Incremental Authorization

incrementalAuth: {
  enabled: true,
  allowSkip: true,                    // Allow skipping app auth
  showAllAppsAtOnce: true,            // Show all apps in one page
  skippedAppBehavior: 'require-auth', // 'anonymous' or 'require-auth'
}

Federated Authentication Configuration

Configure how multi-provider (federated) authentication is gated and validated.
federatedAuth: {
  stateValidation: 'strict',     // 'strict' (recommended) or 'format'
  minProviders: 1,               // no JWT until ≥1 provider linked
  requiredProviders: ['github'], // these ids must all be linked
}
OptionValuesDescription
stateValidation'strict' | 'format''strict': Full state match (recommended). 'format': Only validates state format
minProvidersnumberMinimum providers that must be linked before a JWT is minted (default 1 when providers are configured)
requiredProvidersstring[]Provider ids that must all be linked before a JWT is minted

OAuth Endpoints

Local and remote modes expose standard OAuth endpoints:
EndpointMethodDescription
/oauth/authorizeGETStart authorization flow
/oauth/tokenPOSTExchange code for tokens
/oauth/registerPOSTDynamic Client Registration
/oauth/userinfoGETUser profile information
/.well-known/oauth-authorization-serverGETServer metadata
/.well-known/jwks.jsonGETPublic signing keys

Use Cases

Multi-Provider Federation

Combine multiple IdPs under one session (Slack + GitHub + custom)

Progressive Authorization

Users authorize apps incrementally as needed

Full Token Control

Custom token lifetimes, scopes, and refresh behavior

Tool-Authorization Enforcement

Gate tools via the interactive consent picker (shipped) and enforce the selection at call time
Do NOT use local or remote mode when:
  • You only have one IdP and don’t need federation (use transparent instead)
  • You want to minimize auth complexity
  • Running multiple instances without Redis

Mode Selection Flowchart


Security Comparison

Security AspectPublicTransparentLocalRemote
Token VerificationNoneAgainst upstream JWKSHS256 symmetric secretHS256 symmetric secret (FrontMCP-issued session)
PKCE SupportN/ADepends on IdPAlways S256Always S256 (downstream); upstream depends on IdP
Refresh Token RotationN/ADepends on IdPAlways rotatedDepends on upstream IdP
Signing KeyJWT_SECRET (symmetric)Upstream-managedJWT_SECRET (symmetric)JWT_SECRET (symmetric) + upstream JWKS
Tool-authz enforcementNoNoOptionalOptional
Session RevocationN/AN/ASupportedSupported

Token Verification Flow


Next Steps

Remote OAuth

Configure upstream IdP integration

Local OAuth

Set up self-contained authentication

Progressive Authorization

Implement incremental app authorization

Production Deployment

Security checklist for production