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
- Ensure every tool name added to group.ToolNames is registered via PrimitiveManager before serving requests
- Rebuild groups whenever tools are added or removed so group and manager stay in sync
- Check server startup logs and config for misspelled or duplicate tool names
- 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
- Derive group tool names from the registry, never hardcode them
- Add a startup assertion that every group tool resolves in PrimitiveManager
- Rebuild groups inside the same lock/scope as tool registration changes
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
- METHOD_NOT_FOUND
- INVALID_REQUEST
- INTERNAL_ERROR
- INVALID_PARAMS
- Mcp-Method header value '%s' does not match body value '%s'
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/e606128add13cf09.
Report an issue: GitHub.