{"record":{"id":"de39a044ac27fd05","repo":"mastra-ai/mastra","slug":"mcp-client-on-list-changed-tools-failed","errorCode":"MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED","errorMessage":"MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED","messagePattern":"MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/client/configuration.ts","lineNumber":692,"sourceCode":"       *\n       * @param serverName - Name of the server to monitor\n       * @param handler - Callback function invoked when tools are added/removed/modified\n       * @returns Promise resolving when handler is registered\n       * @throws {MastraError} If setting up the handler fails\n       *\n       * @example\n       * ```typescript\n       * await mcp.tools.onListChanged('weatherServer', async () => {\n       *   const tools = await mcp.listTools();\n       * });\n       * ```\n       */\n      onListChanged: async (serverName: string, handler: () => void) => {\n        try {\n          const internalClient = await this.getConnectedClientForServer(serverName);\n          return internalClient.setToolListChangedNotificationHandler(handler);\n        } catch (error) {\n          throw new MastraError(\n            {\n              id: 'MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED',\n              domain: ErrorDomain.MCP,\n              category: ErrorCategory.THIRD_PARTY,\n              details: {\n                serverName,\n              },\n            },\n            error,\n          );\n        }\n      },\n    };\n  }\n\n  private addToInstanceCache() {\n    if (!mcpClientInstances.has(this.id)) {\n      mcpClientInstances.set(this.id, this);","sourceCodeStart":674,"sourceCodeEnd":710,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/client/configuration.ts#L674-L710","documentation":"MastraError thrown when registering a tool list-changed notification handler fails. Like the prompts variant, it resolves a connected client for the server and then calls setToolListChangedNotificationHandler; any failure to connect is wrapped with the serverName in details. It means tool change notifications cannot be subscribed for that server.","triggerScenarios":"Calling mcpClient.tools.onListChanged(serverName, handler) (or getToolsForServer paths that set it up) when the connection for serverName cannot be established.","commonSituations":"Server name typo; server not yet connected when wiring dynamic tool refresh; MCP server restarted and connection dropped before handler registration.","solutions":["Confirm serverName is configured and spelled correctly.","Establish the connection before calling onListChanged.","Inspect the wrapped cause for the transport-level failure (e.g., stdio spawn error, HTTP 4xx/5xx).","Re-register the handler after the client reconnects."],"exampleFix":"// before\nclient.tools.onListChanged(serverName, handler);\n// after\ntry {\n  client.tools.onListChanged(serverName, handler);\n} catch (e) {\n  logger.error('tool-list subscription failed', { serverName, cause: (e as MastraError).detail?.originalMessage });\n}\n","handlingStrategy":"try-catch","validationCode":"if (!Object.keys(configuredServers).includes(serverName)) throw new Error(`unknown server ${serverName}`);\nawait client.getConnectedClientForServer(serverName);","typeGuard":null,"tryCatchPattern":"try {\n  client.tools.onListChanged(serverName, handler);\n} catch (e) {\n  if (e instanceof MastraError && e.id === 'MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED') {\n    logger.error('tool list subscription failed', { serverName, cause: e });\n  } else throw e;\n}","preventionTips":["Wire tool-change subscriptions after initial connection succeeds.","Re-register handlers after reconnects.","Validate server names against config keys at startup.","Keep handler registration idempotent to survive retries."],"tags":["mcp","tools","notification","connection"],"backgroundTag":"mcp-subscription-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}