googleapis/mcp-toolbox · error

client_id and client_secret need to be specified

Error message

client_id and client_secret need to be specified

What it means

When useClientOAuth is not "true", the Looker source authenticates the server itself using a client credential session; it requires both client_id and client_secret to be present in the config. If either is empty, Initialize refuses to proceed with this error. Only the client OAuth mode (delegated per-request tokens) may omit them.

Source

Thrown at internal/sources/looker/looker.go:132

		VerifySsl:    r.SslVerification,
		Timeout:      int32(duration.Seconds()),
		ClientId:     r.ClientId,
		ClientSecret: r.ClientSecret,
	}

	var tokenSource oauth2.TokenSource
	tokenSource, _ = initGoogleCloudConnection(ctx)

	s := &Source{
		Config:              r,
		ApiSettings:         &cfg,
		TokenSource:         tokenSource,
		AuthTokenHeaderName: "Authorization",
	}

	if strings.ToLower(r.UseClientOAuth) == "false" {
		if r.ClientId == "" || r.ClientSecret == "" {
			return nil, fmt.Errorf("client_id and client_secret need to be specified")
		}
		s.Client = v4.NewLookerSDK(rtl.NewAuthSession(cfg))
		resp, err := s.Client.Me("", s.ApiSettings)
		if err != nil {
			return nil, fmt.Errorf("incorrect settings: %w", err)
		}
		logger.DebugContext(ctx, fmt.Sprintf("logged in as %s %s", *resp.FirstName, *resp.LastName))
	} else {
		if strings.ToLower(r.UseClientOAuth) != "true" {
			s.AuthTokenHeaderName = r.UseClientOAuth
		}
		logger.DebugContext(ctx, fmt.Sprintf("Using AuthTokenHeaderName: %s", s.AuthTokenHeaderName))
	}

	return s, nil

}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Set both client_id and client_secret in the Looker source config.
  2. Verify the secret-injection mechanism (env var expansion, mounted secret) actually populated them.
  3. If using per-user OAuth instead, set useClientOAuth: "true" so credentials are supplied per request.

Example fix

# before
sources:
  looker:
    kind: looker
    baseUrl: https://mycompany.looker.com
# after
sources:
  looker:
    kind: looker
    baseUrl: https://mycompany.looker.com
    client_id: ${LOOKER_CLIENT_ID}
    client_secret: ${LOOKER_CLIENT_SECRET}
Defensive patterns

Strategy: validation

Validate before calling

// Go or pre-flight shell: fail fast when server-auth mode lacks credentials
if !strings.EqualFold(cfg.UseClientOAuth, "true") && (cfg.ClientId == "" || cfg.ClientSecret == "") {
    return errors.New("looker source needs client_id and client_secret (or set useClientOAuth: true)")
}
// shell check before start:
// [ -n "$LOOKER_CLIENT_ID" ] && [ -n "$LOOKER_CLIENT_SECRET" ] || echo 'missing Looker credentials'

Try / catch

src, err := cfg.Initialize(ctx, tracer)
if err != nil {
    if strings.Contains(err.Error(), "client_id and client_secret need to be specified") {
        fmt.Println("Set client_id/client_secret in YAML or env-inject LOOKER_CLIENT_ID/LOOKER_CLIENT_SECRET.")
    }
    return err
}

Prevention

When it happens

Trigger: Config with useClientOAuth false/unset and either client_id or client_secret empty at Initialize time.

Common situations: Deploying with secrets passed via env vars/secret manager that failed to inject, leaving empty fields; forgetting to fill credentials when switching from client-OAuth mode back to server auth; YAML keys misnamed (clientId vs client_id).

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/97450c7676669eb0. Report an issue: GitHub.