CherryHQ/cherry-studio · error · McpError

MethodNotFound

MethodNotFound

Error message

Unknown tool: ${toolName}

What it means

The AssistantServer CallToolRequest handler knows five tools: navigate, diagnose, product_info, apply_setting, create_agent. Any other tool name hits the default branch and throws McpError with ErrorCode.MethodNotFound. This is the protocol-correct rejection of unsupported tools.

Source

Thrown at src/main/ai/mcp/servers/assistant.ts:272

    this.mcpServer.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const toolName = request.params.name
      const args = request.params.arguments ?? {}

      try {
        switch (toolName) {
          case 'navigate':
            return await this.navigate(args as Record<string, string | Record<string, string> | undefined>)
          case 'diagnose':
            return await this.diagnose(args)
          case 'product_info':
            return await this.productInfo(args)
          case 'apply_setting':
            return await this.applySetting(args as Record<string, string | undefined>)
          case 'create_agent':
            return await this.createAgent(args as Record<string, string | undefined>)
          default:
            throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`)
        }
      } catch (error) {
        const message = error instanceof Error ? error.message : String(error)
        logger.error(`Tool error: ${toolName}`, { error: message })
        return {
          content: [{ type: 'text' as const, text: `Error: ${message}` }],
          isError: true
        }
      }
    })
  }

  private readProductManifest(): Record<string, unknown> {
    const manifestPath = application.getPath('feature.agents.assistant.manifest.file')
    let rawManifest: string
    try {
      rawManifest = fs.readFileSync(manifestPath, 'utf-8')
    } catch {

View on GitHub (pinned to 726446b54c)

Solutions

  1. Call ListTools to get the current advertised set before invoking.
  2. Confirm you are targeting the 'assistant' server.
  3. Update the client to the server's tool surface.

Example fix

// before
await assistant.callTool({ name: 'translate', arguments: {...} })

// after
await assistant.callTool({ name: 'diagnose', arguments: { action: 'info' } })
Defensive patterns

Strategy: validation

Validate before calling

const ASSISTANT_TOOLS = new Set(['navigate', 'diagnose', 'product_info', 'apply_setting', 'create_agent'])
// Client-side:
if (!ASSISTANT_TOOLS.has(toolName)) {
  throw new Error(`'${toolName}' is not offered by the assistant server`)
}

Type guard

function isAssistantTool(name: string): boolean {
  return ['navigate', 'diagnose', 'product_info', 'apply_setting', 'create_agent'].includes(name)
}

Prevention

When it happens

Trigger: An MCP client sends a CallToolRequest with a name not among the five advertised tools. Common with stale client tool caches, misrouted requests, or an LLM hallucinating a tool name.

Common situations: Client/server version skew where the client believes a removed tool still exists; a generic MCP probe; a bug in the router sending the call to the assistant server instead of the intended one.

Related errors


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