@mcp-z/client 2.2.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/dist/cjs/auth/capability-discovery.d.cts +3 -1
- package/dist/cjs/auth/capability-discovery.d.ts +3 -1
- package/dist/cjs/auth/capability-discovery.js +46 -32
- package/dist/cjs/auth/capability-discovery.js.map +1 -1
- package/dist/cjs/auth/discovery-fetch.d.cts +2 -0
- package/dist/cjs/auth/discovery-fetch.d.ts +2 -0
- package/dist/cjs/auth/discovery-fetch.js +85 -31
- package/dist/cjs/auth/discovery-fetch.js.map +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.d.cts +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.d.ts +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.js +13 -6
- package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -1
- package/dist/cjs/auth/oauth-callback-listener.d.cts +1 -1
- package/dist/cjs/auth/oauth-callback-listener.d.ts +1 -1
- package/dist/cjs/auth/oauth-callback-listener.js +40 -4
- package/dist/cjs/auth/oauth-callback-listener.js.map +1 -1
- package/dist/cjs/auth/rfc9728-discovery.d.cts +7 -2
- package/dist/cjs/auth/rfc9728-discovery.d.ts +7 -2
- package/dist/cjs/auth/rfc9728-discovery.js +120 -88
- package/dist/cjs/auth/rfc9728-discovery.js.map +1 -1
- package/dist/cjs/auth/types.d.cts +4 -0
- package/dist/cjs/auth/types.d.ts +4 -0
- package/dist/cjs/auth/types.js.map +1 -1
- package/dist/cjs/connection/connect-client.d.cts +9 -1
- package/dist/cjs/connection/connect-client.d.ts +9 -1
- package/dist/cjs/connection/connect-client.js +282 -75
- package/dist/cjs/connection/connect-client.js.map +1 -1
- package/dist/cjs/connection/existing-process-transport.d.cts +18 -18
- package/dist/cjs/connection/existing-process-transport.d.ts +18 -18
- package/dist/cjs/connection/existing-process-transport.js +187 -82
- package/dist/cjs/connection/existing-process-transport.js.map +1 -1
- package/dist/cjs/connection/wait-for-http-ready.d.cts +1 -1
- package/dist/cjs/connection/wait-for-http-ready.d.ts +1 -1
- package/dist/cjs/connection/wait-for-http-ready.js +30 -5
- package/dist/cjs/connection/wait-for-http-ready.js.map +1 -1
- package/dist/cjs/dcr/dcr-authenticator.d.cts +1 -1
- package/dist/cjs/dcr/dcr-authenticator.d.ts +1 -1
- package/dist/cjs/dcr/dcr-authenticator.js +29 -18
- package/dist/cjs/dcr/dcr-authenticator.js.map +1 -1
- package/dist/cjs/dcr/dynamic-client-registrar.js +2 -1
- package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/spawn/owned-process-tree.d.cts +12 -0
- package/dist/cjs/spawn/owned-process-tree.d.ts +12 -0
- package/dist/cjs/spawn/owned-process-tree.js +93 -0
- package/dist/cjs/spawn/owned-process-tree.js.map +1 -0
- package/dist/cjs/spawn/spawn-server.d.cts +8 -32
- package/dist/cjs/spawn/spawn-server.d.ts +8 -32
- package/dist/cjs/spawn/spawn-server.js +406 -97
- package/dist/cjs/spawn/spawn-server.js.map +1 -1
- package/dist/cjs/spawn/spawn-servers.d.cts +18 -8
- package/dist/cjs/spawn/spawn-servers.d.ts +18 -8
- package/dist/cjs/spawn/spawn-servers.js +342 -113
- package/dist/cjs/spawn/spawn-servers.js.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/path-utils.js +7 -4
- package/dist/cjs/utils/path-utils.js.map +1 -1
- package/dist/esm/auth/capability-discovery.d.ts +3 -1
- package/dist/esm/auth/capability-discovery.js +21 -11
- package/dist/esm/auth/capability-discovery.js.map +1 -1
- package/dist/esm/auth/discovery-fetch.d.ts +2 -0
- package/dist/esm/auth/discovery-fetch.js +64 -23
- package/dist/esm/auth/discovery-fetch.js.map +1 -1
- package/dist/esm/auth/interactive-oauth-flow.d.ts +1 -1
- package/dist/esm/auth/interactive-oauth-flow.js +13 -6
- package/dist/esm/auth/interactive-oauth-flow.js.map +1 -1
- package/dist/esm/auth/oauth-callback-listener.d.ts +1 -1
- package/dist/esm/auth/oauth-callback-listener.js +34 -4
- package/dist/esm/auth/oauth-callback-listener.js.map +1 -1
- package/dist/esm/auth/rfc9728-discovery.d.ts +7 -2
- package/dist/esm/auth/rfc9728-discovery.js +40 -16
- package/dist/esm/auth/rfc9728-discovery.js.map +1 -1
- package/dist/esm/auth/types.d.ts +4 -0
- package/dist/esm/auth/types.js.map +1 -1
- package/dist/esm/connection/connect-client.d.ts +9 -1
- package/dist/esm/connection/connect-client.js +97 -35
- package/dist/esm/connection/connect-client.js.map +1 -1
- package/dist/esm/connection/existing-process-transport.d.ts +18 -18
- package/dist/esm/connection/existing-process-transport.js +132 -70
- package/dist/esm/connection/existing-process-transport.js.map +1 -1
- package/dist/esm/connection/wait-for-http-ready.d.ts +1 -1
- package/dist/esm/connection/wait-for-http-ready.js +19 -4
- package/dist/esm/connection/wait-for-http-ready.js.map +1 -1
- package/dist/esm/dcr/dcr-authenticator.d.ts +1 -1
- package/dist/esm/dcr/dcr-authenticator.js +26 -15
- package/dist/esm/dcr/dcr-authenticator.js.map +1 -1
- package/dist/esm/dcr/dynamic-client-registrar.js +2 -1
- package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/spawn/owned-process-tree.d.ts +12 -0
- package/dist/esm/spawn/owned-process-tree.js +39 -0
- package/dist/esm/spawn/owned-process-tree.js.map +1 -0
- package/dist/esm/spawn/spawn-server.d.ts +8 -32
- package/dist/esm/spawn/spawn-server.js +228 -99
- package/dist/esm/spawn/spawn-server.js.map +1 -1
- package/dist/esm/spawn/spawn-servers.d.ts +18 -8
- package/dist/esm/spawn/spawn-servers.js +180 -55
- package/dist/esm/spawn/spawn-servers.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/path-utils.js +7 -4
- package/dist/esm/utils/path-utils.js.map +1 -1
- package/package.json +8 -3
- package/schemas/servers.d.ts +24 -0
- package/schemas/servers.schema.json +31 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/auth/types.ts"],"sourcesContent":["/**\n * Shared types for OAuth and DCR authentication\n */\n\n/**\n * OAuth callback result from authorization server\n */\nexport interface CallbackResult {\n /** Authorization code from OAuth server */\n code: string;\n /** State parameter for CSRF protection */\n state?: string;\n /** Issuer identifier of the authorization server that minted the response (RFC 9207) */\n iss?: string;\n}\n\n/**\n * PKCE (Proof Key for Code Exchange) parameters (RFC 7636)\n * Used to secure OAuth 2.0 authorization code flow for public clients\n */\nexport interface PkceParams {\n /** Code verifier - cryptographically random string (43-128 characters) */\n codeVerifier: string;\n /** Code challenge - derived from code verifier using challenge method */\n codeChallenge: string;\n /** Code challenge method - S256 (SHA-256) or plain */\n codeChallengeMethod: 'S256' | 'plain';\n}\n\n/**\n * OAuth token set with access and refresh tokens\n */\nexport interface TokenSet {\n /** Access token for API requests */\n accessToken: string;\n /** Refresh token for obtaining new access tokens */\n refreshToken: string;\n /** Timestamp when access token expires (milliseconds since epoch) */\n expiresAt: number;\n /** Scopes granted for this token set */\n scopes?: string[];\n /** Client ID used for DCR registration (stored for future use) */\n clientId?: string;\n /** Client secret used for DCR registration (stored for future use) */\n clientSecret?: string;\n /** Issuer identifier of the authorization server these credentials belong to (SEP-2352) */\n issuer?: string;\n}\n\n/**\n * OAuth 2.0 Protected Resource Metadata (RFC 9728)\n * Response from .well-known/oauth-protected-resource endpoint\n */\nexport interface ProtectedResourceMetadata {\n /** The protected resource identifier */\n resource: string;\n /** List of authorization server URLs that can issue tokens for this resource */\n authorization_servers: string[];\n /** Optional list of scopes supported by this resource */\n scopes_supported?: string[];\n /** Optional list of bearer token methods supported (header, query, body) */\n bearer_methods_supported?: string[];\n}\n\n/**\n * OAuth 2.0 Authorization Server Metadata (RFC 8414)\n * Response from .well-known/oauth-authorization-server endpoint\n */\nexport interface AuthorizationServerMetadata {\n /** The authorization server's issuer identifier */\n issuer?: string;\n /** URL of the authorization endpoint */\n authorization_endpoint?: string;\n /** URL of the token endpoint */\n token_endpoint?: string;\n /** URL of the client registration endpoint (DCR - RFC 7591) */\n registration_endpoint?: string;\n /** URL of the token introspection endpoint */\n introspection_endpoint?: string;\n /** List of OAuth scopes supported by the authorization server */\n scopes_supported?: string[];\n /** Response types supported (code, token, etc.) */\n response_types_supported?: string[];\n /** Grant types supported (authorization_code, refresh_token, etc.) */\n grant_types_supported?: string[];\n /** Token endpoint authentication methods supported */\n token_endpoint_auth_methods_supported?: string[];\n /** Whether the authorization response carries an `iss` parameter (RFC 9207) */\n authorization_response_iss_parameter_supported?: boolean;\n}\n\n/**\n * OAuth server capabilities discovered from .well-known endpoint\n */\nexport interface AuthCapabilities {\n /** Whether the server supports Dynamic Client Registration (RFC 7591) */\n supportsDcr: boolean;\n /** Issuer identifier from the authorization server metadata (RFC 8414) */\n issuer?: string;\n /**\n * The protected resource's canonical identifier, from the RFC 9728 metadata\n * document's `resource` field. This is what an RFC 8707 `resource` indicator\n * must carry, and it is the resource server's own statement of its identity -\n * not the URL we happened to dial, and never the base URL discovery was\n * performed against, which has any `/mcp` segment stripped off it.\n *\n * Absent when no protected-resource metadata was published and the\n * authorization server was reached by direct RFC 8414 discovery instead.\n */\n resource?: string;\n /** Whether the authorization response carries an `iss` parameter (RFC 9207) */\n authorizationResponseIssSupported?: boolean;\n /** DCR client registration endpoint */\n registrationEndpoint?: string;\n /** OAuth authorization endpoint */\n authorizationEndpoint?: string;\n /** OAuth token endpoint */\n tokenEndpoint?: string;\n /** Token introspection endpoint */\n introspectionEndpoint?: string;\n /** Supported OAuth scopes */\n scopes?: string[];\n}\n\n/**\n * Client credentials from DCR registration\n */\nexport interface ClientCredentials {\n /** OAuth client ID */\n clientId: string;\n /** OAuth client secret */\n clientSecret: string;\n /** Timestamp when client was registered */\n issuedAt?: number;\n}\n\n/**\n * Options for DCR client registration\n */\nexport interface DcrRegistrationOptions {\n /** Redirect URI for OAuth callback, from the loopback listener the caller has already bound (RFC 8252) */\n redirectUri: string;\n /** Client name to register */\n clientName?: string;\n /**\n * Loopback trust grant for the registration_endpoint fetch (SSRF\n * mitigation - see `src/auth/discovery-fetch.ts`). Compute this from the\n * MCP server the caller is actually talking to, never from\n * `registrationEndpoint` itself (which is typically sourced from\n * remote-controlled AS metadata). Defaults to `false`.\n */\n allowLoopback?: boolean;\n}\n\n/**\n * Options for OAuth authorization flow\n */\nexport interface OAuthFlowOptions {\n /** Port for OAuth callback listener (required - use get-port to find available port) */\n port: number;\n /** Issuer identifier discovered before the flow starts; the `iss` in the authorization response must match it (RFC 9207) */\n issuer: string;\n /** Canonical resource server URI, sent as `resource` on the authorization, token, and refresh requests (RFC 8707) */\n resource: string;\n /** Redirect URI for OAuth callback (optional - will be built from port if not provided) */\n redirectUri?: string;\n /** OAuth scopes to request */\n scopes?: string[];\n /** Whether the authorization server advertises `authorization_response_iss_parameter_supported` (RFC 9207) */\n authorizationResponseIssSupported?: boolean;\n /** Enable PKCE (RFC 7636) - recommended for all clients, required for public clients */\n pkce?: boolean;\n /** Headless mode (don't open browser) */\n headless?: boolean;\n /** Timeout for callback (milliseconds) */\n timeout?: number;\n /** Optional logger for debug output (defaults to singleton logger) */\n logger?: import('../utils/logger.ts').Logger;\n /**\n * Loopback trust grant for the token endpoint fetch (SSRF mitigation - see\n * `src/auth/discovery-fetch.ts`). Compute this from the MCP server the\n * caller is actually talking to, never from `tokenEndpoint` itself (which\n * is typically sourced from remote-controlled AS metadata). Defaults to\n * `false`.\n */\n allowLoopback?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GAED;;CAEC"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/auth/types.ts"],"sourcesContent":["/**\n * Shared types for OAuth and DCR authentication\n */\n\n/**\n * OAuth callback result from authorization server\n */\nexport interface CallbackResult {\n /** Authorization code from OAuth server */\n code: string;\n /** State parameter for CSRF protection */\n state?: string;\n /** Issuer identifier of the authorization server that minted the response (RFC 9207) */\n iss?: string;\n}\n\n/**\n * PKCE (Proof Key for Code Exchange) parameters (RFC 7636)\n * Used to secure OAuth 2.0 authorization code flow for public clients\n */\nexport interface PkceParams {\n /** Code verifier - cryptographically random string (43-128 characters) */\n codeVerifier: string;\n /** Code challenge - derived from code verifier using challenge method */\n codeChallenge: string;\n /** Code challenge method - S256 (SHA-256) or plain */\n codeChallengeMethod: 'S256' | 'plain';\n}\n\n/**\n * OAuth token set with access and refresh tokens\n */\nexport interface TokenSet {\n /** Access token for API requests */\n accessToken: string;\n /** Refresh token for obtaining new access tokens */\n refreshToken: string;\n /** Timestamp when access token expires (milliseconds since epoch) */\n expiresAt: number;\n /** Scopes granted for this token set */\n scopes?: string[];\n /** Client ID used for DCR registration (stored for future use) */\n clientId?: string;\n /** Client secret used for DCR registration (stored for future use) */\n clientSecret?: string;\n /** Issuer identifier of the authorization server these credentials belong to (SEP-2352) */\n issuer?: string;\n}\n\n/**\n * OAuth 2.0 Protected Resource Metadata (RFC 9728)\n * Response from .well-known/oauth-protected-resource endpoint\n */\nexport interface ProtectedResourceMetadata {\n /** The protected resource identifier */\n resource: string;\n /** List of authorization server URLs that can issue tokens for this resource */\n authorization_servers: string[];\n /** Optional list of scopes supported by this resource */\n scopes_supported?: string[];\n /** Optional list of bearer token methods supported (header, query, body) */\n bearer_methods_supported?: string[];\n}\n\n/**\n * OAuth 2.0 Authorization Server Metadata (RFC 8414)\n * Response from .well-known/oauth-authorization-server endpoint\n */\nexport interface AuthorizationServerMetadata {\n /** The authorization server's issuer identifier */\n issuer?: string;\n /** URL of the authorization endpoint */\n authorization_endpoint?: string;\n /** URL of the token endpoint */\n token_endpoint?: string;\n /** URL of the client registration endpoint (DCR - RFC 7591) */\n registration_endpoint?: string;\n /** URL of the token introspection endpoint */\n introspection_endpoint?: string;\n /** List of OAuth scopes supported by the authorization server */\n scopes_supported?: string[];\n /** Response types supported (code, token, etc.) */\n response_types_supported?: string[];\n /** Grant types supported (authorization_code, refresh_token, etc.) */\n grant_types_supported?: string[];\n /** Token endpoint authentication methods supported */\n token_endpoint_auth_methods_supported?: string[];\n /** Whether the authorization response carries an `iss` parameter (RFC 9207) */\n authorization_response_iss_parameter_supported?: boolean;\n}\n\n/**\n * OAuth server capabilities discovered from .well-known endpoint\n */\nexport interface AuthCapabilities {\n /** Whether the server supports Dynamic Client Registration (RFC 7591) */\n supportsDcr: boolean;\n /** Issuer identifier from the authorization server metadata (RFC 8414) */\n issuer?: string;\n /**\n * The protected resource's canonical identifier, from the RFC 9728 metadata\n * document's `resource` field. This is what an RFC 8707 `resource` indicator\n * must carry, and it is the resource server's own statement of its identity -\n * not the URL we happened to dial, and never the base URL discovery was\n * performed against, which has any `/mcp` segment stripped off it.\n *\n * Absent when no protected-resource metadata was published and the\n * authorization server was reached by direct RFC 8414 discovery instead.\n */\n resource?: string;\n /** Whether the authorization response carries an `iss` parameter (RFC 9207) */\n authorizationResponseIssSupported?: boolean;\n /** DCR client registration endpoint */\n registrationEndpoint?: string;\n /** OAuth authorization endpoint */\n authorizationEndpoint?: string;\n /** OAuth token endpoint */\n tokenEndpoint?: string;\n /** Token introspection endpoint */\n introspectionEndpoint?: string;\n /** Supported OAuth scopes */\n scopes?: string[];\n}\n\n/**\n * Client credentials from DCR registration\n */\nexport interface ClientCredentials {\n /** OAuth client ID */\n clientId: string;\n /** OAuth client secret */\n clientSecret: string;\n /** Timestamp when client was registered */\n issuedAt?: number;\n}\n\n/**\n * Options for DCR client registration\n */\nexport interface DcrRegistrationOptions {\n /** Redirect URI for OAuth callback, from the loopback listener the caller has already bound (RFC 8252) */\n redirectUri: string;\n /** Client name to register */\n clientName?: string;\n /**\n * Loopback trust grant for the registration_endpoint fetch (SSRF\n * mitigation - see `src/auth/discovery-fetch.ts`). Compute this from the\n * MCP server the caller is actually talking to, never from\n * `registrationEndpoint` itself (which is typically sourced from\n * remote-controlled AS metadata). Defaults to `false`.\n */\n allowLoopback?: boolean;\n /** Cancels an in-progress registration request. */\n signal?: AbortSignal;\n}\n\n/**\n * Options for OAuth authorization flow\n */\nexport interface OAuthFlowOptions {\n /** Cancels an in-progress authorization and closes its callback listener. */\n signal?: AbortSignal;\n /** Port for OAuth callback listener (required - use get-port to find available port) */\n port: number;\n /** Issuer identifier discovered before the flow starts; the `iss` in the authorization response must match it (RFC 9207) */\n issuer: string;\n /** Canonical resource server URI, sent as `resource` on the authorization, token, and refresh requests (RFC 8707) */\n resource: string;\n /** Redirect URI for OAuth callback (optional - will be built from port if not provided) */\n redirectUri?: string;\n /** OAuth scopes to request */\n scopes?: string[];\n /** Whether the authorization server advertises `authorization_response_iss_parameter_supported` (RFC 9207) */\n authorizationResponseIssSupported?: boolean;\n /** Enable PKCE (RFC 7636) - recommended for all clients, required for public clients */\n pkce?: boolean;\n /** Headless mode (don't open browser) */\n headless?: boolean;\n /** Timeout for callback (milliseconds) */\n timeout?: number;\n /** Optional logger for debug output (defaults to singleton logger) */\n logger?: import('../utils/logger.ts').Logger;\n /**\n * Loopback trust grant for the token endpoint fetch (SSRF mitigation - see\n * `src/auth/discovery-fetch.ts`). Compute this from the MCP server the\n * caller is actually talking to, never from `tokenEndpoint` itself (which\n * is typically sourced from remote-controlled AS metadata). Defaults to\n * `false`.\n */\n allowLoopback?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GAED;;CAEC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Helper to connect MCP SDK clients to servers with intelligent transport inference.
|
|
5
5
|
* Automatically detects transport type from URL protocol or type field.
|
|
6
6
|
*/
|
|
7
|
-
import type { VersionNegotiationOptions } from '@modelcontextprotocol/client';
|
|
7
|
+
import type { Transport, VersionNegotiationOptions } from '@modelcontextprotocol/client';
|
|
8
8
|
import { Client } from '@modelcontextprotocol/client';
|
|
9
9
|
import { type DcrAuthenticatorOptions } from '../dcr/index.js';
|
|
10
10
|
import type { ServerProcess } from '../spawn/spawn-server.js';
|
|
@@ -18,6 +18,12 @@ interface RegistryLike {
|
|
|
18
18
|
servers: Map<string, ServerProcess>;
|
|
19
19
|
}
|
|
20
20
|
import { type Logger } from '../utils/logger.js';
|
|
21
|
+
/** @internal - Bounds work by aborting the actual request signal at the deadline. */
|
|
22
|
+
export declare function withAbortTimeout<T>(operationFn: (signal: AbortSignal) => Promise<T>, ms: number, operation: string, parentSignal?: AbortSignal): Promise<T>;
|
|
23
|
+
/** @internal - Connects a transport with a deadline that aborts and cleans up the actual connection. */
|
|
24
|
+
export declare function connectTransportWithTimeout(client: Client, transport: Transport, ms: number, operation: string, parentSignal?: AbortSignal): Promise<void>;
|
|
25
|
+
/** @internal - Connects one client/transport pair and reports any failed cleanup. */
|
|
26
|
+
export declare function connectTransport(client: Client, transport: Transport, signal?: AbortSignal): Promise<void>;
|
|
21
27
|
/**
|
|
22
28
|
* Connect MCP SDK client to server with full readiness handling.
|
|
23
29
|
* @internal - Use registry.connect() instead
|
|
@@ -65,5 +71,7 @@ export declare function connectMcpClient(registryOrConfig: RegistryLike | Server
|
|
|
65
71
|
dcrAuthenticator?: Partial<DcrAuthenticatorOptions>;
|
|
66
72
|
logger?: Logger;
|
|
67
73
|
versionNegotiation?: VersionNegotiationOptions;
|
|
74
|
+
/** Cancels readiness, authentication, and transport connection work. */
|
|
75
|
+
signal?: AbortSignal;
|
|
68
76
|
}): Promise<Client>;
|
|
69
77
|
export {};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Helper to connect MCP SDK clients to servers with intelligent transport inference.
|
|
5
5
|
* Automatically detects transport type from URL protocol or type field.
|
|
6
6
|
*/
|
|
7
|
-
import type { VersionNegotiationOptions } from '@modelcontextprotocol/client';
|
|
7
|
+
import type { Transport, VersionNegotiationOptions } from '@modelcontextprotocol/client';
|
|
8
8
|
import { Client } from '@modelcontextprotocol/client';
|
|
9
9
|
import { type DcrAuthenticatorOptions } from '../dcr/index.js';
|
|
10
10
|
import type { ServerProcess } from '../spawn/spawn-server.js';
|
|
@@ -18,6 +18,12 @@ interface RegistryLike {
|
|
|
18
18
|
servers: Map<string, ServerProcess>;
|
|
19
19
|
}
|
|
20
20
|
import { type Logger } from '../utils/logger.js';
|
|
21
|
+
/** @internal - Bounds work by aborting the actual request signal at the deadline. */
|
|
22
|
+
export declare function withAbortTimeout<T>(operationFn: (signal: AbortSignal) => Promise<T>, ms: number, operation: string, parentSignal?: AbortSignal): Promise<T>;
|
|
23
|
+
/** @internal - Connects a transport with a deadline that aborts and cleans up the actual connection. */
|
|
24
|
+
export declare function connectTransportWithTimeout(client: Client, transport: Transport, ms: number, operation: string, parentSignal?: AbortSignal): Promise<void>;
|
|
25
|
+
/** @internal - Connects one client/transport pair and reports any failed cleanup. */
|
|
26
|
+
export declare function connectTransport(client: Client, transport: Transport, signal?: AbortSignal): Promise<void>;
|
|
21
27
|
/**
|
|
22
28
|
* Connect MCP SDK client to server with full readiness handling.
|
|
23
29
|
* @internal - Use registry.connect() instead
|
|
@@ -65,5 +71,7 @@ export declare function connectMcpClient(registryOrConfig: RegistryLike | Server
|
|
|
65
71
|
dcrAuthenticator?: Partial<DcrAuthenticatorOptions>;
|
|
66
72
|
logger?: Logger;
|
|
67
73
|
versionNegotiation?: VersionNegotiationOptions;
|
|
74
|
+
/** Cancels readiness, authentication, and transport connection work. */
|
|
75
|
+
signal?: AbortSignal;
|
|
68
76
|
}): Promise<Client>;
|
|
69
77
|
export {};
|
|
@@ -7,10 +7,24 @@
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", {
|
|
8
8
|
value: true
|
|
9
9
|
});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function _export(target, all) {
|
|
11
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
_export(exports, {
|
|
17
|
+
get connectMcpClient () {
|
|
13
18
|
return connectMcpClient;
|
|
19
|
+
},
|
|
20
|
+
get connectTransport () {
|
|
21
|
+
return connectTransport;
|
|
22
|
+
},
|
|
23
|
+
get connectTransportWithTimeout () {
|
|
24
|
+
return connectTransportWithTimeout;
|
|
25
|
+
},
|
|
26
|
+
get withAbortTimeout () {
|
|
27
|
+
return withAbortTimeout;
|
|
14
28
|
}
|
|
15
29
|
});
|
|
16
30
|
var _client = require("@modelcontextprotocol/client");
|
|
@@ -23,6 +37,14 @@ var _urlutilsts = require("../lib/url-utils.js");
|
|
|
23
37
|
var _loggerts = require("../utils/logger.js");
|
|
24
38
|
var _existingprocesstransportts = require("./existing-process-transport.js");
|
|
25
39
|
var _waitforhttpreadyts = require("./wait-for-http-ready.js");
|
|
40
|
+
function _array_like_to_array(arr, len) {
|
|
41
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
42
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
43
|
+
return arr2;
|
|
44
|
+
}
|
|
45
|
+
function _array_without_holes(arr) {
|
|
46
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
47
|
+
}
|
|
26
48
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
27
49
|
try {
|
|
28
50
|
var info = gen[key](arg);
|
|
@@ -71,6 +93,14 @@ function _interop_require_default(obj) {
|
|
|
71
93
|
default: obj
|
|
72
94
|
};
|
|
73
95
|
}
|
|
96
|
+
function _iterable_to_array(iter) {
|
|
97
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
|
|
98
|
+
return Array.from(iter);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function _non_iterable_spread() {
|
|
102
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
103
|
+
}
|
|
74
104
|
function _object_spread(target) {
|
|
75
105
|
for(var i = 1; i < arguments.length; i++){
|
|
76
106
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
@@ -86,6 +116,9 @@ function _object_spread(target) {
|
|
|
86
116
|
}
|
|
87
117
|
return target;
|
|
88
118
|
}
|
|
119
|
+
function _to_consumable_array(arr) {
|
|
120
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
121
|
+
}
|
|
89
122
|
function _ts_generator(thisArg, body) {
|
|
90
123
|
var f, y, t, _ = {
|
|
91
124
|
label: 0,
|
|
@@ -185,33 +218,232 @@ function _ts_generator(thisArg, body) {
|
|
|
185
218
|
};
|
|
186
219
|
}
|
|
187
220
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
221
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
222
|
+
if (!o) return;
|
|
223
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
224
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
225
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
226
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
227
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
228
|
+
}
|
|
229
|
+
var HTTP_CONNECTION_TIMEOUT_MS = 30000;
|
|
230
|
+
var CLIENT_CLEANUP_TIMEOUT_MS = 5000;
|
|
231
|
+
function withAbortTimeout(operationFn, ms, operation, parentSignal) {
|
|
232
|
+
return _async_to_generator(function() {
|
|
233
|
+
var controller, timeoutError, abortFromParent, timeoutId;
|
|
234
|
+
return _ts_generator(this, function(_state) {
|
|
235
|
+
switch(_state.label){
|
|
236
|
+
case 0:
|
|
237
|
+
controller = new AbortController();
|
|
238
|
+
timeoutError = new Error("Timeout after ".concat(ms, "ms: ").concat(operation));
|
|
239
|
+
abortFromParent = function abortFromParent() {
|
|
240
|
+
return controller.abort(_instanceof(parentSignal === null || parentSignal === void 0 ? void 0 : parentSignal.reason, Error) ? parentSignal.reason : new Error('Connection was cancelled'));
|
|
241
|
+
};
|
|
242
|
+
parentSignal === null || parentSignal === void 0 ? void 0 : parentSignal.addEventListener('abort', abortFromParent, {
|
|
243
|
+
once: true
|
|
244
|
+
});
|
|
245
|
+
if (parentSignal === null || parentSignal === void 0 ? void 0 : parentSignal.aborted) abortFromParent();
|
|
246
|
+
timeoutId = setTimeout(function() {
|
|
247
|
+
return controller.abort(timeoutError);
|
|
248
|
+
}, ms);
|
|
249
|
+
_state.label = 1;
|
|
250
|
+
case 1:
|
|
251
|
+
_state.trys.push([
|
|
252
|
+
1,
|
|
253
|
+
,
|
|
254
|
+
3,
|
|
255
|
+
4
|
|
256
|
+
]);
|
|
257
|
+
return [
|
|
258
|
+
4,
|
|
259
|
+
operationFn(controller.signal)
|
|
260
|
+
];
|
|
261
|
+
case 2:
|
|
262
|
+
// Preserve the operation's error unchanged: connection cleanup may have
|
|
263
|
+
// attached failures to the original cancellation or timeout.
|
|
264
|
+
return [
|
|
265
|
+
2,
|
|
266
|
+
_state.sent()
|
|
267
|
+
];
|
|
268
|
+
case 3:
|
|
269
|
+
clearTimeout(timeoutId);
|
|
270
|
+
parentSignal === null || parentSignal === void 0 ? void 0 : parentSignal.removeEventListener('abort', abortFromParent);
|
|
271
|
+
return [
|
|
272
|
+
7
|
|
273
|
+
];
|
|
274
|
+
case 4:
|
|
275
|
+
return [
|
|
276
|
+
2
|
|
277
|
+
];
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
})();
|
|
281
|
+
}
|
|
282
|
+
function connectTransportWithTimeout(client, transport, ms, operation, parentSignal) {
|
|
196
283
|
return _async_to_generator(function() {
|
|
197
|
-
var timeoutId;
|
|
198
284
|
return _ts_generator(this, function(_state) {
|
|
199
285
|
return [
|
|
200
286
|
2,
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}),
|
|
205
|
-
new Promise(function(_, reject) {
|
|
206
|
-
timeoutId = setTimeout(function() {
|
|
207
|
-
return reject(new Error("Timeout after ".concat(ms, "ms: ").concat(operation)));
|
|
208
|
-
}, ms);
|
|
209
|
-
})
|
|
210
|
-
])
|
|
287
|
+
withAbortTimeout(function(signal) {
|
|
288
|
+
return connectTransport(client, transport, signal);
|
|
289
|
+
}, ms, operation, parentSignal)
|
|
211
290
|
];
|
|
212
291
|
});
|
|
213
292
|
})();
|
|
214
293
|
}
|
|
294
|
+
function throwIfAborted(signal) {
|
|
295
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) throw _instanceof(signal.reason, Error) ? signal.reason : new Error('Connection was cancelled');
|
|
296
|
+
}
|
|
297
|
+
function closeClientWithinTimeout(client) {
|
|
298
|
+
return _async_to_generator(function() {
|
|
299
|
+
var timeoutId;
|
|
300
|
+
return _ts_generator(this, function(_state) {
|
|
301
|
+
switch(_state.label){
|
|
302
|
+
case 0:
|
|
303
|
+
_state.trys.push([
|
|
304
|
+
0,
|
|
305
|
+
,
|
|
306
|
+
2,
|
|
307
|
+
3
|
|
308
|
+
]);
|
|
309
|
+
return [
|
|
310
|
+
4,
|
|
311
|
+
Promise.race([
|
|
312
|
+
client.close(),
|
|
313
|
+
new Promise(function(_, reject) {
|
|
314
|
+
timeoutId = setTimeout(function() {
|
|
315
|
+
return reject(new Error("Client cleanup did not complete within ".concat(CLIENT_CLEANUP_TIMEOUT_MS, "ms")));
|
|
316
|
+
}, CLIENT_CLEANUP_TIMEOUT_MS);
|
|
317
|
+
})
|
|
318
|
+
])
|
|
319
|
+
];
|
|
320
|
+
case 1:
|
|
321
|
+
_state.sent();
|
|
322
|
+
return [
|
|
323
|
+
3,
|
|
324
|
+
3
|
|
325
|
+
];
|
|
326
|
+
case 2:
|
|
327
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
328
|
+
return [
|
|
329
|
+
7
|
|
330
|
+
];
|
|
331
|
+
case 3:
|
|
332
|
+
return [
|
|
333
|
+
2
|
|
334
|
+
];
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
})();
|
|
338
|
+
}
|
|
339
|
+
function rethrowAfterClientCleanup(error, clients, message) {
|
|
340
|
+
return _async_to_generator(function() {
|
|
341
|
+
var cleanup, cleanupErrors;
|
|
342
|
+
return _ts_generator(this, function(_state) {
|
|
343
|
+
switch(_state.label){
|
|
344
|
+
case 0:
|
|
345
|
+
return [
|
|
346
|
+
4,
|
|
347
|
+
Promise.allSettled(clients.map(function(client) {
|
|
348
|
+
return closeClientWithinTimeout(client);
|
|
349
|
+
}))
|
|
350
|
+
];
|
|
351
|
+
case 1:
|
|
352
|
+
cleanup = _state.sent();
|
|
353
|
+
cleanupErrors = cleanup.flatMap(function(result) {
|
|
354
|
+
return result.status === 'rejected' ? [
|
|
355
|
+
result.reason
|
|
356
|
+
] : [];
|
|
357
|
+
});
|
|
358
|
+
if (cleanupErrors.length > 0) throw new AggregateError([
|
|
359
|
+
error
|
|
360
|
+
].concat(_to_consumable_array(cleanupErrors)), message, {
|
|
361
|
+
cause: error
|
|
362
|
+
});
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
})();
|
|
367
|
+
}
|
|
368
|
+
function connectTransport(client, transport, signal) {
|
|
369
|
+
return _async_to_generator(function() {
|
|
370
|
+
var abortHandler, connecting, aborted, error;
|
|
371
|
+
return _ts_generator(this, function(_state) {
|
|
372
|
+
switch(_state.label){
|
|
373
|
+
case 0:
|
|
374
|
+
_state.trys.push([
|
|
375
|
+
0,
|
|
376
|
+
5,
|
|
377
|
+
7,
|
|
378
|
+
8
|
|
379
|
+
]);
|
|
380
|
+
throwIfAborted(signal);
|
|
381
|
+
connecting = client.connect(transport);
|
|
382
|
+
if (!signal) return [
|
|
383
|
+
3,
|
|
384
|
+
2
|
|
385
|
+
];
|
|
386
|
+
aborted = new Promise(function(_, reject) {
|
|
387
|
+
abortHandler = function abortHandler() {
|
|
388
|
+
return reject(_instanceof(signal.reason, Error) ? signal.reason : new Error('Connection was cancelled'));
|
|
389
|
+
};
|
|
390
|
+
signal.addEventListener('abort', abortHandler, {
|
|
391
|
+
once: true
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
return [
|
|
395
|
+
4,
|
|
396
|
+
Promise.race([
|
|
397
|
+
connecting,
|
|
398
|
+
aborted
|
|
399
|
+
])
|
|
400
|
+
];
|
|
401
|
+
case 1:
|
|
402
|
+
_state.sent();
|
|
403
|
+
return [
|
|
404
|
+
3,
|
|
405
|
+
4
|
|
406
|
+
];
|
|
407
|
+
case 2:
|
|
408
|
+
return [
|
|
409
|
+
4,
|
|
410
|
+
connecting
|
|
411
|
+
];
|
|
412
|
+
case 3:
|
|
413
|
+
_state.sent();
|
|
414
|
+
_state.label = 4;
|
|
415
|
+
case 4:
|
|
416
|
+
return [
|
|
417
|
+
3,
|
|
418
|
+
8
|
|
419
|
+
];
|
|
420
|
+
case 5:
|
|
421
|
+
error = _state.sent();
|
|
422
|
+
return [
|
|
423
|
+
4,
|
|
424
|
+
rethrowAfterClientCleanup(error, [
|
|
425
|
+
client
|
|
426
|
+
], 'MCP connection failed and client cleanup also failed')
|
|
427
|
+
];
|
|
428
|
+
case 6:
|
|
429
|
+
_state.sent();
|
|
430
|
+
return [
|
|
431
|
+
3,
|
|
432
|
+
8
|
|
433
|
+
];
|
|
434
|
+
case 7:
|
|
435
|
+
if (signal && abortHandler) signal.removeEventListener('abort', abortHandler);
|
|
436
|
+
return [
|
|
437
|
+
7
|
|
438
|
+
];
|
|
439
|
+
case 8:
|
|
440
|
+
return [
|
|
441
|
+
2
|
|
442
|
+
];
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
})();
|
|
446
|
+
}
|
|
215
447
|
/**
|
|
216
448
|
* Infer transport type from server configuration with validation.
|
|
217
449
|
*
|
|
@@ -253,7 +485,7 @@ function _ts_generator(thisArg, body) {
|
|
|
253
485
|
}
|
|
254
486
|
function connectMcpClient(registryOrConfig, serverName, options) {
|
|
255
487
|
return _async_to_generator(function() {
|
|
256
|
-
var _ref, isRegistry, serversConfig, registry, logger, serverConfig, available, transportType, clientOptions, client, serverHandle, transport, transport1, isSpawnedHttp, url, mcpServerUrl, capabilities, authToken, port, redirectUri, authenticator, tokens, staticHeaders, dcrHeaders, mergedHeaders, transportOptions, transport2, error, errorMessage, cause, isConnectionRefused, shouldFallback, sseClient, staticHeaders1, dcrHeaders1, mergedHeaders1, sseTransportOptions, sseTransport
|
|
488
|
+
var _ref, isRegistry, serversConfig, registry, logger, serverConfig, available, transportType, clientOptions, client, serverHandle, transport, transport1, isSpawnedHttp, url, mcpServerUrl, capabilities, authToken, port, redirectUri, authenticator, tokens, staticHeaders, dcrHeaders, mergedHeaders, transportOptions, transport2, error, _options_signal, errorMessage, cause, isConnectionRefused, unavailable, shouldFallback, sseClient, staticHeaders1, dcrHeaders1, mergedHeaders1, sseTransportOptions, sseTransport;
|
|
257
489
|
return _ts_generator(this, function(_state) {
|
|
258
490
|
switch(_state.label){
|
|
259
491
|
case 0:
|
|
@@ -262,6 +494,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
262
494
|
serversConfig = isRegistry ? registryOrConfig.config : registryOrConfig;
|
|
263
495
|
registry = isRegistry ? registryOrConfig : undefined;
|
|
264
496
|
logger = (_ref = options === null || options === void 0 ? void 0 : options.logger) !== null && _ref !== void 0 ? _ref : _loggerts.logger;
|
|
497
|
+
throwIfAborted(options === null || options === void 0 ? void 0 : options.signal);
|
|
265
498
|
serverConfig = serversConfig[serverName];
|
|
266
499
|
if (!serverConfig) {
|
|
267
500
|
available = Object.keys(serversConfig).join(', ');
|
|
@@ -297,7 +530,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
297
530
|
transport = new _existingprocesstransportts.ExistingProcessTransport(serverHandle.process);
|
|
298
531
|
return [
|
|
299
532
|
4,
|
|
300
|
-
client.
|
|
533
|
+
connectTransport(client, transport, options === null || options === void 0 ? void 0 : options.signal)
|
|
301
534
|
];
|
|
302
535
|
case 1:
|
|
303
536
|
_state.sent();
|
|
@@ -319,7 +552,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
319
552
|
// client.connect() performs initialize handshake - when it resolves, server is ready
|
|
320
553
|
return [
|
|
321
554
|
4,
|
|
322
|
-
client.
|
|
555
|
+
connectTransport(client, transport1, options === null || options === void 0 ? void 0 : options.signal)
|
|
323
556
|
];
|
|
324
557
|
case 3:
|
|
325
558
|
_state.sent();
|
|
@@ -327,12 +560,12 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
327
560
|
case 4:
|
|
328
561
|
return [
|
|
329
562
|
3,
|
|
330
|
-
|
|
563
|
+
16
|
|
331
564
|
];
|
|
332
565
|
case 5:
|
|
333
566
|
if (!(transportType === 'http')) return [
|
|
334
567
|
3,
|
|
335
|
-
|
|
568
|
+
16
|
|
336
569
|
];
|
|
337
570
|
if (!('url' in serverConfig) || !serverConfig.url) {
|
|
338
571
|
throw new Error("Server '".concat(serverName, "' has http transport but missing 'url' field"));
|
|
@@ -347,7 +580,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
347
580
|
logger.debug("[connectMcpClient] waiting for HTTP server '".concat(serverName, "' at ").concat(serverConfig.url));
|
|
348
581
|
return [
|
|
349
582
|
4,
|
|
350
|
-
(0, _waitforhttpreadyts.waitForHttpReady)(serverConfig.url)
|
|
583
|
+
(0, _waitforhttpreadyts.waitForHttpReady)(serverConfig.url, 30000, options === null || options === void 0 ? void 0 : options.signal)
|
|
351
584
|
];
|
|
352
585
|
case 6:
|
|
353
586
|
_state.sent();
|
|
@@ -365,7 +598,11 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
365
598
|
mcpServerUrl = (0, _urlutilsts.normalizeUrl)(serverConfig.url);
|
|
366
599
|
return [
|
|
367
600
|
4,
|
|
368
|
-
|
|
601
|
+
withAbortTimeout(function(signal) {
|
|
602
|
+
return (0, _indexts.probeAuthCapabilities)(mcpServerUrl, {
|
|
603
|
+
signal: signal
|
|
604
|
+
});
|
|
605
|
+
}, _constantsts.DCR_CAPABILTY_DISCOVERY_TIMEOUT, 'DCR capability discovery', options === null || options === void 0 ? void 0 : options.signal)
|
|
369
606
|
];
|
|
370
607
|
case 8:
|
|
371
608
|
capabilities = _state.sent();
|
|
@@ -389,7 +626,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
389
626
|
}, options === null || options === void 0 ? void 0 : options.dcrAuthenticator));
|
|
390
627
|
return [
|
|
391
628
|
4,
|
|
392
|
-
authenticator.ensureAuthenticated(mcpServerUrl, capabilities)
|
|
629
|
+
authenticator.ensureAuthenticated(mcpServerUrl, capabilities, options === null || options === void 0 ? void 0 : options.signal)
|
|
393
630
|
];
|
|
394
631
|
case 10:
|
|
395
632
|
tokens = _state.sent();
|
|
@@ -407,7 +644,7 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
407
644
|
12,
|
|
408
645
|
14,
|
|
409
646
|
,
|
|
410
|
-
|
|
647
|
+
16
|
|
411
648
|
]);
|
|
412
649
|
// Try modern Streamable HTTP first (protocol version 2025-03-26)
|
|
413
650
|
// Merge static headers from config with DCR auth headers (DCR Authorization takes precedence)
|
|
@@ -426,16 +663,19 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
426
663
|
// This is safe at runtime - the undefined is valid per MCP spec
|
|
427
664
|
return [
|
|
428
665
|
4,
|
|
429
|
-
|
|
666
|
+
connectTransportWithTimeout(client, transport2, HTTP_CONNECTION_TIMEOUT_MS, 'StreamableHTTP connection', options === null || options === void 0 ? void 0 : options.signal)
|
|
430
667
|
];
|
|
431
668
|
case 13:
|
|
432
669
|
_state.sent();
|
|
433
670
|
return [
|
|
434
671
|
3,
|
|
435
|
-
|
|
672
|
+
16
|
|
436
673
|
];
|
|
437
674
|
case 14:
|
|
438
675
|
error = _state.sent();
|
|
676
|
+
// Cancellation and cleanup failures must reach the caller; neither can
|
|
677
|
+
// safely be converted into an SSE fallback attempt.
|
|
678
|
+
if ((options === null || options === void 0 ? void 0 : (_options_signal = options.signal) === null || _options_signal === void 0 ? void 0 : _options_signal.aborted) || _instanceof(error, AggregateError)) throw error;
|
|
439
679
|
// Fall back to SSE transport (MCP protocol version 2024-11-05)
|
|
440
680
|
// SSE is a standard MCP transport used by many servers (e.g., FastMCP ecosystem)
|
|
441
681
|
errorMessage = _instanceof(error, Error) ? error.message : String(error);
|
|
@@ -443,19 +683,12 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
443
683
|
// Check error.cause.code for ECONNREFUSED (fetch errors wrap the actual error in cause)
|
|
444
684
|
cause = _instanceof(error, Error) ? error.cause : undefined;
|
|
445
685
|
isConnectionRefused = (cause === null || cause === void 0 ? void 0 : cause.code) === 'ECONNREFUSED' || errorMessage.includes('Connection refused');
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
4,
|
|
453
|
-
client.close().catch(function() {})
|
|
454
|
-
];
|
|
455
|
-
case 15:
|
|
456
|
-
_state.sent();
|
|
457
|
-
throw new Error("Server not running at ".concat(url));
|
|
458
|
-
case 16:
|
|
686
|
+
if (isConnectionRefused) {
|
|
687
|
+
unavailable = new Error("Server not running at ".concat(url), {
|
|
688
|
+
cause: error
|
|
689
|
+
});
|
|
690
|
+
throw unavailable;
|
|
691
|
+
}
|
|
459
692
|
// Check for known errors that indicate SSE fallback is needed
|
|
460
693
|
shouldFallback = errorMessage.includes('Missing session ID') || // FastMCP specific
|
|
461
694
|
errorMessage.includes('404') || // Server doesn't have streamable HTTP endpoint
|
|
@@ -483,44 +716,18 @@ function connectMcpClient(registryOrConfig, serverName, options) {
|
|
|
483
716
|
}
|
|
484
717
|
} : undefined;
|
|
485
718
|
sseTransport = new _client.SSEClientTransport(url, sseTransportOptions);
|
|
486
|
-
_state.label = 17;
|
|
487
|
-
case 17:
|
|
488
|
-
_state.trys.push([
|
|
489
|
-
17,
|
|
490
|
-
19,
|
|
491
|
-
,
|
|
492
|
-
21
|
|
493
|
-
]);
|
|
494
719
|
return [
|
|
495
720
|
4,
|
|
496
|
-
|
|
721
|
+
connectTransportWithTimeout(sseClient, sseTransport, HTTP_CONNECTION_TIMEOUT_MS, 'SSE connection', options === null || options === void 0 ? void 0 : options.signal)
|
|
497
722
|
];
|
|
498
|
-
case
|
|
723
|
+
case 15:
|
|
499
724
|
_state.sent();
|
|
500
725
|
// Return SSE client instead of original
|
|
501
726
|
return [
|
|
502
727
|
2,
|
|
503
728
|
sseClient
|
|
504
729
|
];
|
|
505
|
-
case
|
|
506
|
-
sseError = _state.sent();
|
|
507
|
-
// SSE connection failed - clean up both clients before throwing
|
|
508
|
-
return [
|
|
509
|
-
4,
|
|
510
|
-
Promise.all([
|
|
511
|
-
client.close().catch(function() {}),
|
|
512
|
-
sseClient.close().catch(function() {})
|
|
513
|
-
])
|
|
514
|
-
];
|
|
515
|
-
case 20:
|
|
516
|
-
_state.sent();
|
|
517
|
-
throw sseError;
|
|
518
|
-
case 21:
|
|
519
|
-
return [
|
|
520
|
-
3,
|
|
521
|
-
22
|
|
522
|
-
];
|
|
523
|
-
case 22:
|
|
730
|
+
case 16:
|
|
524
731
|
return [
|
|
525
732
|
2,
|
|
526
733
|
client
|