/**
 * External MCP Server Manager
 * Handles lifecycle management of external MCP servers including:
 * - Process spawning and management
 * - Health monitoring and automatic restart
 * - Connection management and cleanup
 * - Tool discovery and registration
 */
import { EventEmitter } from "events";
import { ToolDiscoveryService } from "./toolDiscoveryService.js";
import type { HITLManager, JsonObject, ServerLoadResult, ExternalMCPServerInstance, ExternalMCPServerHealth, ExternalMCPConfigValidation, ExternalMCPOperationResult, ExternalMCPManagerConfig, ExternalMCPToolInfo, MCPServerInfo } from "../types/index.js";
export declare class ExternalServerManager extends EventEmitter {
    private servers;
    private config;
    private isShuttingDown;
    /** Servers whose previous ping has not returned; the interval must not stack. */
    private healthChecksInFlight;
    /** Tool calls currently executing per server; a busy server is not a hung one. */
    private inFlightToolCalls;
    /** Consecutive pings missed while idle, per server. */
    private unresponsiveChecks;
    private toolDiscovery;
    private enableMainRegistryIntegration;
    private hitlManager?;
    constructor(config?: ExternalMCPManagerConfig, options?: {
        enableMainRegistryIntegration?: boolean;
    });
    /**
     * Attach a McpOutputNormalizer to the underlying ToolDiscoveryService.
     * All tool outputs will be measured and (if oversized) replaced with compact
     * surrogates before being returned to callers.
     */
    setOutputNormalizer(normalizer: import("./mcpOutputNormalizer.js").McpOutputNormalizer): void;
    /**
     * Set HITL manager for human-in-the-loop safety mechanisms
     * @param hitlManager - HITL manager instance (optional, can be undefined to disable)
     */
    setHITLManager(hitlManager?: HITLManager): void;
    /**
     * Get current HITL manager
     */
    getHITLManager(): HITLManager | undefined;
    /**
     * Resolve the human-readable server name for an event payload.
     * Falls back to serverId if the instance or config.name isn't available.
     */
    getServerName(serverId: string): string;
    /**
     * Load MCP server configurations from .mcp-config.json file with parallel loading support
     * Automatically registers servers found in the configuration
     * @param configPath Optional path to config file (defaults to .mcp-config.json in cwd)
     * @param options Loading options including parallel support
     * @returns Promise resolving to { serversLoaded, errors }
     */
    loadMCPConfiguration(configPath?: string, options?: {
        parallel?: boolean;
    }): Promise<ServerLoadResult>;
    /**
     * Load MCP servers in parallel for improved performance
     * @param configPath Optional path to config file (defaults to .mcp-config.json in cwd)
     * @returns Promise resolving to batch operation result
     */
    loadMCPConfigurationParallel(configPath?: string | null): Promise<ServerLoadResult>;
    /**
     * Load MCP servers sequentially (original implementation for backward compatibility)
     * @param configPath Optional path to config file (defaults to .mcp-config.json in cwd)
     * @returns Promise resolving to batch operation result
     */
    loadMCPConfigurationSequential(configPath?: string): Promise<ServerLoadResult>;
    /**
     * Validate external MCP server configuration
     */
    validateConfig(config: MCPServerInfo): ExternalMCPConfigValidation;
    /**
     * Convert MCPServerInfo format (keeping for backward compatibility)
     * Helper function for transitioning to zero-conversion architecture
     */
    private convertConfigToMCPServerInfo;
    /**
     * Add a new external MCP server - Backward compatibility overload
     */
    addServer(serverId: string, config: MCPServerInfo): Promise<ExternalMCPOperationResult<ExternalMCPServerInstance>>;
    /**
     * Add a new external MCP server - Updated to accept MCPServerInfo
     */
    addServer(serverId: string, serverInfo: MCPServerInfo): Promise<ExternalMCPOperationResult<ExternalMCPServerInstance>>;
    /**
     * Remove an external MCP server
     */
    removeServer(serverId: string): Promise<ExternalMCPOperationResult<void>>;
    /**
     * Start an external MCP server
     */
    private startServer;
    /**
     * Close a live client/transport pair, clearing the lifecycle hooks first
     * so the `onclose` they would otherwise trigger cannot schedule a restart
     * of a connection being torn down deliberately. Shared by `stopServer` and
     * the minTools readiness gate in `startServer`, which rejects a server
     * before it is ever registered as connected. Leaves status untouched —
     * callers set whatever status fits their case.
     */
    private closeInstanceConnection;
    /**
     * Stop an external MCP server
     */
    private stopServer;
    /**
     * Update server status and emit events
     */
    private updateServerStatus;
    /**
     * Hook the SDK client's lifecycle so the manager learns about the server
     * dying from the object that actually owns the process.
     *
     * `client.onclose` fires when the stdio child closes or a network
     * transport drops. It also fires during our own `stopServer()`, which is
     * why every path into `handleConnectionLost` checks that the client is
     * still the instance's current one and the status is still "connected":
     * a close that arrives while stopping or restarting is intentional.
     */
    private attachClientLifecycle;
    /**
     * Transition a server whose connection is gone, exactly once.
     *
     * Reached from three places that can all observe the same death — the
     * client's onclose, a failed health-check ping, and a tool call rejected
     * with the SDK's connection-closed error — so it is idempotent on the
     * (client, status) pair rather than trusting any one caller to be first.
     */
    private handleConnectionLost;
    private trackToolCall;
    /**
     * Handle server errors
     */
    private handleServerError;
    /**
     * Handle server disconnection
     */
    private handleServerDisconnection;
    /**
     * Schedule server restart with exponential backoff
     */
    private scheduleRestart;
    /**
     * Start health monitoring for a server
     */
    private startHealthMonitoring;
    /**
     * Perform a health check by pinging the server over its live transport.
     *
     * The previous check read `process.killed` — a flag Node sets only when we
     * call `kill()` ourselves, on a process handle that was not even the
     * server's — so it could never observe a server that died on its own.
     *
     * A ping that comes back with the SDK's connection-closed error is a
     * definitive death and is handled immediately. A ping that merely times
     * out is ambiguous: single-threaded servers (a Python MCP server running a
     * synchronous tool) cannot answer while a tool call is executing, and
     * restarting one mid-call would destroy the work in flight. So a timeout
     * counts toward a restart only while the server has no tool call in
     * flight, and only after UNRESPONSIVE_CHECKS_BEFORE_RESTART consecutive
     * misses.
     */
    private performHealthCheck;
    /**
     * Get server instance - converted to ExternalMCPServerInstance for compatibility
     */
    getServer(serverId: string): ExternalMCPServerInstance | undefined;
    /**
     * Get all servers - converted to ExternalMCPServerInstance for compatibility
     */
    getAllServers(): Map<string, ExternalMCPServerInstance>;
    /**
     * List servers as MCPServerInfo - ZERO conversion needed
     */
    listServers(): MCPServerInfo[];
    /**
     * Get server statuses
     */
    getServerStatuses(): ExternalMCPServerHealth[];
    /**
     * Shutdown all servers and clean up resources
     * This method should be called during application shutdown to prevent memory leaks
     */
    shutdown(): Promise<void>;
    /**
     * Destroy the manager and all associated resources
     * Alias for shutdown() to match the pattern used by other components
     */
    destroy(): Promise<void>;
    /**
     * Get manager statistics
     */
    getStatistics(): {
        totalServers: number;
        connectedServers: number;
        failedServers: number;
        totalTools: number;
        totalConnections: number;
        totalErrors: number;
    };
    /**
     * Discover tools from a server
     */
    private discoverServerTools;
    /**
     * Register server tools with main tool registry for unified access
     * This enables external MCP tools to be accessed via the main toolRegistry.executeTool()
     */
    private registerServerToolsWithMainRegistry;
    /**
     * Unregister server tools from main tool registry
     */
    private unregisterServerToolsFromMainRegistry;
    /**
     * Execute a tool on a specific server
     */
    executeTool(serverId: string, toolName: string, parameters: JsonObject, options?: {
        timeout?: number;
    }): Promise<unknown>;
    /**
     * Get all tools from all servers
     */
    getAllTools(): ExternalMCPToolInfo[];
    /**
     * Get tools for a specific server
     */
    getServerTools(serverId: string): ExternalMCPToolInfo[];
    /**
     * Get tool discovery service
     */
    getToolDiscovery(): ToolDiscoveryService;
}
