> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leanmcp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# @leanmcp/auth

> Token-based authentication decorators and multi-provider support for MCP tools

# @leanmcp/auth

Authentication module for LeanMCP providing token-based authentication decorators and multi-provider support for protecting MCP tools, prompts, and resources.

## Features

<CardGroup cols={2}>
  <Card title="@Authenticated Decorator" icon="shield-check">
    Protect tools, prompts, and resources with a simple decorator
  </Card>

  <Card title="Multi-Provider Support" icon="key">
    AWS Cognito, Clerk, Auth0, and LeanMCP providers
  </Card>

  <Card title="Automatic authUser" icon="user">
    Decoded user info injected as global `authUser` variable
  </Card>

  <Card title="Concurrency Safe" icon="bolt">
    Uses AsyncLocalStorage for request-isolated context
  </Card>
</CardGroup>

## Installation

```bash theme={null}
npm install @leanmcp/auth @leanmcp/core
```

### Provider Dependencies

<Tabs>
  <Tab title="AWS Cognito">
    ```bash theme={null}
    npm install @aws-sdk/client-cognito-identity-provider axios jsonwebtoken jwk-to-pem
    ```
  </Tab>

  <Tab title="Clerk">
    ```bash theme={null}
    npm install axios jsonwebtoken jwk-to-pem
    ```
  </Tab>

  <Tab title="Auth0">
    ```bash theme={null}
    npm install axios jsonwebtoken jwk-to-pem
    ```
  </Tab>
</Tabs>

## Quick Start

### 1. Initialize Auth Provider

```typescript theme={null}
import { AuthProvider } from "@leanmcp/auth";

const authProvider = new AuthProvider('cognito', {
  region: 'us-east-1',
  userPoolId: 'us-east-1_XXXXXXXXX',
  clientId: 'your-client-id'
});

await authProvider.init();
```

### 2. Protect Methods with @Authenticated

```typescript theme={null}
import { Tool } from "@leanmcp/core";
import { Authenticated } from "@leanmcp/auth";

export class SentimentService {
  @Tool({ description: 'Analyze sentiment (requires auth)' })
  @Authenticated(authProvider)
  async analyzeSentiment(input: { text: string }) {
    // authUser is automatically available with user info
    console.log('User ID:', authUser.sub);
    console.log('Email:', authUser.email);

    return { 
      sentiment: 'positive', 
      score: 0.8,
      analyzedBy: authUser.sub
    };
  }

  // Public method - no authentication
  @Tool({ description: 'Get categories (public)' })
  async getCategories() {
    return { categories: ['positive', 'negative', 'neutral'] };
  }
}
```

### 3. Protect Entire Service

```typescript theme={null}
// All methods in this class require authentication
@Authenticated(authProvider)
export class SecureService {
  @Tool({ description: 'Protected tool' })
  async protectedTool(input: { data: string }) {
    // authUser is available in all methods
    return { data: input.data, userId: authUser.sub };
  }
}
```

## The authUser Variable

When using `@Authenticated`, a global `authUser` variable is automatically injected containing the decoded JWT payload:

```typescript theme={null}
@Tool({ description: 'Create post' })
@Authenticated(authProvider)
async createPost(input: { title: string, content: string }) {
  // authUser is automatically available
  return {
    id: generateId(),
    title: input.title,
    content: input.content,
    authorId: authUser.sub,
    authorEmail: authUser.email
  };
}
```

### Provider-Specific User Data

<Tabs>
  <Tab title="AWS Cognito">
    ```typescript theme={null}
    {
      sub: 'user-uuid',
      email: 'user@example.com',
      email_verified: true,
      'cognito:username': 'username',
      'cognito:groups': ['admin', 'users']
    }
    ```
  </Tab>

  <Tab title="Clerk">
    ```typescript theme={null}
    {
      sub: 'user_2abc123xyz',
      userId: 'user_2abc123xyz',
      email: 'user@example.com',
      firstName: 'John',
      lastName: 'Doe',
      imageUrl: 'https://img.clerk.com/...'
    }
    ```
  </Tab>

  <Tab title="Auth0">
    ```typescript theme={null}
    {
      sub: 'auth0|507f1f77bcf86cd799439011',
      email: 'user@example.com',
      email_verified: true,
      name: 'John Doe',
      picture: 'https://s.gravatar.com/avatar/...'
    }
    ```
  </Tab>
</Tabs>

### Controlling User Fetch

```typescript theme={null}
// Fetch user info (default)
@Authenticated(authProvider, { getUser: true })
async withUserInfo(input: any) {
  console.log(authUser); // User data available
}

// Only verify token, skip user fetch (faster)
@Authenticated(authProvider, { getUser: false })
async tokenOnlyValidation(input: any) {
  // authUser is undefined
}
```

## Supported Providers

### AWS Cognito

```typescript theme={null}
const authProvider = new AuthProvider('cognito', {
  region: 'us-east-1',
  userPoolId: 'us-east-1_XXXXXXXXX',
  clientId: 'your-client-id'
});
await authProvider.init();
```

**Environment Variables:**

```bash theme={null}
AWS_REGION=us-east-1
COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
COGNITO_CLIENT_ID=your-client-id
```

### Clerk

