# MCP Server with Auth Middleware

This example demonstrates how to integrate the Go MCP SDK's `auth.RequireBearerToken` middleware with an MCP server to provide authenticated access to MCP tools and resources.

## Features

The server provides authentication and authorization capabilities for MCP tools:

### 1. Authentication Methods

- **JWT Token Authentication**: JSON Web Token-based authentication
- **API Key Authentication**: API key-based authentication
- **Scope-based Access Control**: Permission-based access to MCP tools

### 2. MCP Integration

- **Authenticated MCP Tools**: Tools that require authentication and check permissions
- **Token Generation**: Utility endpoints for generating test tokens
- **Middleware Integration**: Seamless integration with MCP server handlers

## Setup

```bash
cd examples/server/auth-middleware
go mod tidy
go run main.go
```

## Testing

```bash
# Run all tests
go test -v

# Run benchmark tests
go test -bench=.

# Generate coverage report
go test -cover
```

## Endpoints

### Public Endpoints (No Authentication Required)

- `GET /health` - Health check
- `GET /.well-known/oauth-protected-resource` - OAuth 2.0 Protected Resource Metadata (RFC 9728)

### MCP Endpoints (Authentication Required)

- `POST /mcp/jwt` - MCP server with JWT authentication
- `POST /mcp/apikey` - MCP server with API key authentication

### Utility Endpoints

- `GET /generate-token` - Generate JWT token
- `POST /generate-api-key` - Generate API key

## Available MCP Tools

The server provides three authenticated MCP tools:

### 1. Say Hi (`say_hi`)

A simple greeting tool that requires authentication.

**Parameters:**
- None required

**Required Scopes:**
- Any authenticated user

### 2. Get User Info (`get_user_info`)

Retrieves user information based on the provided user ID.

**Parameters:**
- `user_id` (string): The user ID to get information for

**Required Scopes:**
- `read` permission

### 3. Create Resource (`create_resource`)

Creates a new resource with the provided details.

**Parameters:**
- `name` (string): The name of the resource
- `description` (string): The description of the resource
- `content` (string): The content of the resource

**Required Scopes:**
- `write` permission

## Example Usage

### 1. Generating JWT Token and Using MCP Tools

```bash
# Generate a token
curl 'http://localhost:8080/generate-token?user_id=alice&scopes=read,write'

# Use MCP tool with JWT authentication
curl -H 'Authorization: Bearer <generated_token>' \
     -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"say_hi","arguments":{}}}' \
     http://localhost:8080/mcp/jwt
```

### 2. Generating API Key and Using MCP Tools

```bash
# Generate an API key
curl -X POST 'http://localhost:8080/generate-api-key?user_id=bob&scopes=read'

# Use MCP tool with API key authentication
curl -H 'Authorization: Bearer <generated_api_key>' \
     -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_user_info","arguments":{"user_id":"test"}}}' \
     http://localhost:8080/mcp/apikey
```

### 3. Testing Scope Restrictions

```bash
# Access MCP tool requiring write scope
curl -H 'Authorization: Bearer <token_with_write_scope>' \
     -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_resource","arguments":{"name":"test","description":"test resource","content":"test content"}}}' \
     http://localhost:8080/mcp/jwt
```

## Core Concepts

### Authentication Integration

This example demonstrates how to integrate `auth.RequireBearerToken` middleware with an MCP server to provide authenticated access. The MCP server operates as an HTTP handler protected by authentication middleware.

### Key Features

1. **MCP Server Integration**: Create MCP server using `mcp.NewServer`
2. **Authentication Middleware**: Protect MCP handlers with `auth.RequireBearerToken`
3. **Token Verification**: Validate tokens using provided `TokenVerifier` functions
4. **Scope Checking**: Verify required permissions (scopes) are present
5. **Expiration Validation**: Check that tokens haven't expired
6. **Context Injection**: Add verified token information to request context
7. **Authenticated MCP Tools**: Tools that operate based on authentication information
8. **Error Handling**: Return appropriate HTTP status codes and error messages on authentication failure

### Implementation

