Documentation Index
Fetch the complete documentation index at: https://mintlify.com/mcp-use/mcp-use/llms.txt
Use this file to discover all available pages before exploring further.
OAuth Authentication
Secure your MCP server with OAuth 2.0 authentication. mcp-use provides zero-config OAuth integration with popular identity providers.
Supported Providers
- Auth0 - Enterprise authentication platform
- WorkOS - SSO and user management for B2B apps
- Supabase - Open-source Firebase alternative
- Keycloak - Open-source identity management
- Custom - Bring your own OAuth provider
Quick Start
Auth0
Zero-config setup with environment variables:
# .env
MCP_USE_OAUTH_AUTH0_DOMAIN=your-tenant.auth0.com
MCP_USE_OAUTH_AUTH0_AUDIENCE=https://your-api.com
import { MCPServer, oauthAuth0Provider } from 'mcp-use/server';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthAuth0Provider() // Auto-configured from env vars
});
server.tool(
{
name: 'get-user',
description: 'Get authenticated user info'
},
async (params, ctx) => {
return {
userId: ctx.auth.user.userId,
email: ctx.auth.user.email,
name: ctx.auth.user.name
};
}
);
await server.listen();
WorkOS
WorkOS supports two OAuth modes:
Dynamic Client Registration (Recommended)
# .env
MCP_USE_OAUTH_WORKOS_SUBDOMAIN=your-company
MCP_USE_OAUTH_WORKOS_API_KEY=sk_xxx # For API calls
import { oauthWorkOSProvider } from 'mcp-use/server';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthWorkOSProvider() // DCR mode
});
Pre-registered OAuth Client
# .env
MCP_USE_OAUTH_WORKOS_SUBDOMAIN=your-company
MCP_USE_OAUTH_WORKOS_CLIENT_ID=client_01KB5...
MCP_USE_OAUTH_WORKOS_API_KEY=sk_xxx
Supabase
# .env
MCP_USE_OAUTH_SUPABASE_PROJECT_ID=your-project-id
MCP_USE_OAUTH_SUPABASE_JWT_SECRET=your-jwt-secret
import { oauthSupabaseProvider } from 'mcp-use/server';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthSupabaseProvider()
});
Keycloak
# .env
MCP_USE_OAUTH_KEYCLOAK_SERVER_URL=https://keycloak.example.com
MCP_USE_OAUTH_KEYCLOAK_REALM=my-realm
MCP_USE_OAUTH_KEYCLOAK_CLIENT_ID=my-client
import { oauthKeycloakProvider } from 'mcp-use/server';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthKeycloakProvider()
});
Provider Configuration
Explicit Configuration
Pass configuration directly instead of using environment variables:
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthAuth0Provider({
domain: 'my-tenant.auth0.com',
audience: 'https://my-api.com'
})
});
Custom Provider
Integrate any OAuth 2.0 provider:
import { oauthCustomProvider } from 'mcp-use/server';
import { jwtVerify, createRemoteJWKSet } from 'jose';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthCustomProvider({
issuer: 'https://oauth.example.com',
jwksUrl: 'https://oauth.example.com/.well-known/jwks.json',
authEndpoint: 'https://oauth.example.com/authorize',
tokenEndpoint: 'https://oauth.example.com/token',
scopesSupported: ['openid', 'profile', 'email'],
grantTypesSupported: ['authorization_code'],
// Custom token verification
verifyToken: async (token) => {
const JWKS = createRemoteJWKSet(
new URL('https://oauth.example.com/.well-known/jwks.json')
);
const { payload } = await jwtVerify(token, JWKS, {
issuer: 'https://oauth.example.com',
audience: 'my-api'
});
return { payload };
},
// Custom user info extraction
getUserInfo: (payload) => ({
userId: payload.sub as string,
email: payload.email as string,
name: payload.name as string
})
})
});
Accessing User Info
Authenticated user information is available in the tool context:
server.tool(
{
name: 'get-profile',
description: 'Get user profile'
},
async (params, ctx) => {
// User information from JWT
const {
userId, // Unique user ID
email, // Email address
name, // Full name
username, // Username
nickname, // Display name
picture, // Avatar URL
roles, // User roles
permissions // User permissions
} = ctx.auth.user;
// Access token for API calls
const token = ctx.auth.accessToken;
// OAuth scopes
const scopes = ctx.auth.scopes;
// JWT payload (all claims)
const payload = ctx.auth.payload;
return {
userId,
email,
name
};
}
);
Authorization
Scope-Based Access
Check if user has required scopes:
import { hasScope, requireScope } from 'mcp-use/server';
server.tool(
{
name: 'admin-action',
description: 'Perform admin action'
},
async (params, ctx) => {
// Check if user has scope
if (!hasScope(ctx, 'admin')) {
return { error: 'Admin access required' };
}
// Or throw error if missing
requireScope(ctx, 'admin'); // Throws if missing
// Check multiple scopes (requires ALL)
requireScope(ctx, ['admin', 'write']);
// Perform admin action
return { success: true };
}
);
Permission-Based Access
Check user permissions (Auth0 style):
import { requireAnyScope } from 'mcp-use/server';
server.tool(
{
name: 'manage-users',
description: 'Manage users'
},
async (params, ctx) => {
// Require at least one of these scopes
requireAnyScope(ctx, ['admin', 'user:write']);
// Check permissions array
const permissions = ctx.auth.permissions;
if (!permissions.includes('users:write')) {
return { error: 'Permission denied' };
}
return { success: true };
}
);
Role-Based Access
Check user roles:
server.tool(
{
name: 'delete-data',
description: 'Delete data'
},
async (params, ctx) => {
const roles = ctx.auth.user.roles || [];
if (!roles.includes('admin')) {
return { error: 'Admin role required' };
}
return { success: true };
}
);
Making Authenticated API Calls
Use the access token to call external APIs:
server.tool(
{
name: 'fetch-user-data',
description: 'Fetch data from API'
},
async (params, ctx) => {
const token = ctx.auth.accessToken;
const response = await fetch('https://api.example.com/user', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
return { error: `API error: ${response.statusText}` };
}
const data = await response.json();
return data;
}
);
OAuth Endpoints
When OAuth is enabled, these endpoints are automatically created:
Discovery Endpoint
GET /.well-known/oauth-protected-resource
Returns OAuth configuration:
{
"resource": "https://your-server.com",
"authorization_servers": ["https://oauth-provider.com"],
"bearer_methods_supported": ["header"],
"resource_documentation": "https://your-server.com/docs"
}
GET /.well-known/oauth-authorization-server
Returns provider configuration:
{
"issuer": "https://oauth-provider.com",
"authorization_endpoint": "https://oauth-provider.com/authorize",
"token_endpoint": "https://oauth-provider.com/token",
"scopes_supported": ["openid", "profile", "email"],
"grant_types_supported": ["authorization_code"]
}
Protected Routes
All /mcp endpoints are automatically protected with bearer authentication:
POST /mcp
Authorization: Bearer <token>
If the token is missing or invalid, the server returns:
401 Unauthorized
WWW-Authenticate: Bearer error="unauthorized", resource_metadata="https://your-server.com/.well-known/oauth-protected-resource"
OAuth Modes
Proxy Mode (Default)
MCP server proxies OAuth requests to the provider:
┌────────┐ ┌────────────┐ ┌──────────┐
│ Client │ ───> │ MCP Server │ ───> │ Provider │
└────────┘ └────────────┘ └──────────┘
Available routes:
POST /authorize - Start OAuth flow
POST /token - Exchange code for token
GET /.well-known/* - Discovery endpoints
Direct Mode (WorkOS)
Clients communicate directly with the provider:
┌────────┐ ┌──────────┐
│ Client │ ───> │ Provider │
└────────┘ └──────────┘
│
└─────> ┌────────────┐
│ MCP Server │ (validates tokens)
└────────────┘
Only discovery endpoints are available:
GET /.well-known/* - Discovery endpoints
Advanced Configuration
Skip JWT Verification (Development Only)
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
oauth: oauthAuth0Provider({
domain: 'dev-tenant.auth0.com',
audience: 'https://dev-api.com',
verifyJwt: false // ONLY for development!
})
});
Never disable JWT verification in production. This makes your server vulnerable to token forgery.
Custom Bearer Middleware
Create custom authentication middleware:
import { createBearerAuthMiddleware } from 'mcp-use/server';
const provider = oauthAuth0Provider();
const middleware = createBearerAuthMiddleware(provider, 'https://my-server.com');
// Apply to custom routes
server.app.use('/api/*', middleware);
Best Practices
1. Environment Variables
Store credentials securely:
# Good
MCP_USE_OAUTH_AUTH0_DOMAIN=tenant.auth0.com
MCP_USE_OAUTH_AUTH0_AUDIENCE=https://api.example.com
# Bad - hardcoded in code
Always validate user IDs and permissions:
server.tool(
{
name: 'get-user-data',
schema: z.object({
userId: z.string()
})
},
async ({ userId }, ctx) => {
// Ensure user can only access their own data
if (userId !== ctx.auth.user.userId) {
return { error: 'Access denied' };
}
return await getUserData(userId);
}
);
3. Scope Requirements
Document required scopes in tool descriptions:
server.tool(
{
name: 'admin-tool',
description: 'Admin-only tool (requires admin scope)'
},
async (params, ctx) => {
requireScope(ctx, 'admin');
// ...
}
);
4. Error Handling
Provide clear error messages:
server.tool(
{
name: 'protected-action'
},
async (params, ctx) => {
if (!ctx.auth) {
return { error: 'Authentication required. Please sign in.' };
}
if (!hasScope(ctx, 'write')) {
return { error: 'Insufficient permissions. Contact your administrator.' };
}
// ...
}
);
Examples
Complete Auth0 Server
See examples/server/oauth/auth0/src/server.ts:
import { MCPServer, oauthAuth0Provider, error, object } from 'mcp-use/server';
const server = new MCPServer({
name: 'auth0-server',
version: '1.0.0',
oauth: oauthAuth0Provider()
});
server.tool(
{
name: 'get-user-info',
description: 'Get authenticated user info'
},
async (_, ctx) => object({
userId: ctx.auth.user.userId,
email: ctx.auth.user.email,
name: ctx.auth.user.name
})
);
server.tool(
{
name: 'get-auth0-profile',
description: 'Fetch full profile from Auth0'
},
async (_, ctx) => {
const domain = process.env.MCP_USE_OAUTH_AUTH0_DOMAIN;
const res = await fetch(`https://${domain}/userinfo`, {
headers: { Authorization: `Bearer ${ctx.auth.accessToken}` }
});
return object(await res.json());
}
);
await server.listen();
WorkOS Server
See examples/server/oauth/workos/src/server.ts for a complete WorkOS example with API calls.
Next Steps
Widgets
Create interactive UIs
Notifications
Real-time updates
API Reference
Complete API docs