/templates
/oauth

OAuth 2.1 Authentication Template

The typescript-oauth template provides a complete, production-ready OAuth 2.1 implementation for your MCP server. Perfect for user-facing applications that need industry-standard authentication.

๐ŸŽฏ What This Template Provides

  • โœ… OAuth 2.1 Implementation - Complete, standards-compliant
  • โœ… Dual Transport - STDIO for MCP + HTTP for OAuth metadata
  • โœ… Token Validation - Automatic JWT verification, audience binding
  • โœ… Scope-Based Access - Fine-grained permissions
  • โœ… Working Example Tools - Public, protected, and scoped tools
  • โœ… Studio Integration - Complete OAuth flow in NitroStack Studio
  • โœ… Multi-Provider Support - Works with Auth0, Okta, Keycloak, etc.

๐Ÿš€ Quick Start (5 Minutes)

1. Create Project

npx nitrostack init my-oauth-server
# Select: typescript-oauth
cd my-oauth-server
npm install

2. Setup Auth0

See the complete setup guide or follow these quick steps:

Create Auth0 Application:

  1. Auth0 Dashboard โ†’ Applications โ†’ Create
  2. Type: Regular Web Application
  3. Callback URLs: http://localhost:3000/auth/callback
  4. Copy Client ID & Secret

Create Auth0 API:

  1. Auth0 Dashboard โ†’ APIs โ†’ Create
  2. Identifier: http://localhost:3002
  3. Add scopes: read, write, admin

3. Configure Environment

Edit .env:

RESOURCE_URI=http://localhost:3002
AUTH_SERVER_URL=https://YOUR-TENANT.auth0.com
TOKEN_AUDIENCE=http://localhost:3002
TOKEN_ISSUER=https://YOUR-TENANT.auth0.com/

4. Start & Test

npm run dev

Then in NitroStack Studio:

  1. Auth โ†’ OAuth 2.1
  2. Discover: http://localhost:3002
  3. Enter Client ID/Secret
  4. Start OAuth Flow
  5. Test tools! โœ…

๐Ÿ—๏ธ Project Structure

typescript-oauth/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ guards/
โ”‚   โ”‚   โ””โ”€โ”€ oauth.guard.ts          # OAuth token validation
โ”‚   โ”œโ”€โ”€ modules/demo/
โ”‚   โ”‚   โ”œโ”€โ”€ demo.module.ts
โ”‚   โ”‚   โ””โ”€โ”€ demo.tools.ts           # Example tools
โ”‚   โ”œโ”€โ”€ app.module.ts               # OAuthModule configuration
โ”‚   โ””โ”€โ”€ index.ts                    # Entry point
โ”œโ”€โ”€ .env                            # Environment config
โ”œโ”€โ”€ OAUTH_SETUP.md                  # Complete setup guide
โ””โ”€โ”€ README.md

๐Ÿ“‹ Example Tools

Public Tool (No Auth)

@Tool({
  name: 'get_server_info',
  description: 'Get public server information',
})
async getServerInfo() {
  return {
    name: 'My OAuth Server',
    version: '1.0.0',
  };
}

Protected Tool (OAuth Required)

@Tool({
  name: 'get_user_profile',
  description: 'Get authenticated user profile',
})
@UseGuards(OAuthGuard)
async getUserProfile(@ExecutionContext() context: ExecutionContext) {
  return {
    user: context.auth.subject,      // 'auth0|abc123'
    scopes: context.auth.scopes,     // ['read', 'write']
    email: context.auth.claims.email,
  };
}

Scoped Tool (Requires Specific Scope)

@Tool({
  name: 'admin_statistics',
  description: 'Get admin statistics',
})
@UseGuards(OAuthGuard, createScopeGuard('read', 'admin'))
async adminStats() {
  // Only accessible with both 'read' AND 'admin' scopes
  return { stats: { ... } };
}

๐Ÿ” How OAuth Works in This Template

Dual Transport Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      Your OAuth 2.1 MCP Server           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                          โ”‚
โ”‚  ๐Ÿ“ก STDIO Transport                      โ”‚
โ”‚  โ”œโ”€ MCP Protocol Communication           โ”‚
โ”‚  โ”œโ”€ Tool Execution                       โ”‚
โ”‚  โ””โ”€ Connected to Studio/Claude           โ”‚
โ”‚                                          โ”‚
โ”‚  ๐ŸŒ HTTP Server (Port 3002)              โ”‚
โ”‚  โ”œโ”€ OAuth Metadata Endpoints             โ”‚
โ”‚  โ”œโ”€ /.well-known/oauth-protected-        โ”‚
โ”‚  โ”‚   resource (RFC 9728)                 โ”‚
โ”‚  โ””โ”€ Token Validation                     โ”‚
โ”‚                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Benefits:

  • โœ… Fast STDIO for MCP protocol
  • โœ… Standards-compliant HTTP for OAuth
  • โœ… Automatic - no manual configuration needed!

OAuth Flow

  1. Discovery - Studio fetches OAuth metadata from your server
  2. Credentials - You enter Client ID/Secret
  3. Authorization - Redirected to Auth0 login
  4. Token Exchange - Auth code exchanged for JWT token
  5. Tool Calls - Token automatically included in requests

๐Ÿ”ง Configuration

OAuthModule Setup

