CherryHQ/cherry-studio · error · Error

Unknown tool: ${name}

Error message

Unknown tool: ${name}

What it means

Default branch of the filesystem server's tool dispatch switch. Reached when request.params.name is not glob/ls/grep/read/edit/write/delete. Unlike the fetch server, the handler is wrapped in try/catch (server.ts:80-117) so this throw is converted into an isError tool result, not a transport error. It signals that the client called a tool the server never advertised in ListTools.

Source

Thrown at src/main/ai/mcp/servers/filesystem/server.ts:107

            return await handleLsTool(args, this.baseDir)

          case 'grep':
            return await handleGrepTool(args, this.baseDir)

          case 'read':
            return await handleReadTool(args, this.baseDir)

          case 'edit':
            return await handleEditTool(args, this.baseDir)

          case 'write':
            return await handleWriteTool(args, this.baseDir)

          case 'delete':
            return await handleDeleteTool(args, this.baseDir)

          default:
            throw new Error(`Unknown tool: ${name}`)
        }
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error)
        logger.error(`Tool execution error for ${request.params.name}:`, { error })
        return {
          content: [{ type: 'text', text: `Error: ${errorMessage}` }],
          isError: true
        }
      }
    })
  }
}

export default FileSystemServer

View on GitHub (pinned to 726446b54c)

Solutions

  1. Verify the called name is exactly one of: glob, ls, grep, read, edit, write, delete (lowercase, no prefix).
  2. Have the client re-fetch the tool list via ListTools before dispatching, rather than trusting a stale cache.
  3. When adding/removing tools, keep the ListTools array (server.ts:65-77) and the switch cases in lockstep.

Example fix

// before
default:
  throw new Error(`Unknown tool: ${name}`)

// after — record the miss so version skew is diagnosable
const KNOWN = ['glob','ls','grep','read','edit','write','delete']
default:
  logger.warn('Unknown tool called', { name, known: KNOWN })
  throw new Error(`Unknown tool: ${name}. Available: ${KNOWN.join(', ')}`)
Defensive patterns

Strategy: validation

Validate before calling

// Validate the tool name against the registered filesystem tools.
const FS_TOOLS = new Set(['glob', 'ls', 'grep', 'read', 'edit', 'write', 'delete'])
function isFsTool(name: unknown): name is string {
  return typeof name === 'string' && FS_TOOLS.has(name)
}

Type guard

function isKnownFsTool(name: string): boolean {
  return ['glob', 'ls', 'grep', 'read', 'edit', 'write', 'delete'].includes(name)
}

Prevention

When it happens

Trigger: An MCP client sends a CallToolRequest with a name outside the seven registered tools — a typo, a future/legacy tool name, or a name belonging to a different MCP server the client is confusing this with.

Common situations: Client built against an older or newer server version that had a different tool set; a model inventing a tool name like 'move' or 'copy' that was never implemented; orchestrator routing a request to the wrong server.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/a0195ae986de1d70. Report an issue: GitHub.