Skip to main content
FastMCP provides utility classes for authentication, token management, and OAuth flows.

JWTIssuer

Issues and validates HS256-signed JWTs for the OAuth proxy.
import { JWTIssuer } from "fastmcp";

const issuer = new JWTIssuer({
  issuer: "https://api.example.com",
  audience: "https://api.example.com",
  signingKey: process.env.JWT_SIGNING_KEY!,
  accessTokenTtl: 3600,      // 1 hour
  refreshTokenTtl: 2592000,  // 30 days
});

// Issue access token
const accessToken = issuer.issueAccessToken(
  "client-123",
  ["read", "write"],
  { role: "admin" },  // Additional claims
);

// Issue refresh token
const refreshToken = issuer.issueRefreshToken(
  "client-123",
  ["read", "write"],
);

// Verify token
const result = await issuer.verify(accessToken);
if (result.valid) {
  console.log("Claims:", result.claims);
}

Constructor

config
JWTIssuerConfig
required

Methods

issueAccessToken()

clientId
string
required
Client identifier
scope
string[]
required
Token scopes
additionalClaims
Record<string, unknown>
Custom claims to include in JWT
expiresIn
number
Override default TTL (seconds)
token
string
HS256-signed JWT access token

issueRefreshToken()

clientId
string
required
Client identifier
scope
string[]
required
Token scopes
additionalClaims
Record<string, unknown>
Custom claims to include in JWT
expiresIn
number
Override default TTL (seconds)
token
string
HS256-signed JWT refresh token

verify()

token
string
required
JWT token to verify
result
TokenValidationResult
interface TokenValidationResult {
  valid: boolean;
  claims?: JWTClaims;
  error?: string;
}

deriveKey() (static)

Derive a signing key from a secret using PBKDF2.
const derivedKey = await JWTIssuer.deriveKey("my-secret", 100000);
secret
string
required
Secret to derive key from
iterations
number
default:"100000"
PBKDF2 iterations
key
string
Base64-encoded derived key

JWKSVerifier

Verifies JWTs using public keys from a JWKS endpoint.
import { JWKSVerifier } from "fastmcp";

const verifier = new JWKSVerifier({
  jwksUri: "https://accounts.google.com/.well-known/jwks.json",
  audience: "your-client-id",
  issuer: "https://accounts.google.com",
  cacheDuration: 3600000,    // 1 hour
  cooldownDuration: 30000,   // 30 seconds
});

const result = await verifier.verify(idToken);
if (result.valid) {
  console.log("User:", result.claims?.sub);
}
Note: Requires the jose package: npm install jose

Constructor

config
JWKSVerifierConfig
required

Methods

verify()

token
string
required
JWT token to verify
result
TokenVerificationResult
interface TokenVerificationResult {
  valid: boolean;
  claims?: Record<string, unknown>;
  error?: string;
}

refreshKeys()

Force refresh of JWKS cache.
await verifier.refreshKeys();

getJwksUri()

Get the JWKS URI being used.
const uri = verifier.getJwksUri();

PKCEUtils

PKCE (Proof Key for Code Exchange) utilities for OAuth 2.0.
import { PKCEUtils } from "fastmcp";

// Generate verifier and challenge
const { verifier, challenge } = PKCEUtils.generatePair("S256");

// Validate challenge
const valid = PKCEUtils.validateChallenge(verifier, challenge, "S256");

Static Methods

generatePair()

Generate a complete PKCE pair (verifier + challenge).
method
'S256' | 'plain'
default:"S256"
Challenge method
pair
PKCEPair
interface PKCEPair {
  verifier: string;   // Base64URL-encoded (43-128 chars)
  challenge: string;  // Base64URL-encoded or plain
}

generateVerifier()

Generate a cryptographically secure code verifier.
length
number
default:"128"
Verifier length (43-128 characters)
verifier
string
Base64URL-encoded random string

generateChallenge()

Generate a code challenge from a verifier.
verifier
string
required
Code verifier
method
'S256' | 'plain'
default:"S256"
Challenge method
challenge
string
Base64URL-encoded challenge (S256) or verifier (plain)