// src/app.module.ts
OAuthModule.forRoot({
  // Your MCP server URL
  resourceUri: process.env.RESOURCE_URI!,
  
  // Your OAuth provider(s)
  authorizationServers: [process.env.AUTH_SERVER_URL!],
  
  // Supported scopes
  scopesSupported: ['read', 'write', 'admin'],
  
  // Optional: Token validation
  audience: process.env.TOKEN_AUDIENCE,
  issuer: process.env.TOKEN_ISSUER,
  
  // Optional: Custom validation
  customValidation: async (tokenPayload) => {
    // Add your own validation logic
    return true;
  },
})

Protecting Tools

import { Tool, UseGuards, OAuthGuard, createScopeGuard } from 'nitrostack';

// Requires valid OAuth token
@UseGuards(OAuthGuard)

// Requires specific scope(s)
@UseGuards(OAuthGuard, createScopeGuard('read'))

// Requires multiple scopes
@UseGuards(OAuthGuard, createScopeGuard('read', 'admin'))

๐Ÿงช Testing in Studio

Complete Flow

  1. Start Server:

    npm run dev
    
  2. Open Studio: Navigate to http://localhost:3000

  3. Discover OAuth Server:

    • Auth โ†’ OAuth 2.1 tab
    • Enter: http://localhost:3002
    • Click "Discover Auth Config"
    • โœ… Should show discovered metadata
  4. Enter Credentials:

    • Client ID: [Your Auth0 Client ID]
    • Client Secret: [Your Auth0 Client Secret]
    • Click "Save Client Credentials"
  5. Start OAuth Flow:

    • Click "Start Authorization Flow"
    • Login to Auth0
    • Authorize the application
    • โœ… Redirected back with JWT token!
  6. Test Tools:

    • Go to Tools tab
    • Execute any protected tool
    • โœ… Token automatically included!

๐Ÿ” Security Features

1. Token Audience Binding (RFC 8707)

Tokens are validated to ensure they were issued specifically for your MCP server:

// Token must have your RESOURCE_URI in audience claim
{
  "aud": "http://localhost:3002",  // โ† Must match
  "sub": "user123",
  "scope": "read write admin"
}

2. Automatic Token Validation

NitroStack automatically validates:

  • โœ… JWT signature (verified against JWKS)
  • โœ… Token expiration (exp claim)
  • โœ… Token audience (aud claim)
  • โœ… Token issuer (iss claim)
  • โœ… Not before time (nbf claim)
  • โœ… Required scopes

3. Short-Lived Tokens

Configure Auth0 for short-lived tokens:

  • Access Token: 1 hour
  • Refresh Token: 30 days

Studio automatically handles token refresh.


๐Ÿš€ Production Deployment

1. Update Environment Variables

# Production URLs (with HTTPS!)
RESOURCE_URI=https://mcp.yourapp.com
AUTH_SERVER_URL=https://auth.yourapp.com
TOKEN_AUDIENCE=https://mcp.yourapp.com
TOKEN_ISSUER=https://auth.yourapp.com/

2. Configure OAuth Provider

Update your Auth0 application:

  • Allowed Callback URLs: https://studio.yourapp.com/auth/callback
  • Allowed Web Origins: https://studio.yourapp.com

3. Deploy

# Build
npm run build

# Deploy to your platform
# (Heroku, AWS, GCP, Azure, etc.)

๐ŸŒ Supported OAuth Providers

This template works with any OAuth 2.1 compliant provider:

  • โœ… Auth0 - Easiest for testing
  • โœ… Okta - Enterprise-ready
  • โœ… Keycloak - Self-hosted
  • โœ… Azure AD / Entra ID
  • โœ… Google Identity Platform
  • โœ… AWS Cognito

See OAUTH_SETUP.md for provider-specific configuration.


๐Ÿ“š Learn More


๐Ÿ’ก Common Use Cases

User-Facing Applications

Perfect for applications where users login with their own accounts:

  • Dashboard applications
  • Admin panels
  • Content management systems
  • SaaS platforms

Multi-Tenant Applications

@Tool({ name: 'get_tenant_data' })
@UseGuards(OAuthGuard)
async getTenantData(@ExecutionContext() context: ExecutionContext) {
  const tenantId = context.auth.claims.tenant_id;
  return await db.data.find({ tenantId });
}

Role-Based Access Control

@Tool({ name: 'admin_panel' })
@UseGuards(OAuthGuard, createScopeGuard('admin'))
async adminPanel(@ExecutionContext() context: ExecutionContext) {
  // Only users with 'admin' scope can access
}

๐ŸŽ‰ Why This Template is Amazing

Traditional OAuth Implementation โŒ

Complexity:

  • 500+ lines of boilerplate
  • Manual JWKS fetching & caching
  • Token validation logic
  • Metadata endpoints
  • Security pitfalls everywhere

Time: 2-3 days

This Template โœ…

Simplicity:

OAuthModule.forRoot({ ... });
@UseGuards(OAuthGuard)

Time: 5 minutes!

You Get:

  • โœ… Production-grade OAuth implementation
  • โœ… Standards-compliant (all RFCs)
  • โœ… Secure by default
  • โœ… Working examples
  • โœ… Complete testing flow

Next Steps:

  1. Create your project with npx nitrostack init
  2. Follow the setup guide
  3. Test in Studio
  4. Customize for your needs
  5. Deploy to production!

Happy coding! ๐Ÿš€