```go
// Create MCP server
server := mcp.NewServer(&mcp.Implementation{Name: "authenticated-mcp-server"}, nil)

// Create authentication middleware
authMiddleware := auth.RequireBearerToken(verifier, &auth.RequireBearerTokenOptions{
	Scopes: []string{"read", "write"},
})

// Create MCP handler
handler := mcp.NewStreamableHTTPHandler(func(r *http.Request) *mcp.Server {
	return server
}, nil)

// Apply authentication middleware to MCP handler
authenticatedHandler := authMiddleware(customMiddleware(handler))
```

### Parameters

- **verifier**: Function to verify tokens (`TokenVerifier` type)
- **opts**: Authentication options
  - `Scopes`: List of required permissions
  - `ResourceMetadataURL`: OAuth 2.0 resource metadata URL

### Error Responses

- **401 Unauthorized**: Token is invalid, expired, or missing
- **403 Forbidden**: Required scopes are insufficient
- **WWW-Authenticate Header**: Included when resource metadata URL is configured

## Implementation Details

### 1. TokenVerifier Implementation

```go
func jwtVerifier(ctx context.Context, tokenString string) (*auth.TokenInfo, error) {
	// JWT token verification logic
	// On success: Return TokenInfo
	// On failure: Return auth.ErrInvalidToken
}
```

### 2. Using Authentication Information in MCP Tools

```go
// Get authentication information in MCP tool
func MyTool(ctx context.Context, req *mcp.CallToolRequest, args MyArgs) (*mcp.CallToolResult, any, error) {
	// Extract authentication info from request
	userInfo := req.Extra.TokenInfo

	// Check scopes
	if !slices.Contains(userInfo.Scopes, "read") {
		return nil, nil, fmt.Errorf("insufficient permissions: read scope required")
	}

	// Execute tool logic
	return &mcp.CallToolResult{
		Content: []mcp.Content{
			&mcp.TextContent{Text: "Tool executed successfully"},
		},
	}, nil, nil
}
```

### 3. Middleware Composition

```go
// Combine authentication middleware with custom middleware
authenticatedHandler := authMiddleware(customMiddleware(mcpHandler))
```

## Security Best Practices

1. **Environment Variables**: Use environment variables for JWT secrets in production
2. **Database Storage**: Store API keys in a database
3. **HTTPS Usage**: Always use HTTPS in production environments
4. **Token Expiration**: Set appropriate token expiration times
5. **Principle of Least Privilege**: Grant only the minimum required scopes

## CORS Support

The OAuth metadata endpoint (`/.well-known/oauth-protected-resource`) supports CORS to enable
cross-origin client discovery. It sets `Access-Control-Allow-Origin: *` by default because
OAuth metadata is public information meant for client discovery (RFC 9728 §3.1).

### Custom CORS Policies

For more sophisticated CORS requirements (origin validation, credentials, etc.), wrap the handler
with a CORS middleware library:

**Using github.com/rs/cors:**
```go
import "github.com/rs/cors"

c := cors.New(cors.Options{
    AllowedOrigins: []string{"https://example.com"},
    AllowedMethods: []string{"GET", "OPTIONS"},
})
http.Handle("/.well-known/oauth-protected-resource",
    c.Handler(auth.ProtectedResourceMetadataHandler(metadata)))
```

**Using github.com/jub0bs/cors:**
```go
import "github.com/jub0bs/cors"

corsMiddleware, err := cors.NewMiddleware(cors.Config{
    Origins: []string{"https://example.com"},
    Methods: []string{"GET", "OPTIONS"},
})
http.Handle("/.well-known/oauth-protected-resource",
    corsMiddleware.Wrap(auth.ProtectedResourceMetadataHandler(metadata)))
```

## Use Cases

**Ideal for:**

- MCP servers requiring authentication and authorization
- Applications needing scope-based access control
- Systems requiring both JWT and API key authentication
- Projects needing secure MCP tool access
- Scenarios requiring audit trails and permission management

**Examples:**

- Enterprise MCP servers with user management
- Multi-tenant MCP applications
- Secure API gateways with MCP integration
- Development environments with authentication requirements
- Production systems requiring fine-grained access control
