googleapis/mcp-toolbox · error

description is required for tool %q

Error message

description is required for tool %q

What it means

Config.Initialize for the looker-update-agent tool validates that the tool definition includes a non-empty `description` before building parameters. The description is required because it becomes the tool's public documentation surfaced to LLM clients via MCP; without it the tool cannot be registered.

Source

Thrown at internal/tools/looker/lookerupdateagent/lookerupdateagent.go:71

}

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

	agentIdParameter := parameters.NewStringParameter("agent_id", "The ID of the agent.", parameters.WithStringDefault(""))
	nameParameter := parameters.NewStringParameter("name", "The name of the agent.", parameters.WithStringDefault(""))
	descriptionParameter := parameters.NewStringParameter("description", "The description of the agent.", parameters.WithStringDefault(""))
	instructionsParameter := parameters.NewStringParameter("instructions", "The instructions (system prompt) for the agent.", parameters.WithStringDefault(""))
	sourcesParameter := parameters.NewArrayParameter(
		"sources",
		"Optional. A list of JSON-encoded data sources for the agent (e.g., [{\"model\": \"my_model\", \"explore\": \"my_explore\"}]).",
		parameters.NewMapParameter(
			"source",
			"A JSON-encoded source object with 'model' and 'explore' keys.",
			"string",
		),
		parameters.WithArrayRequired(false),
	)
	codeInterpreterParameter := parameters.NewBooleanParameter("code_interpreter", "Optional. Enables Code Interpreter for this Agent.", parameters.WithBooleanDefault(false))
	allParameters := parameters.Parameters{agentIdParameter, nameParameter, descriptionParameter, instructionsParameter, sourcesParameter, codeInterpreterParameter}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add a non-empty `description:` to the looker-update-agent tool definition in your config
  2. If generated, fix the template/serialization so the description field is populated
  3. Run a config lint/pre-check that asserts every tool entry has description before calling Initialize

Example fix

// before (tools.yaml)
tools:
  update_agent:
    kind: looker-update-agent
    source: my-looker-source
// after
tools:
  update_agent:
    kind: looker-update-agent
    source: my-looker-source
    description: Update fields of a Looker agent by ID.
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Description == "" {
    return errors.New("looker-update-agent tool requires a non-empty description")
}

Try / catch

tool, err := cfg.Initialize(ctx)
if err != nil {
    if strings.Contains(err.Error(), "description is required") {
        return fmt.Errorf("config error: set `description` for tool %q", cfg.Name)
    }
    return err
}

Prevention

When it happens

Trigger: A tools.yaml (or API-constructed) Config for kind looker-update-agent has no `description:` field or an empty string, then Initialize is invoked during server startup or config parsing.

Common situations: Hand-writing a tool entry and omitting description; templating that renders an empty description; migrating configs from an older format where description was optional.

Related errors


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