googleapis/mcp-toolbox · error

unable to retrieve %s source for tool %q

Error message

unable to retrieve %s source for tool %q

What it means

While building the tools/list manifest, GenerateListToolsResult resolves each tool's backing source via pMgr.GetSource(srcName). If the source the tool depends on is not registered, it returns "unable to retrieve <src> source for tool <tool>". The tool exists, but its data-source dependency is missing from the manager.

Source

Thrown at internal/server/mcp/v20241105/manifests.go:118

// 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)
		mcpManifest = append(mcpManifest, toolManifest)
	}
	return ListToolsResult{Tools: mcpManifest}, nil
}

// generatePromptManifest generates a version-specific Prompt manifest for list/prompts
func generatePromptManifest(name, desc string, args prompts.Arguments) Prompt {
	mcpArgs := make([]PromptArgument, 0, len(args))
	for _, arg := range args {
		promptArg := PromptArgument{
			Name:        arg.GetName(),

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Verify the source block with that exact name exists and its kind is correct in your tools config.
  2. Check server startup logs for source initialization errors (bad credentials/env) and fix the environment so the source registers.
  3. Confirm the tool's source reference spelling matches the source's name field exactly.
  4. Restart the server with the corrected config and re-run tools/list.

Example fix

# before: tool references a source that fails to init
tools:
  run-query:
    source: prod-db
# environment missing PROD_DB_URI -> source never registers
# after: export the required env so the source initializes
export PROD_DB_URI=postgres://...  # then restart toolbox
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: confirm every tool's source exists in the source list
const sources = new Set((await (await fetch(`${base}/api/source`)).json()).map(s => s.name));
for (const tool of tools) {
  if (tool.source && !sources.has(tool.source)) throw new Error(`Missing source ${tool.source} for ${tool.name}`);
}

Prevention

When it happens

Trigger: A tool declares source: my-db but no source named my-db is defined/initialized in the config; the source's Initialize failed (bad credentials, missing env var) so it never registered; source renamed while the tool's source reference was not updated.

Common situations: Missing or wrong environment variables (connection strings, keys) so the source fails at startup; copy-pasting tool definitions without their source block; source kind typos (e.g. postgres vs alloydb-pg) so it is not registered; edited configs where the source section was deleted.

Related errors


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