diff --git a/src/server/connections.ts b/src/server/connections.ts index 182b0368..47019694 100644 --- a/src/server/connections.ts +++ b/src/server/connections.ts @@ -165,7 +165,12 @@ export class ConnectionService { }); return await use(client, bounded); } finally { - await client.close().catch(() => {}); + await client.close().catch((error: unknown) => { + console.error( + 'Failed to close MCP client:', + error instanceof Error ? error.message : error, + ); + }); } } private async discover( diff --git a/src/server/parallel.ts b/src/server/parallel.ts index cf6f6131..f8d08fbd 100644 --- a/src/server/parallel.ts +++ b/src/server/parallel.ts @@ -195,6 +195,11 @@ export async function parallelSources( throw new Error('Parallel could not extract usable source evidence.'); return pages; } finally { - await client.close().catch(() => {}); + await client.close().catch((error: unknown) => { + console.error( + 'Failed to close MCP client:', + error instanceof Error ? error.message : error, + ); + }); } } diff --git a/tests/parallel.test.ts b/tests/parallel.test.ts index 82e79e9e..a0815d76 100644 --- a/tests/parallel.test.ts +++ b/tests/parallel.test.ts @@ -108,6 +108,22 @@ describe('Parallel research', () => { ), ).toHaveLength(1); }); + it('logs MCP client close failures instead of swallowing them', async () => { + mcp.callTool.mockResolvedValue(result(page())); + mcp.close.mockRejectedValueOnce(new Error('transport gone')); + const error = vi.spyOn(console, 'error').mockImplementation(() => {}); + const sources = await parallelSources( + { objective: 'Read', urls: ['https://example.com'] }, + {}, + signal, + ); + expect(sources).toHaveLength(1); + expect(error).toHaveBeenCalledWith( + 'Failed to close MCP client:', + 'transport gone', + ); + error.mockRestore(); + }); it('surfaces provider errors and closes the client', async () => { mcp.callTool.mockResolvedValue({ isError: true,