googleapis/mcp-toolbox · error

description is required for tool %q

Error message

description is required for tool %q

What it means

sqlite-execute-sql requires a human-readable `description` for the tool. Config.Initialize returns this error before building the tool when cfg.Description is empty. The description is surfaced to the LLM, so it is mandatory in the tool spec.

Source

Thrown at internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go:67

}

type Config struct {
	tools.ConfigBase `yaml:",inline"`
	Type             string                 `yaml:"type" validate:"required"`
	Source           string                 `yaml:"source" validate:"required"`
	Annotations      *tools.ToolAnnotations `yaml:"annotations,omitempty"`
}

// validate interface
var _ tools.ToolConfig = Config{}

func (cfg Config) ToolConfigType() string {
	return resourceType
}

func (cfg Config) Initialize(context.Context) (tools.Tool, error) {
	if cfg.Description == "" {
		return nil, fmt.Errorf("description is required for tool %q", cfg.Name)
	}

	sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.")
	params := parameters.Parameters{sqlParameter}

	return Tool{
		BaseTool: tools.NewBaseTool(
			cfg,
			tools.GetAnnotationsOrDefault(cfg.Annotations, tools.NewDestructiveAnnotations),
			tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired},
			params,
		),
	}, nil
}

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

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add a non-empty `description:` field to the sqlite-execute-sql tool definition.
  2. Check YAML indentation: description must be a sibling of name/source under the tool.
  3. If description comes from a template/parameter, verify it resolves to a non-empty string.

Example fix

# before
tools:
  exec-sql:
    kind: sqlite-execute-sql
    source: my-sqlite
# after
tools:
  exec-sql:
    kind: sqlite-execute-sql
    source: my-sqlite
    description: "Executes arbitrary SQL statements against the SQLite database."
Defensive patterns

Strategy: validation

Validate before calling

# Fail fast before starting the server:
yq '.tools[] | select(.kind == "sqlite-execute-sql") | select(.description == null or .description == "") | .name' tools.yaml | grep . && echo 'missing description' && exit 1

Type guard

func hasDescription(kind, name, desc string) error {
    if desc == "" { return fmt.Errorf("tool %q: description is required", name) }
    return null
}

Try / catch

tool, err := cfg.Initialize(ctx)
if err != nil {
    log.Fatalf("tool config invalid: %v", err)
}

Prevention

When it happens

Trigger: A tools.yaml defines a tool of kind `sqlite-execute-sql` without a `description:` field, or with an empty string; description set via templating that resolves to empty.

Common situations: Hand-writing a minimal tool config and omitting description; YAML indentation error placing description under the wrong key so it never populates the field; generating configs programmatically and skipping optional-looking fields.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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