googleapis/mcp-toolbox · error
tool does not exist: %s
Error message
tool does not exist: %s
What it means
GenerateListToolsResult iterates the group's tool names and looks each up in the PrimitiveManager via pMgr.GetTool. If a name in g.ToolNames has no registered tool, it returns "tool does not exist: %s". This means the group references a tool that the manager never registered, so the tools/list manifest cannot be built.
Source
Thrown at internal/server/mcp/v20260728/manifests.go:122
}
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, supportsSecureParams bool) (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)
}
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)
}
// Skip a Tool that requires secure params extension if the client doesn't support it.
if tool.HasSecureParams() && !supportsSecureParams {
continue
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Check server startup logs for tool load/registration failures for the named tool.
- Ensure the tool is defined in the YAML and its `kind` is supported by this server version.
- Update the group's `tools:` list to match exact registered tool names.
- Restart the server after config edits so groups and registered tools stay consistent.
Example fix
// before (group references undefined tool)
group:
tools:
- execute_sql # not defined
// after
group:
tools:
- execute_sql
tools:
execute_sql:
kind: postgres-execute-sql
source: my-pg-instance
Defensive patterns
Strategy: validation
Validate before calling
// Config sanity check before serving (server side):
// every group tool name must have a tools: entry with a valid kind
for (const t of group.tools) {
if (!(t in config.tools)) throw new Error(`group references undefined tool: ${t}`);
} Try / catch
try {
const {tools} = await client.request({method:'tools/list'});
} catch (e) {
if (String(e.message).includes('tool does not exist')) {
console.error('Server group references an unregistered tool; check server config:', e.message);
} else throw e;
} Prevention
- Keep group tool lists generated from the same source as tool definitions.
- Check startup logs for tool registration failures.
- Verify each tool's kind is supported by the server version in use.
- Rename tools and their group references in the same commit.
When it happens
Trigger: A group's `tools:` list (or URL-selected group) contains a tool name that is absent from the server's registered tools — usually because the tool failed to load from the YAML config, was renamed, or the group config is out of sync.
Common situations: YAML config lists a tool under a group but the tool definition is missing or its kind is unrecognized, startup registration failed silently, config edited to rename a tool without updating the group, or using a prebuilt config where tool names changed across versions.
Related errors
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/95fb420d27435393.
Report an issue: GitHub.