
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ee98228e-818f-5fa0-9ac1-b798ee69b91d")}catch(e){}}();
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import log from '@apify/log';
import { TimeoutError } from '../errors.js';
import { getHttpStatusCode } from '../utils/logging.js';
import { ACTORIZED_MCP_CONNECTION_TIMEOUT_MSEC } from './const.js';
import { getMCPServerID } from './proxy.js';
/**
 * Creates and connects a ModelContextProtocol client.
 * First tries streamable HTTP transport, then falls back to SSE transport.
 */
export async function connectMCPClient(url, token, mcpSessionId) {
    try {
        return await createMCPStreamableClient(url, token);
    }
    catch (error) {
        // If streamable HTTP transport fails on not timeout error, continue with SSE transport
        if (error instanceof TimeoutError) {
            log.warning('Connection to MCP server using streamable HTTP transport timed out', { url, mcpSessionId });
            return null;
        }
        // If streamable HTTP transport fails, fall back to SSE transport
        log.debug('Streamable HTTP transport failed, falling back to SSE transport', {
            url,
            mcpSessionId,
            statusCode: getHttpStatusCode(error),
            errMessage: error instanceof Error ? error.message : String(error),
        });
    }
    try {
        return await createMCPSSEClient(url, token);
    }
    catch (error) {
        if (error instanceof TimeoutError) {
            log.warning('Connection to MCP server using SSE transport timed out', { url, mcpSessionId });
            return null;
        }
        // External MCP server unavailability is operational, not a bug.
        // Mezmo (logDNA) promotes log entries to errors when the message contains "error"
        // Sanitize the error message to preserve the soft-fail log level.
        const errMessage = (error instanceof Error ? error.message : String(error)).replace(/ error:/gi, ' failure:');
        log.softFail('MCP server unreachable', {
            url,
            mcpSessionId,
            statusCode: getHttpStatusCode(error),
            errMessage,
        });
        return null;
    }
}
async function withTimeout(millis, promise) {
    let timeoutPid;
    const timeout = new Promise((_resolve, reject) => {
        timeoutPid = setTimeout(() => reject(new TimeoutError(`Timed out after ${millis} ms.`)), millis);
    });
    return Promise.race([
        promise,
        timeout,
    ]).finally(() => clearTimeout(timeoutPid));
}
async function connectWithTransport(url, transport) {
    const client = new Client({
        name: getMCPServerID(url),
        version: '1.0.0',
    });
    await withTimeout(ACTORIZED_MCP_CONNECTION_TIMEOUT_MSEC, client.connect(transport));
    return client;
}
/**
 * Creates and connects a ModelContextProtocol client using the SSE transport.
 */
async function createMCPSSEClient(url, token) {
    const transport = new SSEClientTransport(new URL(url), {
        requestInit: {
            headers: {
                authorization: `Bearer ${token}`,
            },
        },
        eventSourceInit: {
            // The EventSource package augments EventSourceInit with a "fetch" parameter.
            // You can use this to set additional headers on the outgoing request.
            // Based on this example: https://github.com/modelcontextprotocol/typescript-sdk/issues/118
            async fetch(input, init) {
                const headers = new Headers((init === null || init === void 0 ? void 0 : init.headers) || {});
                headers.set('authorization', `Bearer ${token}`);
                return fetch(input, { ...init, headers });
            },
            // We have to cast to "any" to use it, since it's non-standard
        }, // eslint-disable-line @typescript-eslint/no-explicit-any
    });
    return await connectWithTransport(url, transport);
}
/**
 * Creates and connects a ModelContextProtocol client using the streamable HTTP transport.
 */
async function createMCPStreamableClient(url, token) {
    const transport = new StreamableHTTPClientTransport(new URL(url), {
        requestInit: {
            headers: {
                authorization: `Bearer ${token}`,
            },
        },
    });
    return await connectWithTransport(url, transport);
}
//# sourceMappingURL=client.js.map
//# debugId=ee98228e-818f-5fa0-9ac1-b798ee69b91d
