diff --git a/apps/mcp/src/server/client/index.ts b/apps/mcp/src/server/client/index.ts index a2ccc8e7..0005b59d 100644 --- a/apps/mcp/src/server/client/index.ts +++ b/apps/mcp/src/server/client/index.ts @@ -336,7 +336,12 @@ export class SupermemoryClient { options?: { signal?: AbortSignal }, ): Promise { try { - const signal = options?.signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS) + const signal = options?.signal + ? AbortSignal.any([ + options.signal, + AbortSignal.timeout(FETCH_TIMEOUT_MS), + ]) + : AbortSignal.timeout(FETCH_TIMEOUT_MS) const response = await fetch(`${this.apiUrl}/v3/documents/documents`, { method: "POST", headers: { diff --git a/packages/tools/src/shared/forget-memory.ts b/packages/tools/src/shared/forget-memory.ts index 8691c92a..2f326722 100644 --- a/packages/tools/src/shared/forget-memory.ts +++ b/packages/tools/src/shared/forget-memory.ts @@ -33,7 +33,9 @@ export async function forgetMemoryRequest( Authorization: `Bearer ${apiKey}`, }, body: JSON.stringify(params), - signal: options?.signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS), + signal: options?.signal + ? AbortSignal.any([options.signal, AbortSignal.timeout(FETCH_TIMEOUT_MS)]) + : AbortSignal.timeout(FETCH_TIMEOUT_MS), }) if (!response.ok) { diff --git a/packages/tools/src/tool-operations.test.ts b/packages/tools/src/tool-operations.test.ts index 8efef91d..5e0fc61d 100644 --- a/packages/tools/src/tool-operations.test.ts +++ b/packages/tools/src/tool-operations.test.ts @@ -180,7 +180,7 @@ describe("memoryForget", () => { expect(init.signal).toBeInstanceOf(AbortSignal) }) - it("uses a caller-provided signal instead of creating a timeout", async () => { + it("composes a caller-provided signal with the timeout", async () => { const fetchMock = stubFetch() const controller = new AbortController() @@ -192,7 +192,10 @@ describe("memoryForget", () => { ) const [, init] = fetchMock.mock.calls[0] as [string, RequestInit] - expect(init.signal).toBe(controller.signal) + expect(init.signal).toBeInstanceOf(AbortSignal) + expect(init.signal?.aborted).toBe(false) + controller.abort() + expect(init.signal?.aborted).toBe(true) }) it("throws a descriptive error on non-2xx responses", async () => {