```typescript theme={null}
// Session Mode (default)
const authProvider = new AuthProvider('clerk', {
  frontendApi: 'your-frontend-api.clerk.accounts.dev',
  secretKey: 'sk_test_...'
});

// OAuth Mode (with refresh tokens)
const authProvider = new AuthProvider('clerk', {
  frontendApi: 'your-frontend-api.clerk.accounts.dev',
  secretKey: 'sk_test_...',
  clientId: 'your-oauth-client-id',
  clientSecret: 'your-oauth-client-secret',
  redirectUri: 'https://yourapp.com/callback'
});

await authProvider.init();
```

### Auth0

```typescript theme={null}
const authProvider = new AuthProvider('auth0', {
  domain: 'your-tenant.auth0.com',
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  audience: 'https://your-api-identifier'
});
await authProvider.init();
```

### LeanMCP

For LeanMCP platform deployments with user secrets support:

```typescript theme={null}
const authProvider = new AuthProvider('leanmcp', {
  apiKey: 'your-leanmcp-api-key'
});
await authProvider.init();
```

## Client Usage

Authentication tokens are passed via the `_meta` field following MCP protocol standards:

```typescript theme={null}
await mcpClient.callTool({
  name: "analyzeSentiment",
  arguments: { text: "Hello world" },
  _meta: {
    authorization: {
      type: "bearer",
      token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
  }
});
```

## Error Handling

```typescript theme={null}
import { AuthenticationError } from "@leanmcp/auth";

try {
  await service.protectedMethod({ text: "test" });
} catch (error) {
  if (error instanceof AuthenticationError) {
    switch (error.code) {
      case 'MISSING_TOKEN':
        console.log('No token provided');
        break;
      case 'INVALID_TOKEN':
        console.log('Token is invalid or expired');
        break;
      case 'VERIFICATION_FAILED':
        console.log('Verification failed:', error.message);
        break;
    }
  }
}
```

## API Reference

### AuthProvider

```typescript theme={null}
class AuthProvider {
  constructor(provider: string, config: any);
  async init(config?: any): Promise<void>;
  async verifyToken(token: string): Promise<boolean>;
  async refreshToken(refreshToken: string): Promise<any>;
  async getUser(token: string): Promise<any>;
  getProviderType(): string;
}
```

### @Authenticated Decorator

```typescript theme={null}
function Authenticated(
  authProvider: AuthProvider, 
  options?: AuthenticatedOptions
): ClassDecorator | MethodDecorator;

interface AuthenticatedOptions {
  getUser?: boolean;   // Default: true
  projectId?: string;  // For LeanMCP user secrets
}
```

### AuthenticationError

```typescript theme={null}
class AuthenticationError extends Error {
  code: 'MISSING_TOKEN' | 'INVALID_TOKEN' | 'VERIFICATION_FAILED';
  constructor(message: string, code: string);
}
```

### Helper Functions

```typescript theme={null}
// Check if authentication is required
function isAuthenticationRequired(target: any): boolean;

// Get auth provider for method/class
function getAuthProvider(target: any): AuthProviderBase | undefined;

// Get current authenticated user
function getAuthUser(): any;
```

## Best Practices

<AccordionGroup>
  <Accordion title="Security">
    * Always use HTTPS in production
    * Store tokens securely (keychain, encrypted storage)
    * Implement token refresh before expiration
    * Add rate limiting to protect against brute force
  </Accordion>

  <Accordion title="Configuration">
    * Use environment variables for credentials
    * Never hardcode secrets in code
    * Use `_meta` for auth, not business arguments
  </Accordion>

  <Accordion title="Performance">
    * Use `getUser: false` when you only need token validation
    * JWKS keys are cached automatically for performance
  </Accordion>
</AccordionGroup>

## OAuth 2.1 Support

Beyond server-side token verification, `@leanmcp/auth` provides complete OAuth 2.1 infrastructure:

<CardGroup cols={2}>
  <Card title="OAuth Client" icon="user" href="/sdk/auth-oauth-client">
    Browser-based OAuth flows with PKCE, token storage, and automatic refresh
  </Card>

  <Card title="OAuth Server & Proxy" icon="server" href="/sdk/auth-oauth-server">
    Build authorization servers with external provider proxy support
  </Card>
</CardGroup>

### Submodule Imports

```typescript theme={null}
// Server-side token verification (this page)
import { AuthProvider, Authenticated } from '@leanmcp/auth';

// OAuth client for browser-based flows
import { OAuthClient } from '@leanmcp/auth/client';

// Token storage backends
import { MemoryStorage, FileStorage, KeychainStorage } from '@leanmcp/auth/storage';

// OAuth proxy for external providers
import { OAuthProxy, googleProvider, githubProvider } from '@leanmcp/auth/proxy';

// OAuth authorization server
import { OAuthAuthorizationServer } from '@leanmcp/auth/server';
```

## Related Packages

* [@leanmcp/core](/sdk/core) - Core decorators and server functionality
* [@leanmcp/env-injection](/sdk/env-injection) - Environment variable injection for user secrets
* [OAuth Client](/sdk/auth-oauth-client) - Client-side OAuth with PKCE and token storage
* [OAuth Server & Proxy](/sdk/auth-oauth-server) - Authorization servers with external provider support

## Links

* [GitHub Repository](https://github.com/LeanMCP/leanmcp-sdk)
* [NPM Package](https://www.npmjs.com/package/@leanmcp/auth)