validateChallenge()

Validate a code verifier against a challenge.
verifier
string
required
Code verifier to validate
challenge
string
required
Expected challenge
method
string
required
Challenge method used
valid
boolean
Whether verifier matches challenge

ConsentManager

Manages consent screens and cookie signing for OAuth flows.
import { ConsentManager } from "fastmcp";

const manager = new ConsentManager("signing-key-secret");

// Create consent response
const response = manager.createConsentResponse(transaction, "Google");

// Sign consent cookie
const cookie = manager.signConsentCookie({
  transactionId: "trans-123",
  clientName: "My App",
  provider: "Google",
  scope: ["openid", "profile"],
  timestamp: Date.now(),
});

// Validate consent cookie
const data = manager.validateConsentCookie(cookie);
if (data) {
  console.log("Valid consent:", data);
}

Constructor

signingKey
string
required
Secret key for signing consent cookies

Methods

createConsentResponse()

transaction
OAuthTransaction
required
OAuth transaction
provider
string
required
Provider name for display
response
Response
HTTP response with consent HTML

signConsentCookie()

data
ConsentData
required
Consent data to sign
Signed cookie value

validateConsentCookie()

Signed cookie value
data
ConsentData | null
Validated consent data or null if invalid/expired

Token Storage

Token storage backends for OAuth tokens and mappings.

MemoryTokenStorage

In-memory token storage with TTL support.
import { MemoryTokenStorage } from "fastmcp";

const storage = new MemoryTokenStorage(60000); // Cleanup every 60s

// Save value with TTL
await storage.save("key", { data: "value" }, 3600); // 1 hour

// Get value
const value = await storage.get("key");

// Delete value
await storage.delete("key");

// Manual cleanup
await storage.cleanup();

// Destroy storage
storage.destroy();

Constructor

cleanupIntervalMs
number
default:"60000"
Cleanup interval in milliseconds

Methods

save
(key: string, value: unknown, ttl?: number) => Promise<void>
Save value with optional TTL (seconds)
get
(key: string) => Promise<unknown | null>
Retrieve value (returns null if expired/not found)
delete
(key: string) => Promise<void>
Delete value
cleanup
() => Promise<void>
Remove expired entries
size
() => number
Get number of stored items
destroy
() => void
Clear storage and stop cleanup interval

EncryptedTokenStorage

Encrypted wrapper for token storage using AES-256-GCM.
import { EncryptedTokenStorage, MemoryTokenStorage } from "fastmcp";

const backend = new MemoryTokenStorage();
const storage = new EncryptedTokenStorage(backend, "encryption-key");

// Same interface as backend, but values are encrypted
await storage.save("key", { secret: "data" }, 3600);
const value = await storage.get("key");

Constructor

backend
TokenStorage
required
Underlying storage backend
encryptionKey
string
required
Encryption key (derived using scrypt)

Methods

Same as TokenStorage interface - all values are automatically encrypted/decrypted.

DiscoveryDocumentCache

Caches OAuth discovery documents with TTL and request coalescing.
import { DiscoveryDocumentCache } from "fastmcp";

const cache = new DiscoveryDocumentCache({
  ttl: 3600000, // 1 hour
});

// Fetch and cache discovery document
const doc = await cache.get(
  "https://accounts.google.com/.well-known/openid-configuration",
);

// Check if cached
if (cache.has(url)) {
  console.log("Document is cached");
}

// Clear cache
cache.clear(); // Clear all
cache.clear(url); // Clear specific URL

// Get cache size
console.log("Cached documents:", cache.size);

Constructor

options
object

Methods

get()

Fetch discovery document (uses cache if available).
url
string
required
Discovery document URL
document
Promise<unknown>
Discovery document as JSON object
Features:
  • Returns cached value if valid
  • Coalesces concurrent requests for same URL
  • Auto-caches successful fetches

has()

Check if URL is cached and not expired.
url
string
required
Discovery document URL
cached
boolean
Whether document is cached and valid

clear()

Clear cache.
url
string
Optional URL to clear (omit to clear all)

size

Get number of cached documents.
size
number
Number of cached documents