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

Valkey tools assert that the attached source implements the compatibleSource interface (a Valkey client-backed source). ValidateSource returns this error when the tool is bound to a source of any other type, so the tool never runs against a non-Valkey backend.

Source

Thrown at internal/tools/valkey/valkey.go:99

// 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)
	}

	// Replace parameters
	commands, err := replaceCommandsParams(t.Cfg.Commands, t.Cfg.Parameters, params)
	if err != nil {
		return nil, util.NewAgentError("error replacing commands' parameters", err)
	}
	res, err := source.RunCommand(ctx, commands)
	if err != nil {
		return nil, util.ProcessGeneralError(err)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Point the tool's 'source' field at a source declared with kind: valkey
  2. If the backend is Redis, use the corresponding redis tool kind instead of the valkey one
  3. Confirm the source initializes successfully before the tool binds to it

Example fix

# before
sources:
  cache:
    kind: redis
    address: localhost:6379
tools:
  valkey-cmd:
    kind: valkey-execute-sql
    source: cache
# after
sources:
  cache:
    kind: valkey
    address: localhost:6379
tools:
  valkey-cmd:
    kind: valkey-execute-sql
    source: cache
Defensive patterns

Strategy: validation

Validate before calling

kind, _ := getSourceKind(toolsYAML, tool.Source)
if kind != "valkey" {
    return fmt.Errorf("tool %s requires a valkey source, got %s", tool.Name, kind)
}

Type guard

func asValkeySource(s sources.Source) (compatibleSource, bool) {
    cs, ok := s.(compatibleSource)
    return cs, ok
}

Try / catch

if err := tool.ValidateSource(src); err != nil {
    // rebind tool to a kind: valkey source and reload
}

Prevention

When it happens

Trigger: tools.yaml pairing a valkey tool with a source whose kind is not valkey (e.g. redis, postgres); calling ValidateSource or Invoke with a mismatched sources.Source implementation.

Common situations: Assuming Redis and Valkey sources are interchangeable; copy-pasted configs where the source name points to a different kind; refactors that changed the source kind but not the tool bindings.

Related errors


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