import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
/**
 * Background heartbeat service that keeps a registered peer alive.
 *
 * When running, it periodically:
 * 1. Sends an MCP debug-level logging notification (keeps stdio pipe active)
 * 2. Calls backend.updateLastSeen() to refresh the peer's lastSeenAt timestamp
 *    - Local mode: writes to state file via peer-registry
 *    - Cloud mode: POST /api/sessions/:sessionId/heartbeat
 *
 * Uses a setTimeout chain (not a fixed-interval timer) so that failure delays can use
 * exponential backoff. Retryable errors (network, 503, 429) trigger backoff
 * and retry. Terminal errors (401, INVALID_INPUT) stop immediately.
 *
 * Auto-stops after MAX_FAILURES consecutive retryable errors (capped retry).
 */
export declare class HeartbeatService {
    private timer;
    private peerId;
    private mcpServer;
    private onPeerEvicted;
    private consecutiveFailures;
    private intervalMs;
    private backoff;
    private static readonly MAX_FAILURES;
    /**
     * Classify whether an error is terminal (should not retry) or retryable.
     *
     * Terminal errors:
     * - INVALID_INPUT: peer ID is wrong, retrying won't help
     * - Auth errors (401/Unauthorized): credentials invalid
     *
     * Note: PEER_NOT_FOUND is NOT classified here because it has its own
     * special handling path (onPeerEvicted callback) in tick().
     */
    private isTerminalError;
    /**
     * Schedule the next heartbeat tick after a delay.
     * Every timer is .unref()'d to prevent process hang on SIGTERM.
     */
    private scheduleNextTick;
    /**
     * Start the heartbeat for a registered peer.
     * Idempotent — stops any existing heartbeat before starting a new one.
     *
     * @param onPeerEvicted - Optional callback invoked when the server returns
     *   PEER_NOT_FOUND (404), indicating the peer was evicted by stale cleanup.
     *   The callback should trigger re-registration.
     */
    start(peerId: string, mcpServer: McpServer, onPeerEvicted?: () => void): void;
    /**
     * Stop the heartbeat timer. Safe to call multiple times.
     */
    stop(options?: {
        preservePeerInfo?: boolean;
    }): void;
    get isRunning(): boolean;
    /**
     * Restart the heartbeat using stored peerId, mcpServer, and onPeerEvicted.
     * Used after automatic re-registration to resume keepalive ticks.
     */
    restart(): void;
    /**
     * Single heartbeat tick.
     * On success: schedules next tick at normal interval and resets backoff.
     * On retryable error: schedules next tick at backoff delay.
     * On terminal error or MAX_FAILURES: stops heartbeat.
     */
    private tick;
}
export declare const heartbeat: HeartbeatService;
//# sourceMappingURL=heartbeat.d.ts.map