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[] | undefinedView on GitHub (pinned to 726446b54c)
Solutions
- Call ListTools on the cherry-tools server and only invoke names it advertises (cron/notify/config).
- Verify the tool name spelling and casing.
- 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
- Call ListTools to discover the exact tool names.
- Route tools to the correct server (brave/browser live elsewhere).
- Verify casing.
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
- InvalidParams
- Unknown chat type: ${type}
- Invalid command: command must be a non-empty string
- Invalid command: command cannot be empty
- Invalid args: must be an array
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/2e7f31743760607f.
Report an issue: GitHub.