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

When building a toolset manifest, each tool's declared source is looked up in the populated source manager. If the tool names a source that was not registered (or failed to initialize), BuildManifest aborts with this error naming the source kind and tool. A tool cannot produce its manifest without its backing source.

Source

Thrown at internal/tools/toolsets.go:72

}

type ToolsetManifest struct {
	ServerVersion string              `json:"serverVersion"`
	ToolsManifest map[string]Manifest `json:"tools"`
}

// BuildManifest resolves the manifest for every tool in the toolset against the
// provided sources, returning an error if any tool's manifest cannot be built.
func (t Toolset) BuildManifest(pMgr PrimitiveManagerI) (ToolsetManifest, error) {
	toolsManifest := make(map[string]Manifest, len(t.Tools))
	for _, tool := range t.Tools {
		srcName := (*tool).GetSourceName()
		var src sources.Source
		var ok bool
		if srcName != "" {
			src, ok = pMgr.GetSource(srcName)
			if !ok {
				return ToolsetManifest{}, fmt.Errorf("unable to retrieve %s source for tool %q", srcName, (*tool).GetName())
			}
		}
		m, err := (*tool).Manifest(src)
		if err != nil {
			return ToolsetManifest{}, fmt.Errorf("error generating manifest for tool %q: %w", (*tool).GetName(), err)
		}
		toolsManifest[(*tool).GetName()] = m
	}
	return ToolsetManifest{ServerVersion: t.Manifest.ServerVersion, ToolsManifest: toolsManifest}, nil
}

func (t ToolsetConfig) Initialize(serverVersion string, toolsMap map[string]Tool) (Toolset, error) {
	// finish toolset setup
	// Check each declared tool name exists
	toolset := Toolset{
		ToolsetConfig: t,
		Tools:         make([]*Tool, 0, len(t.ToolNames)),
		Manifest: ToolsetManifest{

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Ensure a source with the exact name the tool references is defined in the `sources:` section of the config
  2. Fix typos in the tool's `source:` field so it matches a defined source key
  3. Check startup logs for earlier source initialization failures that prevented registration
  4. If renaming a source, update every tool that references it

Example fix

// before (tools.yaml)
tools:
  run_query:
    kind: trino-execute-sql
    source: trino-prod
// after (with matching source defined)
sources:
  trino-prod:
    kind: trino
    host: trino.example.com
tools:
  run_query:
    kind: trino-execute-sql
    source: trino-prod
Defensive patterns

Strategy: validation

Validate before calling

definedSources := map[string]bool{"my-trino": true} // keys of sources: in config
for _, t := range toolsetTools {
    if t.Source != "" && !definedSources[t.Source] {
        return fmt.Errorf("tool %q references undefined source %q", t.Name, t.Source)
    }
}

Try / catch

manifest, err := tools.BuildManifest(toolset, pMgr)
if err != nil {
    if strings.Contains(err.Error(), "unable to retrieve") {
        // surface which source/tool pair to fix in the config
    }
    return err
}

Prevention

When it happens

Trigger: Calling BuildManifest on a toolset where tool.GetSourceName() returns a name absent from pMgr — the tool's `source:` field references a source not defined in the YAML, or the source block failed to load earlier.

Common situations: Typo in the tool's `source:` field; the corresponding source entry missing or commented out in the config; the source itself failed to initialize and was never added to the manager; renaming a source without updating tools that reference it.

Related errors


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