googleapis/mcp-toolbox · error
description is required for tool %q
Error message
description is required for tool %q
What it means
The postgres-list-tables Config.Initialize requires a non-empty `description`; because ConfigBase's description is not marked required elsewhere, Initialize enforces it explicitly and returns this error when the field is empty or omitted. Descriptions are what the MCP client/LLM sees for the tool, so Toolbox refuses to register undescribed tools. This fires during config parsing/initialization, before any database connection is made.
Source
Thrown at internal/tools/postgres/postgreslisttables/postgreslisttables.go:144
RunSQL(context.Context, string, []any) (any, error)
}
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"`
}
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)
}
allParameters := parameters.Parameters{
parameters.NewStringParameter("table_names", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed.", parameters.WithStringDefault("")),
parameters.NewStringParameter("output_format", "Optional: Use 'simple' for names only or 'detailed' for full info.", parameters.WithStringDefault("detailed")),
}
return Tool{
BaseTool: tools.NewBaseTool(
cfg,
tools.GetAnnotationsOrDefault(cfg.Annotations, tools.NewReadOnlyAnnotations),
tools.Manifest{Description: cfg.Description, Parameters: allParameters.Manifest(), AuthRequired: cfg.AuthRequired},
allParameters,
),
}, nil
}
var _ tools.Tool = Tool{}
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Add a non-empty `description:` to the tool's yaml entry.
- If constructing Config in Go, set ConfigBase.Description before calling Initialize.
- Check yaml indentation so the description key actually nests under the tool.
- Use a prebuilt config as a template to get the required fields right.
Example fix
# before
tools:
list-tables:
kind: postgres-list-tables
source: my-pg
# after
tools:
list-tables:
kind: postgres-list-tables
source: my-pg
description: Lists detailed schema information for tables in a Postgres database. Defensive patterns
Strategy: validation
Validate before calling
# shell check before starting toolbox
python3 - <<'EOF'
import sys, yaml
cfg = yaml.safe_load(open('tools.yaml'))
for name, t in (cfg.get('tools') or {}).items():
if not t.get('description'):
sys.exit(f"tool {name!r} is missing a non-empty description")
EOF Type guard
// Go-side guard before Initialize
if cfg.Description == "" {
return fmt.Errorf("tool %q has no description; set ConfigBase.Description", cfg.Name)
} Prevention
- Always include a meaningful `description:` for every tool in the yaml.
- Copy tool definitions from prebuilt configs that already include descriptions.
- Watch yaml indentation so description stays nested under the tool entry.
- Lint configs in CI to reject empty description fields.
When it happens
Trigger: Defining a `postgres-list-tables` tool in the tools yaml without a `description:` field, or with `description: ""` — cfg.Description == "" in Initialize.
Common situations: Minimal hand-written tool configs that only set name/kind/source; YAML indentation mistakes that drop the description key; programmatically constructing Config and leaving Description unset; copying tool blocks and deleting the description.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- doc %d: unexpected non-string key in input: %v
- doc %d: invalid config format at key %q: %w
- doc %d: invalid config format at key %q: expected nested for
- %s missing 'kind' field or it is not a string
- missing 'kind' field or it is not a string: %v
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/91eeb0e0b682166c.
Report an issue: GitHub.