googleapis/mcp-toolbox · error
INTERNAL_ERROR
INTERNAL_ERROR
Error message
tool does not exist: %s
What it means
GenerateListToolsResult iterates the group's ToolNames and looks each up in the PrimitiveManager; a missing tool aborts tools/list generation with this INTERNAL_ERROR. It signals that the group references a tool name that is not registered globally.
Source
Thrown at internal/server/mcp/v20250618/manifests.go:108
}
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
- Verify every tool name referenced in the server config matches a registered tool (compare against a working tools/list output)
- Restart the server to rebuild group and manager consistently after config changes
- Check startup logs for tool initialization failures that leave the tool unregistered
Example fix
// before (config) tools: - execute_query // after tools: - execute-sql
Defensive patterns
Strategy: try-catch
Try / catch
try { const res = await mcp.request('tools/list', {}); } catch (e) { if (e.code === -32603 && /tool does not exist/.test(e.message)) { console.error('group references unregistered tool, restart server / fix config:', e.message); } else throw e; } Prevention
- Generate group tool lists from the same config that registers tools
- Check startup logs for failed tool registrations
- Restart after any config change instead of assuming hot-reload consistency
When it happens
Trigger: A group.Group contains a tool name absent from pMgr — group constructed from config referencing a tool that failed to initialize, was renamed, or was removed by a concurrent reload while a tools/list call is served.
Common situations: Typo'd tool name in the toolbox YAML prebuilt/group config; a tool's init/registration failing silently so it never lands in the manager; custom code building groups with hardcoded names.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/99a19e236d16b3d1.
Report an issue: GitHub.