Kafka MCP Server supports OAuth 2.1 authentication when running in HTTP transport mode. This enables secure, token-based authentication for MCP clients accessing the server over HTTP.
The implementation uses oauth-mcp-proxy@v1.0.0, a standalone OAuth 2.1 library designed specifically for Go MCP servers.
┌─────────────────┐
│ MCP Client │
│ (Cursor, etc) │
└────────┬────────┘
│
│ Bearer Token
│ Authorization: Bearer <token>
▼
┌─────────────────────────────────┐
│ HTTP Server │
│ │
│ ┌──────────────────────────┐ │
│ │ OAuth Middleware │ │
│ │ - Token Extraction │ │
│ │ - Token Validation │ │
│ │ - User Context Inject │ │
│ └──────────┬───────────────┘ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ MCP Server Handler │ │
│ │ /mcp endpoint │ │
│ └──────────────────────────┘ │
└─────────────────────────────────┘
│
▼
┌─────────────────┐
│ Kafka Cluster │
└─────────────────┘
The OAuth integration follows a specific initialization sequence:
http.NewServeMux() created in main()CreateOAuthOption(cfg, mux) registers OAuth routes on muxNewMCPServer(name, version, oauthOption) with OAuth middlewarestartHTTPServer() mounts MCP handler and starts serverThis ensures OAuth routes and middleware are properly configured before the server starts handling requests.
Best for: Environments where clients can handle OAuth flows directly.
Characteristics:
Configuration:
export MCP_TRANSPORT=http
export MCP_HTTP_PORT=8080
export OAUTH_ENABLED=true
export OAUTH_MODE=native
export OAUTH_PROVIDER=okta
export OAUTH_SERVER_URL=http://localhost:8080
export OIDC_ISSUER=https://company.okta.com
export OIDC_AUDIENCE=api://kafka-mcp-server
Best for: Centralized OAuth management, simple clients.
Characteristics:
Configuration:
export MCP_TRANSPORT=http
export MCP_HTTP_PORT=8080
export OAUTH_ENABLED=true
export OAUTH_MODE=proxy
export OAUTH_PROVIDER=google
export OAUTH_SERVER_URL=http://localhost:8080
export OIDC_ISSUER=https://accounts.google.com
export OIDC_CLIENT_ID=your-client-id.apps.googleusercontent.com
export OIDC_CLIENT_SECRET=your-client-secret
export OIDC_AUDIENCE=your-client-id.apps.googleusercontent.com
export OAUTH_REDIRECT_URIS=http://localhost:8080/oauth/callback
export JWT_SECRET=$(openssl rand -hex 32)
Simple symmetric key authentication for local development.
export OAUTH_PROVIDER=hmac
export OAUTH_MODE=native
export JWT_SECRET=$(openssl rand -hex 32)
export OIDC_ISSUER=http://localhost:8080
export OIDC_AUDIENCE=api://kafka-mcp-server
Use case: Local testing without external OAuth provider.
Enterprise SSO provider.
Setup Requirements:
Native Mode:
export OAUTH_PROVIDER=okta
export OAUTH_MODE=native
export OIDC_ISSUER=https://company.okta.com
export OIDC_AUDIENCE=api://kafka-mcp-server
Proxy Mode: Add client credentials
export OIDC_CLIENT_ID=your-okta-client-id
export OIDC_CLIENT_SECRET=your-okta-client-secret
export OAUTH_REDIRECT_URIS=http://localhost:8080/oauth/callback
export JWT_SECRET=$(openssl rand -hex 32)
Google Workspace authentication.
Setup Requirements:
Configuration:
export OAUTH_PROVIDER=google
export OIDC_ISSUER=https://accounts.google.com
export OIDC_AUDIENCE=your-client-id.apps.googleusercontent.com
Microsoft identity platform.
Setup Requirements:
Configuration:
export OAUTH_PROVIDER=azure
export OIDC_ISSUER=https://login.microsoftonline.com/{tenant-id}/v2.0
export OIDC_AUDIENCE=api://your-app-id
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_TRANSPORT |
Transport mode | stdio |
Yes (set to http) |
MCP_HTTP_PORT |
HTTP server port | 8080 |
No |
| Variable | Description | Default | Required |
|---|---|---|---|
OAUTH_ENABLED |
Enable OAuth | false |
Yes |
OAUTH_MODE |
Mode: native or proxy | native |
No |
OAUTH_PROVIDER |
Provider: hmac, okta, google, azuread | okta |
No |
OAUTH_SERVER_URL |
Full server URL | - | Yes |
| Variable | Description | Required |
|---|---|---|
OIDC_ISSUER |
OAuth issuer URL | Yes |
OIDC_AUDIENCE |
OAuth audience | Yes |
OIDC_CLIENT_ID |
OAuth client ID | Proxy mode only |
OIDC_CLIENT_SECRET |
OAuth client secret | Proxy mode only |
| Variable | Description | Required |
|---|---|---|
OAUTH_REDIRECT_URIS |
Comma-separated redirect URIs | Yes |
JWT_SECRET |
JWT signing secret | Yes |
When OAuth is enabled, the following endpoints are automatically registered:
/.well-known/oauth-authorization-server - OAuth 2.1 metadata (RFC 8414)/.well-known/openid-configuration - OIDC discovery/.well-known/oauth-protected-resource - Protected resource metadata/.well-known/jwks.json - JSON Web Key Set/oauth/authorize - Authorization endpoint/oauth/callback - OAuth callback endpoint/oauth/token - Token exchange endpoint/oauth/register - Dynamic client registration/mcp - MCP server endpoint (protected when OAuth enabled)The HMAC provider is perfect for local development without external dependencies:
# Start server with HMAC OAuth
export MCP_TRANSPORT=http
export MCP_HTTP_PORT=8080
export OAUTH_ENABLED=true
export OAUTH_PROVIDER=hmac
export OAUTH_MODE=native
export OAUTH_SERVER_URL=http://localhost:8080
export OIDC_ISSUER=http://localhost:8080
export OIDC_AUDIENCE=api://kafka-mcp-server
export JWT_SECRET=$(openssl rand -hex 32)
export KAFKA_BROKERS=localhost:9092
./bin/kafka-mcp-server
Check OAuth metadata:
curl http://localhost:8080/.well-known/oauth-authorization-server | jq
Expected output:
{
"issuer": "http://localhost:8080",
"authorization_endpoint": "http://localhost:8080/oauth/authorize",
"token_endpoint": "http://localhost:8080/oauth/token",
"jwks_uri": "http://localhost:8080/.well-known/jwks.json",
...
}
# Generate test token (implementation-specific)
TOKEN="your-bearer-token"
# Access MCP endpoint with token
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/mcp
OAUTH_SERVER_URL to HTTPS URLDevelopment:
OAUTH_SERVER_URL=http://localhost:8080 is acceptableopenssl rand -hex 32Staging:
Production:
Issue: failed to setup OAuth
Solutions:
Issue: OAuth discovery endpoints not found
Solutions:
OAUTH_ENABLED=trueMCP_TRANSPORT=httpIssue: Valid tokens are rejected
Solutions:
Authorization: Bearer <token>OIDC_ISSUEROIDC_AUDIENCEIssue: Server doesn’t shutdown cleanly
Solutions:
When OAuth is enabled, authenticated user information is available in tool handlers:
import (
oauth "github.com/tuannvm/oauth-mcp-proxy"
)
func myToolHandler(ctx context.Context, request ToolRequest) (*ToolResponse, error) {
// Extract authenticated user from context
user, ok := oauth.GetUserFromContext(ctx)
if !ok {
return nil, fmt.Errorf("authentication required")
}
slog.Info("Tool accessed by authenticated user",
"username", user.Username,
"email", user.Email,
"subject", user.Subject)
// Proceed with tool logic
// ...
}
For advanced use cases, you can customize OAuth behavior by modifying internal/mcp/server.go:
// Example: Add custom logger
oauthConfig.Logger = customLogger
// Example: Customize provider-specific settings
if cfg.OAuthProvider == "okta" {
// Provider-specific configuration
}
Step 1: Ensure backwards compatibility
# Existing STDIO configuration still works
export MCP_TRANSPORT=stdio
export KAFKA_BROKERS=localhost:9092
Step 2: Add HTTP transport without OAuth
export MCP_TRANSPORT=http
export MCP_HTTP_PORT=8080
export KAFKA_BROKERS=localhost:9092
Step 3: Enable OAuth
export MCP_TRANSPORT=http
export MCP_HTTP_PORT=8080
export OAUTH_ENABLED=true
export OAUTH_MODE=native
export OAUTH_PROVIDER=okta
export OAUTH_SERVER_URL=https://your-domain.com
export OIDC_ISSUER=https://company.okta.com
export OIDC_AUDIENCE=api://kafka-mcp-server
export KAFKA_BROKERS=localhost:9092
Step 4: Update MCP clients
For OAuth-related issues: