UNPKG

@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
/** * 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; }