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

GenerateListToolsResult fetches each tool's backing source via pMgr.GetSource(tool.GetSourceName()) so tool parameters can be generated. If the source name is registered on the tool but no such source exists in the manager, it returns "unable to retrieve %s source for tool %q". The tool→source wiring in the config is broken.

Source

Thrown at internal/server/mcp/v20260728/manifests.go:129

		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
		}
		toolManifest := generateToolManifest(toolName, tool.GetDescription(), tool.GetAuthRequired(), params, tool.GetAnnotations(src), urlParams)
		mcpManifest = append(mcpManifest, toolManifest)
	}
	res := ListToolsResult{
		Tools: mcpManifest,
		Result: Result{
			ResultType: resultTypeComplete,

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Check that a source with exactly that name exists under `sources:` in the YAML config.
  2. Look at startup logs for source initialization failures (bad DSN, missing env vars) that prevented registration.
  3. Fix the tool's `source:` field to reference the correct source name.
  4. Validate the full config loads cleanly before serving (run the server and confirm no config errors at startup).

Example fix

// before
tools:
  execute_sql:
    kind: postgres-execute-sql
    source: mydb   # no such source
// after
sources:
  my-pg:
    kind: postgres
    uri: ${POSTGRES_URI}
tools:
  execute_sql:
    kind: postgres-execute-sql
    source: my-pg
Defensive patterns

Strategy: validation

Validate before calling

// Config sanity check before serving (server side):
for (const [name, tool] of Object.entries(config.tools)) {
  if (!(tool.source in (config.sources ?? {}))) {
    throw new Error(`tool ${name} references missing source ${tool.source}`);
  }
}

Try / catch

try {
  const {tools} = await client.request({method:'tools/list'});
} catch (e) {
  if (String(e.message).includes('unable to retrieve') && String(e.message).includes('source for tool')) {
    console.error('Tool references a missing source; fix the sources: block:', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: A tool's `source:` field names a source that is not defined (or failed to initialize) in the `sources:` section of the config, so GetSource(srcName) returns !ok while building the tools/list manifest.

Common situations: Typo in the tool's `source` value, source block deleted or renamed while tools still reference it, source failing at startup due to missing credentials/env vars causing it not to register, or copying a tool entry between configs without its source.

Related errors


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