CherryHQ/cherry-studio · warning · McpError

MethodNotFound

MethodNotFound

Error message

Unknown tool: ${toolName}

What it means

The outer switch in callTool dispatches over CRON_TOOL_NAME, NOTIFY_TOOL_NAME, CONFIG_TOOL_NAME; any other toolName falls to default and throws McpError(ErrorCode.MethodNotFound, 'Unknown tool: ${toolName}'). This is the autonomy server's equivalent of a 404 for tool routing.

Source

Thrown at src/main/ai/mcp/servers/cherryAutonomyTools.ts:323

            case 'update_channel':
              return await this.configUpdateChannel(args)
            case 'remove_channel':
              return await this.configRemoveChannel(args)
            case 'reconnect_channel':
              return await this.configReconnectChannel(args)
            case 'complete_bootstrap':
              return this.configCompleteBootstrap()
            case 'reset_bootstrap':
              return this.configResetBootstrap()
            default:
              throw new McpError(
                ErrorCode.InvalidParams,
                `Unknown action "${action}", expected status/rename/add_channel/update_channel/remove_channel/reconnect_channel/complete_bootstrap/reset_bootstrap`
              )
          }
        }
        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}`, { agentId: this.agentId, error: message })
      return {
        content: [{ type: 'text' as const, text: `Error: ${message}` }],
        isError: true
      }
    }
  }

  private async addJob(args: Record<string, unknown>) {
    const name = args.name as string | undefined
    const message = args.message as string | undefined
    const cronExpr = args.cron as string | undefined
    const every = args.every as string | undefined
    const at = args.at as string | undefined
    const rawChannelIds = args.channel_ids as string[] | undefined

View on GitHub (pinned to 726446b54c)

Solutions

  1. Call ListTools on the cherry-tools server and only invoke names it advertises (cron/notify/config).
  2. Verify the tool name spelling and casing.
  3. If the tool belongs elsewhere (e.g. brave search, browser), route the call to that server.

Example fix

// before
server.callTool({ name: 'schedule', arguments: {...} })

// after — use the registered cron tool name
server.callTool({ name: CRON_TOOL_NAME, arguments: { action: 'add', ... } })
Defensive patterns

Strategy: validation

Validate before calling

const AUTONOMY_TOOLS = new Set([CRON_TOOL_NAME, NOTIFY_TOOL_NAME, CONFIG_TOOL_NAME])
function validateAutonomyTool(name: unknown) {
  if (typeof name !== 'string' || !AUTONOMY_TOOLS.has(name)) {
    throw new Error(`Unknown tool: ${name}. This server exposes: ${[...AUTONOMITY_TOOLS].join(', ')}`)
  }
}

Type guard

function isAutonomyTool(v: unknown): boolean {
  return typeof v === 'string' && [CRON_TOOL_NAME, NOTIFY_TOOL_NAME, CONFIG_TOOL_NAME].includes(v)
}

Try / catch

if (!isAutonomyTool(name)) {
  return { content: [{ type: 'text', text: `Unknown tool on autonomy server: ${name}` }], isError: true }
}

Prevention

When it happens

Trigger: Calling the cherry-tools autonomy server with a tool name that is not cron, notify, or config — a typo, a hallucinated name, or a tool belonging to a different server.

Common situations: Agent assumes a tool exists on this server (e.g. 'search', 'email'); casing mismatch; client routed the call to the wrong server; tool was renamed in an upgrade.

Related errors


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