yikart/AiToEarn · error · McpError
MethodNotFound
MethodNotFound
Error message
Unknown tool: ${request.params.name} What it means
In the tools/call handler, registry.findTool looks up the tool by name for this mcpModuleId before any execution. If no tool metadata is registered under that name, the handler throws McpError MethodNotFound, matching JSON-RPC -32601 semantics.
Source
Thrown at project/aitoearn-backend/libs/nest-mcp/src/services/handlers/mcp-tools.handler.ts:121
})
return {
tools,
}
})
mcpServer.server.setRequestHandler(
CallToolRequestSchema,
async (request) => {
this.logger.debug('CallToolRequestSchema is being called')
const toolInfo = this.registry.findTool(
this.mcpModuleId,
request.params.name,
)
if (!toolInfo) {
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${request.params.name}`,
)
}
try {
// Validate input parameters against the tool's schema
if (toolInfo.metadata.parameters) {
const validation = toolInfo.metadata.parameters.safeParse(
request.params.arguments || {},
)
if (!validation.success) {
throw new McpError(
ErrorCode.InvalidParams,
`Invalid parameters: ${validation.error.message}`,
)
}
// Use validated arguments to ensure defaults and transformations are appliedView on GitHub (pinned to d3aa8bea5b)
Solutions
- Call tools/list and use the exact returned tool name
- Verify the tool's provider class is registered for the correct mcpModuleId
- Fix the tool name typo in the client
- Restart/redeploy so newly added tools are registered
Example fix
// before
await client.callTool({ name: 'send_post', arguments });
// after
const { tools } = await client.listTools();
await client.callTool({ name: tools.find(t => t.name.includes('post'))!.name, arguments }); Defensive patterns
Strategy: validation
Validate before calling
const { tools } = await client.listTools();
const tool = tools.find(t => t.name === name);
if (!tool) throw new Error(`Tool ${name} not available on this server`); Type guard
function toolExists(name: string, tools: { name: string }[]): boolean {
return tools.some(t => t.name === name);
} Try / catch
try {
await client.callTool({ name, arguments });
} catch (e) {
if (e.code === ErrorCode.MethodNotFound) {
await refreshToolList();
if (!toolExists(name, currentTools)) throw new Error(`Tool ${name} removed`);
} else throw e;
} Prevention
- Call tools/list before invoking and cache with a short TTL
- Use exact tool names from the server, not from memory/docs
- Confirm the tool's provider is registered for the target mcpModuleId
- Verify you are calling the correct environment's server
When it happens
Trigger: Client calls tools/call with a name not registered via @McpTool in this module, a typo'd name, or a tool registered under a different mcpModuleId.
Common situations: Stale client-side tool list after server restart/rename; tool defined but its provider never registered in the module; calling a tool on the wrong server (CN vs international) where the module differs.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/3ac459ef1aa7ce28.
Report an issue: GitHub.