googleapis/mcp-toolbox · error

invalid source for %q tool: source %q is not a compatible ty

Error message

invalid source for %q tool: source %q is not a compatible type

What it means

Looker tool ValidateSource checks that the configured source implements the tool's private compatibleSource interface (UseClientAuthorization, GetAuthTokenHeaderName, LookerApiSettings, GetLookerSDK). If the source bound to the tool in the toolbox config is not a Looker source, the Go type assertion fails and this error is returned. It is a config-shape mismatch, not a runtime/network failure.

Source

Thrown at internal/tools/looker/lookerdeleteagent/lookerdeleteagent.go:114

// validate interface
var _ tools.Tool = Tool{}

type Tool struct {
	tools.BaseTool[Config]
}

func (t Tool) GetSourceName() string {
	return t.Cfg.Source
}

func (t Tool) ToConfig() tools.ToolConfig {
	return t.Cfg
}

func (t Tool) ValidateSource(source sources.Source) error {
	_, ok := source.(compatibleSource)
	if !ok {
		return fmt.Errorf("invalid source for %q tool: source %q is not a compatible type", t.Cfg.Type, t.Cfg.Source)
	}
	return nil
}

func (t Tool) Invoke(ctx context.Context, s sources.Source, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) {
	source, ok := s.(compatibleSource)
	if !ok {
		return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, nil)
	}
	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err)
	}

	sdk, err := source.GetLookerSDK(ctx, string(accessToken))
	if err != nil {
		return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err)
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Set the tool's `source` field in the YAML config to the name of a Looker source (kind: looker).
  2. Verify the referenced source actually initializes as a Looker source (check `kind`/`type` in the sources section).
  3. If writing a custom source, implement all four methods of compatibleSource: UseClientAuthorization, GetAuthTokenHeaderName, LookerApiSettings, GetLookerSDK.

Example fix

# before
tools:
  delete-agent:
    kind: looker-delete-agent
    source: my-postgres

# after
tools:
  delete-agent:
    kind: looker-delete-agent
    source: my-looker
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := src.(interface {
	UseClientAuthorization() bool
	GetAuthTokenHeaderName() string
	LookerApiSettings() *rtl.ApiSettings
	GetLookerSDK(context.Context, string) (*v4.LookerSDK, error)
}); !ok {
	return fmt.Errorf("source %T is not a Looker source; check tool's `source` field", src)
}

Type guard

func isCompatibleLookerSource(s sources.Source) bool {
	_, ok := s.(interface {
		UseClientAuthorization() bool
		GetAuthTokenHeaderName() string
		LookerApiSettings() *rtl.ApiSettings
		GetLookerSDK(context.Context, string) (*v4.LookerSDK, error)
	})
	return ok
}

Try / catch

if err := tool.ValidateSource(src); err != nil {
	// log config source name and fix the tool's `source` YAML field
	return fmt.Errorf("binding looker tool failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ValidateSource (directly or via tool resolution at server startup) when the tool's YAML `source:` points to a non-Looker source (e.g. a postgres or http source), or to a Looker-like source that does not implement GetLookerSDK/LookerApiSettings.

Common situations: Copy-pasting a tool definition and forgetting to change its `source` field; renaming a source in the config so the tool silently binds to the wrong one; mixing sources in a multi-source config file; upgrading the toolbox after a Looker source interface change.

Related errors


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