/**
 * CLI-side OAuth client provider for MCP servers.
 *
 * Construction adapter for {@link BaseMCPOAuthProvider} (lives in
 * `vcp-common/mcp-oauth.ts`). The base provider drives the entire OAuth
 * state machine (discovery, DCR, refresh, PKCE, callback exchange); this
 * file wires it to file-backed persistence and a loopback redirect — the
 * native-app counterpart to the server's
 * `FirestoreOAuthProvider` + `ServerCallbackRedirect` pair.
 *
 * Construction is asynchronous because the loopback redirect needs to bind
 * a port and read it back BEFORE the SDK's `clientMetadata.redirect_uris`
 * is set (the auth server must see the live port at registration / discovery
 * time). Use {@link LocalOAuthProvider.create} rather than `new` directly.
 *
 * Wiring back from a successful browser callback into the base provider:
 *   ```ts
 *   const provider = await LocalOAuthProvider.create({ ... });
 *   // ... SDK runs auth flow, opens browser via redirect.onAuthorizationRequired ...
 *   const { code, state } = await provider.awaitCallback();
 *   const tokens = await provider.handleCallback(code, state);
 *   ```
 *
 * The "caller awaits, caller hands code back" pattern matches how the
 * Express callback route at `/mcp/oauth/callback` drives the server-side
 * flow — neither redirect strategy needs a back-reference to its provider.
 */
import type { OAuthClientInformation, OAuthClientMetadata } from "@modelcontextprotocol/sdk/shared/auth.js";
import { BaseMCPOAuthProvider } from "#vcp-common/mcp-oauth.js";
import { LoopbackRedirect, type LoopbackCallback, type LoopbackRedirectOptions } from "./mcp-oauth-redirect-loopback";
export interface LocalOAuthProviderOptions {
    /** OAuth-protected MCP server URL. Used as the canonical store key. */
    serverUrl: string;
    /** Display name (`mcp.json` key). Recorded on PKCE state rows. */
    serverName: string;
    /**
     * Pre-registered DCR client ID. Use for IdPs that don't expose
     * dynamic client registration — the CLI then skips DCR and uses these
     * pinned values directly. Sourced from `mcp.json`'s `oauth.clientId`.
     */
    pinnedClientId?: string;
    /**
     * Pre-registered DCR client secret. Optional even when `pinnedClientId`
     * is set — public clients with `token_endpoint_auth_method: "none"` have
     * no secret. Sourced from `mcp.json`'s `oauth.clientSecret`.
     */
    pinnedClientSecret?: string;
    /**
     * Fixed redirect port. Use for IdPs that require pre-registered redirect
     * URIs and won't accept the kernel-assigned ephemeral port. Sourced from
     * `mcp.json`'s `oauth.redirectPort`.
     */
    pinnedRedirectPort?: number;
    /**
     * If true, the loopback redirect prints the authorization URL to stderr
     * instead of opening a browser. Wired up to `--no-open` for SSH workflows
     * (Phase 3).
     */
    noOpen?: boolean;
    /**
     * Override the credentials directory. See
     * {@link FileMCPOAuthStoreOptions.baseDir}.
     */
    storeDir?: string;
    /**
     * Override the static client metadata. Default is
     * {@link defaultClientMetadata}; rare to need an override outside tests.
     */
    clientMetadata?: OAuthClientMetadata;
    /**
     * Override the loopback timeout / browser opener. Mostly for tests.
     */
    loopbackOptions?: Pick<LoopbackRedirectOptions, "timeoutMs" | "openImpl" | "stderrWrite">;
    /**
     * Optional warning sink. Production callers wire this to the CLI logger
     * + Sentry; tests pass a recording callback.
     */
    onWarning?: (message: string, error: unknown, context?: Record<string, unknown>) => void;
}
/**
 * File-backed + loopback OAuth provider for CLI-managed MCPs. Construction
 * adapter over {@link BaseMCPOAuthProvider}; the base class owns the OAuth
 * state machine, this class only owns construction wiring.
 *
 * Construction is asynchronous (port bind happens before super()). Use
 * {@link LocalOAuthProvider.create}; the constructor itself is private to
 * make this contract explicit.
 */
export declare class LocalOAuthProvider extends BaseMCPOAuthProvider {
    /** The loopback redirect — exposed for `awaitCallback()` and `close()`. */
    readonly loopback: LoopbackRedirect;
    private constructor();
    /**
     * Build a `LocalOAuthProvider`. Binds the loopback port before returning,
     * so the caller can immediately register `provider.redirectUrl` with the
     * IdP (DCR or pre-registration).
     *
     * If `pinnedClientId` is provided, this method also pre-seeds the
     * file-backed store with metadata stub so the base provider's
     * `clientInformation()` returns the pinned values without running DCR.
     * Discovery still runs to populate `authorization_endpoint` /
     * `token_endpoint` — which the static pin can't supply on its own.
     */
    static create(options: LocalOAuthProviderOptions): Promise<LocalOAuthProvider>;
    /**
     * Wait for the loopback redirect to receive a `GET /oauth/callback?...`
     * Resolves with the `(code, state)` tuple to feed into
     * {@link BaseMCPOAuthProvider.handleCallback}.
     *
     * Convenience pass-through; the redirect is also reachable as
     * `provider.loopback.awaitCallback()` if a caller wants finer-grained
     * lifecycle control.
     */
    awaitCallback(): Promise<LoopbackCallback>;
    /**
     * Tear down the loopback listener, releasing the bound port. Idempotent.
     * Call this if the auth flow is abandoned (user cancellation, timeout
     * external to the loopback's own timeout) before
     * {@link awaitCallback} resolves.
     */
    close(): Promise<void>;
    /**
     * Test helper / future inspection: returns the pinned-or-discovered
     * client_id without forcing the caller through `clientInformation()`'s
     * undefined-handling.
     */
    getClientInformation(): Promise<OAuthClientInformation | undefined>;
}
