@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
137 lines (136 loc) • 5.07 kB
TypeScript
/**
* MCP Client Factory
* Creates and manages MCP clients for external servers
* Supports stdio, SSE, WebSocket, and HTTP transports
* Enhanced with retry, rate limiting, and OAuth 2.1 support
*/
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
import type { ClientCapabilities } from "@modelcontextprotocol/sdk/types.js";
import type { ChildProcess } from "child_process";
import type { MCPTransportType, MCPServerInfo, MCPClientResult } from "../types/index.js";
/**
* MCPClientFactory
* Factory class for creating MCP clients with different transports
*/
export declare class MCPClientFactory {
private static readonly NEUROLINK_IMPLEMENTATION;
private static readonly DEFAULT_CAPABILITIES;
/**
* Create an MCP client for the given server configuration
* Enhanced with retry logic, rate limiting, and circuit breaker protection
*/
static createClient(config: MCPServerInfo, timeout?: number): Promise<MCPClientResult>;
/**
* Internal client creation logic
*/
private static createClientInternal;
/**
* The most recent stderr lines written by the stdio server behind
* `transport`. Empty for network transports and for servers that have
* written nothing. Lines are captured from before the process is even
* started, so an early boot failure is included.
*/
static getStderrTail(transport: Transport): string[];
/**
* Create transport based on configuration
*/
private static createTransport;
/**
* Create a stdio transport.
*
* The SDK's StdioClientTransport owns the server process: it spawns the
* child inside `client.connect()` and reports the child's death through
* `transport.onclose`, which the Client forwards as `client.onclose`. There
* is deliberately no `spawn()` here. An earlier "startup probe" launched
* the command a second time, and that duplicate — never spoken to, never
* closed — was the process every lifecycle hook ended up watching while
* the real server could die unnoticed. It also leaked as an orphan on
* every shutdown.
*
* stderr is piped rather than ignored so a crashing server's last lines
* survive to the disconnect log and the connect error. A pipe nobody reads
* would back-pressure the child once the buffer fills, so the tail
* listener is attached before `start()`; the SDK creates the stderr
* PassThrough in its constructor for exactly this reason.
*/
private static createStdioTransport;
/**
* Create SSE transport
*/
private static createSSETransport;
/**
* Create WebSocket transport
*/
private static createWebSocketTransport;
/**
* Create HTTP transport (Streamable HTTP)
* Enhanced with OAuth 2.1, rate limiting, and configurable timeouts
*/
private static createHTTPTransport;
/**
* Create a fetch wrapper with timeout support
*/
private static createFetchWithTimeout;
/**
* Create an enhanced fetch function with timeout and optional retry
*/
private static createEnhancedFetch;
/**
* Set up OAuth provider if configured
*/
private static setupAuthProvider;
/**
* Get authorization header based on auth configuration
*/
private static getAuthorizationHeader;
/**
* Perform MCP handshake and get server capabilities
*/
private static performHandshake;
/**
* Get server information
*/
private static getServerInfo;
/**
* Extract capabilities from server info
*/
private static extractCapabilities;
/**
* Race an operation against a timeout (with optional AbortController
* support), clearing the timer on every outcome. A bare
* `Promise.race([operation, timeoutPromise])` leaves the timeout's
* `setTimeout` handle ref'd and pending until it fires even after
* `operation` already won the race — on the (common) success path that
* stray timer holds the event loop open for the full timeout duration for
* no reason.
*/
private static raceWithTimeout;
/**
* Close an MCP client and clean up resources
*/
static closeClient(client: Client, transport: Transport, process?: ChildProcess): Promise<void>;
/**
* Test connection to an MCP server
*/
static testConnection(config: MCPServerInfo, timeout?: number): Promise<{
success: boolean;
error?: string;
capabilities?: ClientCapabilities;
}>;
/**
* Validate MCP server configuration for client creation
*/
static validateClientConfig(config: MCPServerInfo): {
isValid: boolean;
errors: string[];
};
/**
* Get supported transport types
*/
static getSupportedTransports(): MCPTransportType[];
/**
* Get default client capabilities
*/
static getDefaultCapabilities(): ClientCapabilities;
}