{"record":{"id":"951568c0ca76555d","repo":"ruvnet/ruflo","slug":"failed-to-register-mcp-tools-registration-faile","errorCode":null,"errorMessage":"Failed to register MCP tools: ${registration.failed.join(', ')}","messagePattern":"Failed to register MCP tools: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-server.ts","lineNumber":767,"sourceCode":"    const dualLoopback = this.options.host === 'localhost';\n    const mcpServer = createMCPServer(\n      {\n        name: 'Claude-Flow MCP Server V3',\n        version: '3.0.0',\n        transport: this.options.transport as 'http' | 'websocket',\n        host: dualLoopback ? '127.0.0.1' : this.options.host,\n        additionalHosts: dualLoopback && this.options.transport === 'http' ? ['::1'] : undefined,\n        port: this.options.port,\n        enableMetrics: true,\n        enableCaching: true,\n      },\n      logger\n    );\n    const registration = mcpServer.registerTools(\n      cliTools as Parameters<typeof mcpServer.registerTools>[0]\n    );\n    if (registration.failed.length > 0) {\n      throw new Error(`Failed to register MCP tools: ${registration.failed.join(', ')}`);\n    }\n    await mcpServer.start();\n    this.mcpServers = [mcpServer];\n  }\n\n  /**\n   * Wait for server to be ready\n   */\n  private async waitForReady(timeout = 10000): Promise<void> {\n    // For stdio transport, we're ready immediately (in-process)\n    if (this.options.transport === 'stdio') {\n      return;\n    }\n\n    const startTime = Date.now();\n\n    while (Date.now() - startTime < timeout) {\n      const health = await this.checkHealth();","sourceCodeStart":749,"sourceCodeEnd":785,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/mcp-server.ts#L749-L785","documentation":"When the server wires up its tools it calls registerTools(cliTools), which returns a per-tool registration result; if any tool fails to register (name collision, invalid definition), start aborts with the list of failed tool names. This is a fail-fast at boot: the server refuses to come up in a degraded state where some advertised tools are missing.","triggerScenarios":"Two plugins registering tools with the same name; a tool definition with a malformed schema or duplicate field; a custom tool added to cliTools whose name collides with a built-in; version skew where a plugin was built against a different registration API than the shipped server.","commonSituations":"Adding an in-house plugin that uses a generic name like 'search' that already exists; upgrading @claude-flow/cli while stale plugin builds remain in the plugins directory; forking built-ins without renaming.","solutions":["Read the comma-separated tool names in the message — those are exactly the definitions that failed","Find and rename the colliding definition (namespace custom tools, e.g. 'acme_search' instead of 'search') or disable the conflicting plugin","Validate the tool definition (unique name, well-formed inputSchema) before handing it to the server","Update all plugins and the CLI together so registration APIs match"],"exampleFix":"// before — custom tool collides with a built-in name\nconst myTools = [{ name: 'memory_search', /* ... */ }];\nserver.registerTools(myTools); // failed: memory_search\n\n// after — namespace custom tools\nconst myTools = [{ name: 'acme_memory_search', /* ... */ }];","handlingStrategy":"try-catch","validationCode":"// Validate names are unique before handing tools to the server\nconst seen = new Set<string>();\nfor (const t of myTools) {\n  if (seen.has(t.name)) throw new Error(`duplicate tool name: ${t.name}`);\n  seen.add(t.name);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await server.start();\n} catch (e) {\n  const m = /Failed to register MCP tools: (.+)/.exec((e as Error).message);\n  if (m) {\n    // m[1] lists exactly the colliding/invalid tool names — disable or rename them\n    throw new Error(`registration failed for: ${m[1]}. Rename/disable those tools.`);\n  }\n  throw e;\n}","preventionTips":["Namespace custom tool names (org/product prefix) to avoid built-in collisions","Assert a unique-name invariant in your tool loader before registration","Upgrade plugins and the CLI together so registration APIs stay compatible"],"tags":["mcp","tool-registration","name-collision","startup","plugins"],"backgroundTag":"tool-registration-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}