diff --git a/src/main/AryxAppService.ts b/src/main/AryxAppService.ts index 561b343..7bbb30b 100644 --- a/src/main/AryxAppService.ts +++ b/src/main/AryxAppService.ts @@ -2348,8 +2348,10 @@ export class AryxAppService extends EventEmitter { left?: DiscoveredToolingState, right?: DiscoveredToolingState, ): boolean { - return JSON.stringify(normalizeDiscoveredToolingState(left).mcpServers) - === JSON.stringify(normalizeDiscoveredToolingState(right).mcpServers); + const stripRuntime = (servers: DiscoveredMcpServer[]) => + servers.map(({ probedTools: _, ...rest }) => rest); + return JSON.stringify(stripRuntime(normalizeDiscoveredToolingState(left).mcpServers)) + === JSON.stringify(stripRuntime(normalizeDiscoveredToolingState(right).mcpServers)); } private equalProjectCustomizationState( diff --git a/src/shared/domain/discoveredTooling.ts b/src/shared/domain/discoveredTooling.ts index 8c5874f..65fc860 100644 --- a/src/shared/domain/discoveredTooling.ts +++ b/src/shared/domain/discoveredTooling.ts @@ -122,6 +122,7 @@ export function mergeDiscoveredToolingState( return { ...server, status: existing.status, + probedTools: existing.probedTools, } satisfies DiscoveredMcpServer; } diff --git a/tests/shared/discoveredTooling.test.ts b/tests/shared/discoveredTooling.test.ts index 9c9c18c..5521dd9 100644 --- a/tests/shared/discoveredTooling.test.ts +++ b/tests/shared/discoveredTooling.test.ts @@ -105,4 +105,50 @@ describe('discovered tooling helpers', () => { expect(listPendingDiscoveredMcpServers(dismissed)).toEqual([]); expect(dismissed.mcpServers[1]?.status).toBe('dismissed'); }); + + test('preserves probedTools when fingerprint is unchanged on re-scan', () => { + const probedTools = [ + { name: 'git_status', description: 'Get git status' }, + { name: 'git_diff', description: 'Get git diff' }, + ]; + const current = { + mcpServers: [ + createDiscoveredServer({ + status: 'accepted', + probedTools, + }), + ], + lastScannedAt: TIMESTAMP, + }; + + const merged = mergeDiscoveredToolingState( + current, + [createDiscoveredServer()], + '2026-03-25T01:00:00.000Z', + ); + + expect(merged.mcpServers[0]?.probedTools).toEqual(probedTools); + expect(merged.mcpServers[0]?.status).toBe('accepted'); + }); + + test('drops probedTools when fingerprint changes on re-scan', () => { + const current = { + mcpServers: [ + createDiscoveredServer({ + status: 'accepted', + probedTools: [{ name: 'git_status' }], + }), + ], + lastScannedAt: TIMESTAMP, + }; + + const merged = mergeDiscoveredToolingState( + current, + [createDiscoveredServer({ args: ['server.js', '--debug'] })], + '2026-03-25T01:00:00.000Z', + ); + + expect(merged.mcpServers[0]?.probedTools).toBeUndefined(); + expect(merged.mcpServers[0]?.status).toBe('pending'); + }); });