# 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 ' \ -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 ' \ -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 ' \ -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