charmbracelet/crush · error

mcp '%s' does not use OAuth authentication

Error message

mcp '%s' does not use OAuth authentication

What it means

AuthenticateMCP only supports MCP servers of type HTTP that have OAuth enabled. If the configured server lacks m.OAuth or is not config.MCPHttp, the function returns this error without starting the browser auth flow.

Source

Thrown at internal/agent/tools/mcp/init.go:365

		slog.Debug("Skipping disabled MCP", "name", name)
		return nil
	}

	return initClient(ctx, cfg, name, m, currentGen(name), cfg.Resolver())
}

// AuthenticateMCP initiates the OAuth flow for an MCP server that is in
// StateNeedsAuth. It creates the OAuth handler (which starts a local
// callback server), connects to the server (which triggers the browser
// auth flow on 401), and transitions to StateConnected on success.
func AuthenticateMCP(ctx context.Context, cfg *config.ConfigStore, name string) error {
	m, exists := cfg.Config().MCP[name]
	if !exists {
		return fmt.Errorf("mcp '%s' not found in configuration", name)
	}

	if !m.OAuth || m.Type != config.MCPHttp {
		return fmt.Errorf("mcp '%s' does not use OAuth authentication", name)
	}

	updateState(name, StateStarting, nil, nil, Counts{}, withPending(m))

	// This is the user-initiated flow, so permit the interactive browser
	// authorization the handler otherwise withholds during startup.
	ctx = mcpoauth.WithInteractive(ctx)

	// The OAuth handler persists the token automatically as it is
	// exchanged, so a successful connection has already saved it.
	_, err := connectAndRegister(ctx, cfg, name, m, currentGen(name), cfg.Resolver(), channelEnabled(cfg.Overrides().EnabledChannels, name))
	if err != nil {
		return err
	}
	return nil
}

// PendingAuthServer describes an MCP server awaiting OAuth.

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Set the OAuth option on the HTTP MCP server entry in config.
  2. Switch the server definition to type http if OAuth is intended.
  3. For stdio/API-key servers, provide credentials via env/config instead of OAuth.
  4. Use the correct command for non-OAuth servers instead of MCPAuthenticate.

Example fix

// before
mcp github {
	type http
	url "https://api.github.com/mcp"
}
// after
mcp github {
	type http
	url "https://api.github.com/mcp"
	oauth true
}
Defensive patterns

Strategy: validation

Validate before calling

srv, ok := cfg.Config().MCP[name]
if !ok || !srv.OAuth || srv.Type != config.MCPHttp {
	return fmt.Errorf("server %q must be an HTTP MCP server with OAuth enabled", name)
}

Try / catch

if err := mcp.AuthenticateMCP(ctx, cfg, name); err != nil {
	if strings.Contains(err.Error(), "does not use OAuth") {
		// fall back to env-var/API-key credentials for this server
	}
	return err
}

Prevention

When it happens

Trigger: Calling AuthenticateMCP on an MCP server defined as stdio/sse type, or an HTTP server configured without the OAuth flag set to true in its mcp entry.

Common situations: Trying to run browser OAuth for a local stdio MCP server; forgetting to set the oauth option on an HTTP server; using authenticate on a server that uses static API-key headers instead.

Understand the failure class

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/a7a5a16bcf306b36. Report an issue: GitHub.