/**
 * MCP Client Executor
 * Spawns and communicates with MCP servers
 */
import type { McpServerConfig, ToolDefinition } from '../types.js';
export declare class McpClient {
    private process;
    private requestId;
    private pendingRequests;
    private buffer;
    private initialized;
    private serverName;
    private config;
    /** Serialized config for stale-detection by the pool */
    readonly configHash: string;
    /** HTTP/SSE transport base URL (set when config.url is provided) */
    private httpBaseUrl;
    constructor(serverName: string, config: McpServerConfig);
    connect(): Promise<void>;
    private handleData;
    private sendRequest;
    /**
     * Send a JSON-RPC request over HTTP POST.
     * Used when the server is configured with a URL (HTTP/SSE transport).
     */
    private sendHttpRequest;
    /**
     * Initialize MCP connection over HTTP transport.
     */
    private initializeHttp;
    private initialize;
    listTools(): Promise<ToolDefinition[]>;
    /**
     * Call a tool on the connected MCP server.
     *
     * !! REGRESSION GUARD — DO NOT MODIFY THE RETURN VALUE !!
     *
     * This method MUST return the raw JSON-RPC result exactly as received from
     * the downstream MCP server. The result is typically an MCP content envelope:
     *   { content: [{ type: "text", text: "..." }] }
     *
     * DO NOT:
     *  - Unwrap, flatten, or extract text from content blocks
     *  - Substitute placeholder strings like "(no output)" for null/undefined
     *  - Wrap the result in a new object or add metadata
     *
     * WHY: v1.4.0 added content unwrapping here and it was reverted in v1.4.1
     * because it broke Qwen3.5 (and similar small MoE models). The unwrapping
     * caused double-processing — the router's server.ts already wraps results
     * in MCP content blocks for upstream clients. When callTool() also unwrapped,
     * the model received flattened text instead of structured tool results,
     * causing it to misinterpret outputs and trigger infinite retries.
     *
     * The same regression was nearly re-introduced via unwrapMcpContent() in
     * execute.ts during the v1.4.2 compliance work and had to be reverted again.
     *
     * If you need to transform the result, do it in execute.ts (application
     * layer), NOT here (transport layer) — and read the v1.4.1 commit message
     * (5941768f) before changing anything.
     *
     * @see commit 5941768f "fix: v1.4.1 - revert callTool content unwrapping"
     */
    callTool(toolName: string, args?: Record<string, unknown>): Promise<unknown>;
    private cleanup;
    disconnect(): void;
    get isConnected(): boolean;
}
export declare class McpClientPool {
    private clients;
    /** Per-server rate limiter to prevent overloading downstream MCP servers */
    private rateLimiter;
    constructor(options?: {
        maxRequestsPerWindow?: number;
        windowMs?: number;
    });
    getClient(serverName: string, config: McpServerConfig): McpClient;
    /**
     * Check if a request to a server is allowed by the rate limiter.
     * Returns true if allowed, false if rate-limited.
     */
    isRequestAllowed(serverName: string): boolean;
    /**
     * Get remaining requests for a server in the current window.
     */
    getRemainingRequests(serverName: string): number;
    disconnectAll(): Promise<void>;
    getConnectedServers(): string[];
}
//# sourceMappingURL=client.d.ts.map