From a16d95a7e57197d7bc165a3b9d4da9b8516e76c5 Mon Sep 17 00:00:00 2001 From: Casey Chow Date: Wed, 11 Feb 2026 17:29:19 -0500 Subject: [PATCH 1/2] Declare elicitation form/url client capabilities --- client/src/lib/hooks/__tests__/useConnection.test.tsx | 5 ++++- client/src/lib/hooks/useConnection.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/lib/hooks/__tests__/useConnection.test.tsx b/client/src/lib/hooks/__tests__/useConnection.test.tsx index 4907a085b..877bb4add 100644 --- a/client/src/lib/hooks/__tests__/useConnection.test.tsx +++ b/client/src/lib/hooks/__tests__/useConnection.test.tsx @@ -518,7 +518,10 @@ describe("useConnection", () => { }), expect.objectContaining({ capabilities: expect.objectContaining({ - elicitation: {}, + elicitation: expect.objectContaining({ + form: {}, + url: {}, + }), }), }), ); diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index e14d1037f..590692b28 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -452,7 +452,10 @@ export function useConnection({ const clientCapabilities = { capabilities: { sampling: {}, - elicitation: {}, + elicitation: { + form: {}, + url: {}, + }, roots: { listChanged: true, }, From c6c855620889ec07f129e97098d41b1a2a877877 Mon Sep 17 00:00:00 2001 From: Casey Chow Date: Thu, 12 Feb 2026 14:32:44 -0500 Subject: [PATCH 2/2] Remove URL elicitation capability declaration --- .../hooks/__tests__/useConnection.test.tsx | 55 ++++++++++++++++++- client/src/lib/hooks/useConnection.ts | 9 ++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/client/src/lib/hooks/__tests__/useConnection.test.tsx b/client/src/lib/hooks/__tests__/useConnection.test.tsx index 877bb4add..ce97215f9 100644 --- a/client/src/lib/hooks/__tests__/useConnection.test.tsx +++ b/client/src/lib/hooks/__tests__/useConnection.test.tsx @@ -520,13 +520,66 @@ describe("useConnection", () => { capabilities: expect.objectContaining({ elicitation: expect.objectContaining({ form: {}, - url: {}, }), }), }), ); }); + test("declines URL elicitation requests and continues supporting form requests", async () => { + const mockOnElicitationRequest = jest.fn(); + const propsWithElicitation = { + ...defaultProps, + onElicitationRequest: mockOnElicitationRequest, + }; + + const { result } = renderHook(() => useConnection(propsWithElicitation)); + + await act(async () => { + await result.current.connect(); + }); + + const elicitRequestHandlerCall = + mockClient.setRequestHandler.mock.calls.find((call) => { + try { + const schema = call[0]; + const testRequest = { + method: "elicitation/create", + params: { + mode: "url", + message: "please continue", + url: "https://example.com", + elicitationId: "id-1", + }, + }; + const parseResult = + schema.safeParse && schema.safeParse(testRequest); + return parseResult?.success; + } catch { + return false; + } + }); + + expect(elicitRequestHandlerCall).toBeDefined(); + const [, handler] = elicitRequestHandlerCall; + + let urlResult: unknown; + await act(async () => { + urlResult = await handler({ + method: "elicitation/create", + params: { + mode: "url", + message: "please continue", + url: "https://example.com", + elicitationId: "id-1", + }, + }); + }); + + expect(urlResult).toEqual({ action: "decline" }); + expect(mockOnElicitationRequest).not.toHaveBeenCalled(); + }); + test("sets up elicitation request handler when onElicitationRequest is provided", async () => { const mockOnElicitationRequest = jest.fn(); const propsWithElicitation = { diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 590692b28..ec5e82d4c 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -454,7 +454,6 @@ export function useConnection({ sampling: {}, elicitation: { form: {}, - url: {}, }, roots: { listChanged: true, @@ -1059,6 +1058,14 @@ export function useConnection({ if (onElicitationRequest) { client.setRequestHandler(ElicitRequestSchema, (request) => { + const requestedMode = ( + request as { params?: { mode?: "form" | "url" } } + ).params?.mode; + + if (requestedMode === "url") { + return Promise.resolve({ action: "decline" }); + } + const taskSpec = (request as { params?: { task?: { ttl?: number } } }) .params?.task;