/** * Minimal structural view of a fetch response. Both the platform `Response` * and the eventsource package's `FetchLikeResponse` (used for a caller-supplied * `eventSourceInit.fetch`) satisfy it. */ type ResponseLike = { readonly url: string; readonly body?: unknown; }; /** * Assert that the URL's host is in the allowlist. * * Matching is exact and case-insensitive against `URL.host` (hostname plus * port when the URL carries a non-default port — WHATWG URL elides default * ports, so `https://x.com:443` has host `x.com`). No wildcards. An empty * allowlist denies every host. The URL scheme is not checked. * * @returns the parsed URL, for callers that need it. * @throws {MastraError} `MCP_CLIENT_HOST_NOT_ALLOWED` when the host is not allowed. */ export declare function assertHostAllowed(url: string | URL, allowedHosts: readonly string[], detail?: string): URL; /** * Post-hoc validation for responses produced by a caller-supplied fetch. * * A custom fetch may auto-follow redirects, so the final URL can differ from * the (already validated) request URL. When `response.url` lands on a * disallowed host the response is discarded by throwing — the outbound hop * already happened, but the data never reaches the caller or the model. * * Limitation (fail-open by design): a hand-built or proxied `Response` with an * empty `response.url` skips this check, because custom fetch implementations * legitimately construct such responses. */ export declare function assertResponseHostAllowed(response: R, allowedHosts: readonly string[]): R; export declare function isUrlPolicyError(error: unknown): boolean; /** * Wrap a caller-supplied fetch with the allowedHosts policy: the request URL is * validated before the wrapped fetch runs, and the response is validated * post-hoc via {@link assertResponseHostAllowed}. * * Variadic over the trailing arguments deliberately: the same wrapper serves * the 3-arg `MastraFetchLike` (url, init, requestContext) and the 2-arg * eventsource stream fetch (url, init). */ export declare function wrapFetchWithHostPolicy(fetchImpl: (...args: Args) => Promise, allowedHosts: readonly string[]): (...args: Args) => Promise; /** * Fetch with manual redirect handling so every redirect hop is validated * against the allowlist BEFORE the hop request is sent. Platform fetch follows * redirects transparently, which would bypass a per-call host check. * * Semantics follow platform conventions: * - `Location` is resolved against the current hop's URL (relative Locations are legal). * - 303 switches the method to GET and drops the body; 301/302 on POST do the same. * - 307/308 preserve method and body; a non-replayable body (anything other * than a string) throws rather than silently re-sending an empty body. * - 301/302 on non-POST methods preserve the method and body, matching * platform behavior. * - The `Authorization` header is not carried across hops to a different * origin (scheme, host, or port change), matching the WHATWG Fetch * credential-stripping rule — same host over a downgraded scheme still * drops the header. * - A redirect status with no `Location` header throws. * - More than {@link MAX_REDIRECT_HOPS} hops throws. */ export declare function fetchFollowingAllowedRedirects(fetchImpl: (url: string | URL, init?: RequestInit) => Promise, url: string | URL, init: RequestInit | undefined, allowedHosts: readonly string[]): Promise; export {}; //# sourceMappingURL=url-policy.d.ts.map