/**
 * Shared HTTP security helpers used by both the REST adapter and the MCP
 * Streamable HTTP transport. Keeping them in one place avoids drift between
 * the two servers (e.g., one being upgraded with a new defense and the
 * other forgotten).
 */
import http from "http";
import type { Logger } from "../../logger.js";
import { parseJsonBody } from "../util.js";
export declare const DEFAULT_HOST = "127.0.0.1";
export declare function isLoopbackHost(host: string): boolean;
export declare function defaultAllowedHosts(host: string): string[] | undefined;
/**
 * Validate the Host header against an allowlist (DNS-rebinding defense).
 * Strips the port before comparison; matches case-insensitively. If
 * `allowed` is undefined, validation is skipped.
 */
export declare function isHostAllowed(hostHeader: string | undefined, allowed: string[] | undefined): boolean;
/**
 * Throws if no API key is configured but the bind host is non-loopback.
 * Call this before binding to surface the misconfiguration as early as
 * possible — startup time, not first request.
 */
export declare function enforceNoKeyOnNonLoopback(host: string, apiKey: string | undefined): void;
/**
 * Logs the standard "listening on …" message plus warnings about
 * non-loopback bind and missing API key.
 */
export declare function logServerStart(logger: Logger, serverLabel: string, host: string, port: number, apiKey: string | undefined): void;
export type GuardedRequestContext = {
    method: string;
    path: string;
    start: number;
    sendJson: (status: number, body: unknown) => void;
    /**
     * Send an empty-body response (e.g. 202, 204, 405). Use this instead of
     * `sendJson` when the HTTP status forbids a body or when extra headers
     * (such as `Allow:` on a 405) need to be set without a JSON envelope.
     */
    sendStatus: (status: number, headers?: Record<string, string>) => void;
};
/**
 * Wraps an http.Server request handler with the standard pipeline:
 * 1. Host header validation (403 on mismatch)
 * 2. Authentication (401 on mismatch)
 * 3. Standard error envelope for body-parse errors / 500s
 *
 * The inner handler is only invoked once host + auth have passed.
 */
export declare function makeGuardedRequestListener(opts: {
    logger: Logger;
    apiKey: string | undefined;
    allowedHosts: string[] | undefined;
    /** Inner handler invoked after host + auth have passed. */
    inner: (req: http.IncomingMessage, res: http.ServerResponse, ctx: GuardedRequestContext) => Promise<void>;
}): http.RequestListener;
export { parseJsonBody };
