import type { RequestContext } from '../../utils/internal/requestContext.js';
/** Eagerly creates the HTTP client duration histogram so the series exists from startup. */
export declare function initHttpClientMetrics(): void;
/**
 * Options for the `fetchWithTimeout` utility.
 *
 * Extends the standard `RequestInit` type, omitting `signal` (which is managed
 * internally via `AbortController`) and adding SSRF protection and caller-supplied
 * cancellation options.
 */
export interface FetchWithTimeoutOptions extends Omit<RequestInit, 'signal'> {
    /**
     * When `true`, rejects requests to private/reserved IP ranges and localhost.
     *
     * Use this when fetching user-controlled URLs to reduce the SSRF blast radius
     * against internal services (e.g., cloud metadata endpoints, internal APIs).
     * Covered ranges include RFC 1918, loopback (127.x, ::1), link-local (169.254.x),
     * CGNAT (100.64–127.x), and known internal hostnames (e.g., `metadata.google.internal`).
     *
     * DNS is resolved (via `node:dns/promises`) and all A/AAAA records are
     * validated against private ranges before the request is sent. Available in
     * Node, Bun, and Cloudflare Workers under `nodejs_compat`.
     *
     * When enabled, redirects are followed manually (up to {@link MAX_SSRF_REDIRECTS}
     * hops) with SSRF validation applied to each redirect target.
     *
     * **Best-effort, not a hard guarantee — DNS rebinding / TOCTOU still applies.**
     * The pre-validation lookup and the native `fetch` call's own DNS resolution
     * are independent. A malicious authoritative DNS server (or a low-TTL record
     * racing with cache eviction) can return a public IP at validation time and a
     * private IP at fetch time. This helper does not pin the validated address to
     * the connection.
     *
     * For strong SSRF isolation, layer this with network egress controls
     * (Cloudflare egress rules, k8s NetworkPolicy, host firewall), a fetch proxy
     * that performs DNS pinning, or an HTTP client that resolves once and connects
     * to the validated address.
     *
     * Default: `false` (no restriction).
     */
    rejectPrivateIPs?: boolean;
    /**
     * An optional external `AbortSignal` (e.g., `ctx.signal` from the request context)
     * to combine with the internal timeout signal. If this signal aborts before the
     * timeout fires, the fetch is cancelled immediately and a `McpError` with code
     * `InternalError` is thrown.
     */
    signal?: AbortSignal;
}
/**
 * Fetches a resource with a configurable timeout and optional SSRF protection.
 *
 * Internally manages an `AbortController` that fires after `timeoutMs`. An optional
 * external `signal` (e.g., `ctx.signal`) can be passed via `options` to support
 * early cancellation by the caller. The two signals are composed — whichever fires
 * first wins.
 *
 * When `options.rejectPrivateIPs` is `true`, the target URL is validated before the
 * request is sent, and all redirects are followed manually with per-hop SSRF checks
 * (up to 5 hops). This mode forces `redirect: 'manual'` on the underlying fetch.
 *
 * Non-2xx responses are treated as errors. The response body is read (truncated
 * to {@link ERROR_BODY_LIMIT} bytes to avoid context-window poisoning when an
 * upstream returns an HTML error page), logged, and wrapped in a `McpError`
 * whose code is mapped from the HTTP status via {@link httpStatusToErrorCode}
 * (e.g. 400 → `InvalidParams`, 403 → `Forbidden`, 404 → `NotFound`, 429 →
 * `RateLimited`, 5xx → `ServiceUnavailable`/`InternalError`/`Timeout`).
 *
 * @param url - The URL to fetch (string or `URL` instance).
 * @param timeoutMs - Maximum duration in milliseconds before the request is aborted.
 * @param context - Log bindings for correlated logging (`requestId`, `operation`, etc.).
 *   Passing the handler `Context` is safe — the logger strips non-serializable fields
 *   such as `signal`, `log`, `state`, and protocol method handles. Pass
 *   `options.signal = ctx.signal` explicitly to wire cancellation.
 * @param options - Optional fetch configuration extending `RequestInit`.
 *   - `rejectPrivateIPs`: Block requests to private/internal IP space (SSRF protection).
 *   - `signal`: External `AbortSignal` to cancel the request independently of the timeout.
 *   - All other standard `RequestInit` fields (method, headers, body, etc.) are forwarded.
 * @returns A promise resolving to the `Response` object on HTTP 2xx.
 * @throws {McpError} `ValidationError` if the URL targets a private/reserved address
 *   and `rejectPrivateIPs` is enabled.
 * @throws {McpError} `Timeout` if the request exceeds `timeoutMs`.
 * @throws {McpError} `InternalError` if the request is cancelled via the external signal.
 * @throws {McpError} A status-mapped code (`InvalidParams`/`Unauthorized`/`Forbidden`/
 *   `NotFound`/`RateLimited`/`ServiceUnavailable`/...) if the server returns a non-2xx
 *   status. `error.data` carries `{ statusCode, statusText, responseBody, retryAfter? }`.
 * @throws {McpError} `ServiceUnavailable` if a network-level error occurs.
 * @example
 * ```ts
 * // Basic GET with a 5-second timeout
 * const response = await fetchWithTimeout(
 *   'https://api.example.com/data',
 *   5000,
 *   ctx,
 * );
 * const data = await response.json();
 *
 * // POST with SSRF protection and caller-cancellable signal
 * const response = await fetchWithTimeout(
 *   userProvidedUrl,
 *   10_000,
 *   ctx,
 *   {
 *     method: 'POST',
 *     headers: { 'Content-Type': 'application/json' },
 *     body: JSON.stringify(payload),
 *     rejectPrivateIPs: true,
 *     signal: ctx.signal,
 *   },
 * );
 * ```
 */
export declare function fetchWithTimeout(url: string | URL, timeoutMs: number, context: RequestContext, options?: FetchWithTimeoutOptions): Promise<Response>;
//# sourceMappingURL=fetchWithTimeout.d.ts.map