({
client: connectedClient,
clientConnection,
tool,
args,
meta,
signal,
setAppState,
onProgress,
callToolFn = callMCPTool,
handleElicitation,
}: {
client: ConnectedMCPServer
clientConnection: MCPServerConnection
tool: string
args: Record<string, unknown>
meta?: Record<string, unknown>
signal: AbortSignal
setAppState: (f: (prev: AppState) => AppState) => void
onProgress?: (data: MCPProgress) => void
/** Injectable for testing. Defaults to callMCPTool. */
callToolFn?: (opts: {
client: ConnectedMCPServer
tool: string
args: Record<string, unknown>
meta?: Record<string, unknown>
signal: AbortSignal
onProgress?: (data: MCPProgress) => void
}) => Promise<MCPToolCallResult>
/** Handler for URL elicitations when no hook handles them.
* In print/SDK mode, delegates to structuredIO. In REPL, falls back to queue. */
handleElicitation?: (
serverName: string,
params: ElicitRequestURLParams,
signal: AbortSignal,
) => Promise<ElicitResult>
})
| 2811 | |
| 2812 | /** @internal Exported for testing. */ |
| 2813 | export async function callMCPToolWithUrlElicitationRetry({ |
| 2814 | client: connectedClient, |
| 2815 | clientConnection, |
| 2816 | tool, |
| 2817 | args, |
| 2818 | meta, |
| 2819 | signal, |
| 2820 | setAppState, |
| 2821 | onProgress, |
| 2822 | callToolFn = callMCPTool, |
| 2823 | handleElicitation, |
| 2824 | }: { |
| 2825 | client: ConnectedMCPServer |
| 2826 | clientConnection: MCPServerConnection |
| 2827 | tool: string |
| 2828 | args: Record<string, unknown> |
| 2829 | meta?: Record<string, unknown> |
| 2830 | signal: AbortSignal |
| 2831 | setAppState: (f: (prev: AppState) => AppState) => void |
| 2832 | onProgress?: (data: MCPProgress) => void |
| 2833 | /** Injectable for testing. Defaults to callMCPTool. */ |
| 2834 | callToolFn?: (opts: { |
| 2835 | client: ConnectedMCPServer |
| 2836 | tool: string |
| 2837 | args: Record<string, unknown> |
| 2838 | meta?: Record<string, unknown> |
| 2839 | signal: AbortSignal |
| 2840 | onProgress?: (data: MCPProgress) => void |
| 2841 | }) => Promise<MCPToolCallResult> |
| 2842 | /** Handler for URL elicitations when no hook handles them. |
| 2843 | * In print/SDK mode, delegates to structuredIO. In REPL, falls back to queue. */ |
| 2844 | handleElicitation?: ( |
| 2845 | serverName: string, |
| 2846 | params: ElicitRequestURLParams, |
| 2847 | signal: AbortSignal, |
| 2848 | ) => Promise<ElicitResult> |
| 2849 | }): Promise<MCPToolCallResult> { |
| 2850 | const MAX_URL_ELICITATION_RETRIES = 3 |
| 2851 | for (let attempt = 0; ; attempt++) { |
| 2852 | try { |
| 2853 | return await callToolFn({ |
| 2854 | client: connectedClient, |
| 2855 | tool, |
| 2856 | args, |
| 2857 | meta, |
| 2858 | signal, |
| 2859 | onProgress, |
| 2860 | }) |
| 2861 | } catch (error) { |
| 2862 | // The MCP SDK's Protocol creates plain McpError (not UrlElicitationRequiredError) |
| 2863 | // for error responses, so we check the error code instead of instanceof. |
| 2864 | if ( |
| 2865 | !(error instanceof McpError) || |
| 2866 | error.code !== ErrorCode.UrlElicitationRequired |
| 2867 | ) { |
| 2868 | throw error |
| 2869 | } |
| 2870 |
no test coverage detected