googleapis/mcp-toolbox · error

INTERNAL_ERROR

INTERNAL_ERROR

Error message

tool does not exist: %s

What it means

GenerateListToolsResult builds the tools/list response for the MCP 2025-03-26 protocol by iterating over the tool names registered in a group and looking each one up in the PrimitiveManager. This INTERNAL_ERROR is thrown when a group lists a tool name that the manager cannot resolve, meaning server-side registration state is inconsistent rather than a client mistake.

Source

Thrown at internal/server/mcp/v20250326/manifests.go:106

		}
		if len(authParamList) > 0 {
			authParam[name] = authParamList
		}
	}
	return InputSchema{
		Type:       "object",
		Properties: properties,
		Required:   required,
	}, authParam
}

// GenerateListToolsResult generates tools/list method result according to mcp schema
func GenerateListToolsResult(pMgr *primitives.PrimitiveManager, g group.Group, urlParams map[string]string) (ListToolsResult, error) {
	mcpManifest := make([]Tool, 0, len(g.ToolNames))
	for _, toolName := range g.ToolNames {
		tool, ok := pMgr.GetTool(toolName)
		if !ok {
			return ListToolsResult{}, fmt.Errorf("tool does not exist: %s", toolName)
		}
		// Skip a Tool that requires secure params as they are not supported in this protocol version.
		if tool.HasSecureParams() {
			continue
		}
		srcName := tool.GetSourceName()
		var src sources.Source
		if srcName != "" {
			src, ok = pMgr.GetSource(srcName)
			if !ok {
				return ListToolsResult{}, fmt.Errorf("unable to retrieve %s source for tool %q", srcName, tool.GetName())
			}
		}
		params, err := tool.GetParameters(src)
		if err != nil {
			return ListToolsResult{}, fmt.Errorf("error getting parameters for tool %q: %w", toolName, err)
		}
		toolManifest := generateToolManifest(toolName, tool.GetDescription(), tool.GetAuthRequired(), params, tool.GetAnnotations(src), urlParams)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Ensure every tool name added to group.ToolNames is registered via PrimitiveManager before serving requests
  2. Rebuild groups whenever tools are added or removed so group and manager stay in sync
  3. Check server startup logs and config for misspelled or duplicate tool names
  4. File a bug if this occurs with stock server code, since it indicates internal state corruption

Example fix

// before (group built from stale names)
g.ToolNames = []string{"execute_sql", "list_tables"}
// after (derive names from registered tools)
for name := range registeredTools { g.ToolNames = append(g.ToolNames, name) }
Defensive patterns

Strategy: validation

Validate before calling

tool, ok := pMgr.GetTool(name)
if !ok {
    return fmt.Errorf("tool %q is not registered; check group registration", name)
}

Prevention

When it happens

Trigger: A group.Group's ToolNames slice contains a name that was never registered (or was removed) from primitives.PrimitiveManager, so pMgr.GetTool(toolName) returns ok=false while generating the tools/list manifest.

Common situations: Custom group construction that hardcodes tool names with typos; tools registered after groups were built; code that removes/unregisters a tool without rebuilding groups; server misconfiguration where a toolset references a tool from a disabled source.

Related errors


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