googleapis/mcp-toolbox · error

INVALID_PARAMS

INVALID_PARAMS

Error message

invalid tool name: tool with name %q does not exist

What it means

Before resolving a tool globally, toolsCallHandler verifies the requested tool belongs to the active authorization group (g.ContainsTool). If the tool name is not in the current group's allowlist, the server returns JSON-RPC INVALID_PARAMS with 'invalid tool name: tool with name %q does not exist'. This enforces per-group/per-invocation tool scoping.

Source

Thrown at internal/server/mcp/v20250618/method.go:170

		err = fmt.Errorf("invalid mcp tools call request: %w", err)
		return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err
	}

	toolName := req.Params.Name
	toolArgument := req.Params.Arguments
	logger.DebugContext(ctx, fmt.Sprintf("tool name: %s", toolName))

	// Update span name and set gen_ai attributes
	span := trace.SpanFromContext(ctx)
	span.SetName(fmt.Sprintf("%s %s", TOOLS_CALL, toolName))
	span.SetAttributes(
		attribute.String("gen_ai.tool.name", toolName),
		attribute.String("gen_ai.operation.name", "execute_tool"),
	)

	// Verify tool belongs to the current group before resolving globally.
	if !g.ContainsTool(toolName) {
		err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
		return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
	}

	tool, ok := primitiveMgr.GetTool(toolName)
	if !ok {
		err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
		return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
	}

	if tool.HasSecureParams() {
		err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
		return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
	}

	srcName := tool.GetSourceName()
	var src sources.Source
	if srcName != "" {
		src, ok = primitiveMgr.GetSource(srcName)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Call tools/list for your current session/group and use a name exactly from that result
  2. Check your group/allowlist configuration and add the tool to the group if it should be callable
  3. Confirm any URL query filters (e.g. tool name filters) are not excluding the tool for this request
  4. Fix typos — the %q in the message shows the exact name the server received

Example fix

// before
{"name":"execute_sql","arguments":{}}
// after
{"name":"execute-sql","arguments":{}}
Defensive patterns

Strategy: validation

Validate before calling

const listed = await listTools();
const names = new Set(listed.tools.map(t => t.name));
if (!names.has("execute-sql")) throw new Error("tool not available in this group/session");

Type guard

function isToolAvailable(name: string, listed: { tools: { name: string }[] }): boolean {
  return listed.tools.some(t => t.name === name);
}

Try / catch

try { const res = await callTool(name, args); } catch (e) { if (e.code === -32602 && /does not exist/.test(e.message)) { await refreshToolList(); } else throw e; }

Prevention

When it happens

Trigger: Calling tools/call with a params.name that exists in the toolbox config but is not included in the current group's tool allowlist — e.g. calling a tool that was filtered out by the group or URL-parameter filters used for this invocation.

Common situations: Using a group/restricted client setup where the allowlist omits the tool; stale client-side tool cache from before the group config changed; typos in the tool name when calling directly via HTTP.

Related errors


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