--- internal/cmd/login.go
+++ internal/cmd/login.go
@@ -6,12 +6,14 @@
 	"fmt"
 	"os"
 	"os/signal"
+	"strings"
 
 	"charm.land/lipgloss/v2"
 	"github.com/charmbracelet/crush/internal/client"
 	"github.com/charmbracelet/crush/internal/clipboard"
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/oauth"
+	"github.com/charmbracelet/crush/internal/oauth/claude"
 	"github.com/charmbracelet/crush/internal/oauth/copilot"
 	"github.com/charmbracelet/crush/internal/oauth/hyper"
 	"github.com/charmbracelet/x/ansi"
@@ -25,11 +27,14 @@
 	Short:   "Login Crush to a platform",
 	Long: `Login Crush to a specified platform.
 The platform should be provided as an argument.
-Available platforms are: hyper, copilot.`,
+Available platforms are: hyper, claude, copilot.`,
 	Example: `
 # Authenticate with Charm Hyper
 crush login
 
+# Authenticate with Claude Code Max
+crush login claude
+
 # Authenticate with GitHub Copilot
 crush login copilot
 
@@ -38,6 +43,8 @@
   `,
 	ValidArgs: []cobra.Completion{
 		"hyper",
+		"claude",
+		"anthropic",
 		"copilot",
 		"github",
 		"github-copilot",
@@ -64,6 +71,8 @@
 		switch provider {
 		case "hyper":
 			return loginHyper(c, ws.ID, force)
+		case "anthropic", "claude":
+			return loginClaude(c, ws.ID, force)
 		case "copilot", "github", "github-copilot":
 			return loginCopilot(c, ws.ID, force)
 		default:
@@ -140,6 +149,68 @@
 
 	fmt.Println()
 	fmt.Println("You're now authenticated with Hyper!")
+	return nil
+}
+
+func loginClaude(c *client.Client, wsID string, force bool) error {
+	ctx := getLoginContext()
+
+	if !force {
+		cfg, err := c.GetConfig(ctx, wsID)
+		if err == nil && cfg != nil {
+			if pc, ok := cfg.Providers.Get("anthropic"); ok && pc.OAuthToken != nil {
+				fmt.Println("You are already logged in to Claude Code Max.")
+				fmt.Println("Use --force to re-authenticate.")
+				return nil
+			}
+		}
+	}
+
+	verifier, challenge, err := claude.GetChallenge()
+	if err != nil {
+		return err
+	}
+	authURL, err := claude.AuthorizeURL(verifier, challenge)
+	if err != nil {
+		return err
+	}
+
+	fmt.Println("Open the following URL to authorize your Claude Code Max subscription:")
+	fmt.Println()
+	fmt.Println(lipgloss.NewStyle().Hyperlink(authURL, "id=claude").Render(authURL))
+	fmt.Println()
+	fmt.Println("Press enter to open in your browser...")
+	waitEnter()
+	if err := browser.OpenURL(authURL); err != nil {
+		fmt.Println("Could not open the URL. Open it manually in your browser.")
+	}
+
+	fmt.Println()
+	fmt.Println("After authorizing, paste the code shown on the page and press enter:")
+	fmt.Println()
+	fmt.Print("> ")
+	var code string
+	for code == "" {
+		_, _ = fmt.Scan(&code)
+		code = strings.TrimSpace(code)
+	}
+
+	fmt.Println()
+	fmt.Println("Exchanging authorization code...")
+	token, err := claude.ExchangeToken(ctx, code, verifier)
+	if err != nil {
+		return err
+	}
+
+	if err := cmp.Or(
+		c.SetConfigField(ctx, wsID, config.ScopeGlobal, "providers.anthropic.api_key", token.AccessToken),
+		c.SetConfigField(ctx, wsID, config.ScopeGlobal, "providers.anthropic.oauth", token),
+	); err != nil {
+		return err
+	}
+
+	fmt.Println()
+	fmt.Println("You're now authenticated with Claude Code Max!")
 	return nil
 }
 
