import { type FrontMcpLogger, type FrontMcpServer, type HttpRouteConfig, type ServerRequest, type ServerRequestHandler } from '../common'; /** Shape of the `session:verify` flow output we care about here. */ export type VerifyResult = { kind: 'authorized'; authorization: unknown; } | { kind: 'unauthorized'; prmMetadataHeader: string; } | { kind: 'forbidden'; prmMetadataHeader: string; }; /** * Dispatch the MCP `session:verify` flow for a request. The scope passes a thin * closure over its generic `runFlow` so this helper stays decoupled from the * scope's flow-name typing. */ export type VerifySessionFn = (request: ServerRequest) => Promise; export interface RegisterCustomHttpRoutesArgs { /** Custom routes from `http.routes`. */ routes: HttpRouteConfig[] | undefined; /** Active host server to register routes on. */ server: FrontMcpServer; /** Runs `session:verify` for `auth: true` routes. */ verifySession: VerifySessionFn; /** Resolved gateway entry path (e.g. `''` or `'/mcp'`). */ entryPath: string; /** Per-app / per-scope route base (e.g. `''` or `'/billing'`). */ routeBase: string; logger: FrontMcpLogger; } /** * Error thrown when a custom `http.routes` path collides with a FrontMCP * reserved surface. Fail-fast at startup rather than silently shadowing (or * being shadowed by) the MCP endpoint / discovery / health surfaces. */ export declare class ReservedRouteCollisionError extends Error { readonly method: string; readonly path: string; readonly reserved: string; constructor(method: string, path: string, reserved: string); } /** * Build the exact-match + prefix reserved-path set for the resolved MCP base. * * - Exact matches: the MCP base itself, `/sse`, `/message`, * `/health`, `/metrics`. * - Prefix matches: `/oauth`, `/.well-known` (any sub-path is reserved). */ export declare function computeReservedPaths(entryPath: string, routeBase: string): { exact: Set; prefixes: string[]; }; /** * Throw {@link ReservedRouteCollisionError} when `path` collides with a * reserved FrontMCP surface. Express path params (`:id`) and wildcards in the * *custom* path are compared literally — only the static prefix matters for the * reserved-surface check, so a route like `/files/:id` never collides unless it * is literally under `/oauth`, `/.well-known`, etc. */ export declare function assertNotReserved(method: string, path: string, reserved: { exact: Set; prefixes: string[]; }): void; /** * Wrap a user route handler in the MCP `session:verify` auth flow. On * unauthorized/forbidden the request is short-circuited with a 401/403 carrying * the `WWW-Authenticate` header (mirroring `http.request.flow.ts`); on success * the verified authorization is attached to `req.authSession` (and the internal * auth token) before the user handler runs. */ export declare function wrapWithAuth(handler: ServerRequestHandler, verifySession: VerifySessionFn, logger: FrontMcpLogger): ServerRequestHandler; /** * Register all configured custom HTTP routes on the active server. * * No-op when `routes` is empty/undefined. Throws {@link ReservedRouteCollisionError} * (fail-fast) on the first path that collides with a reserved surface — so a * misconfiguration aborts boot instead of silently mis-mounting. */ export declare function registerCustomHttpRoutes(args: RegisterCustomHttpRoutesArgs): void; //# sourceMappingURL=custom-routes.helper.d.ts.map