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 applied

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Call tools/list and use the exact returned tool name
  2. Verify the tool's provider class is registered for the correct mcpModuleId
  3. Fix the tool name typo in the client
  4. 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

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.