/** * Loopback OAuth Callback Server for MCP Client * * Provides a one-shot local HTTP server that captures the OAuth authorization * code delivered to a loopback redirect URL (RFC 8252). Hosts use it together * with MCPOAuthClientProvider to complete the authorization-code flow for * OAuth-protected MCP servers. * * @see https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization */ /** * Options for creating an OAuth callback server. */ export interface OAuthCallbackServerOptions { /** * The redirect URL the authorization server will send the browser back to. * Its port is the preferred port to bind; if that port is in use, the next * sequential ports are tried (see getCallbackUrlCandidates). The server * binds the URL's hostname โ€” prefer the literal `127.0.0.1` over * `localhost` (RFC 8252 ยง8.3) so the browser and server agree on the * address family. * * @example 'http://127.0.0.1:5533/oauth/callback' */ redirectUrl: string | URL; /** * The OAuth state parameter issued for this authorization request. * The state authenticates the redirect (CSRF protection per OAuth 2.1): * callback requests without a matching state receive an error response and * never settle the flow, so a stray local request cannot abort or spoof a * pending authorization. */ state: string; } /** * The authorization code captured from the OAuth callback. */ export interface OAuthCallbackResult { /** * The authorization code to exchange for tokens. */ code: string; /** * The state parameter echoed back by the authorization server. */ state: string; /** * RFC 9207 authorization-server issuer returned with the callback, when present. */ iss?: string; } /** * A running loopback OAuth callback server. */ export interface OAuthCallbackServer { /** * The callback URL that is actually bound (reflects any port fallback). * Use this โ€” not the preferred redirect URL โ€” as the redirect_uri for the * authorization request. */ url: URL; /** * The port the server is listening on. */ port: number; /** * Waits for the browser to deliver the authorization code. * * Resolves once with the code and state from the first state-matching * callback request. Rejects on timeout, on a state-matching OAuth error * response (`error` / `error_description` query params), or when the * server is closed before a code arrives. */ waitForCode(options?: { timeoutMs?: number; }): Promise; /** * Stops the server and releases the port. Rejects any pending waitForCode. * Idempotent: closing an already-closed server resolves immediately. */ close(): Promise; } /** * Returns the candidate callback URLs for a redirect URL: the URL itself on * its preferred port, followed by the sequential fallback-port variants that * createOAuthCallbackServer will try when the preferred port is in use. * * This is the single source of the candidate list: include all of these as * redirect_uris in the pre-registered client or the hosted Client ID Metadata * Document so a fallback-bound callback URL always matches a listed URI. */ export declare function getCallbackUrlCandidates(redirectUrl: string | URL): URL[]; /** * Starts a one-shot loopback HTTP server that captures the OAuth * authorization code. * * The server binds the redirect URL's hostname on its port, falling back to * the next sequential ports when it is in use (see getCallbackUrlCandidates). * The first state-matching request on the callback path settles the outcome; * subsequent requests receive 410 Gone. Requests whose state does not match * receive an error response without settling, so only the genuine redirect * can complete or abort the flow. The response pages never echo the * authorization code. * * @example * ```typescript * const callbackServer = await createOAuthCallbackServer({ * redirectUrl: 'http://127.0.0.1:5533/oauth/callback', * state: expectedState, * }); * try { * // Direct the user to the authorization URL, then: * const { code } = await callbackServer.waitForCode(); * await transport.finishAuth(code); * } finally { * await callbackServer.close(); * } * ``` */ export declare function createOAuthCallbackServer(options: OAuthCallbackServerOptions): Promise; //# sourceMappingURL=oauth-callback-server.d.ts.map