/** * OAuth client provider for remote MCP servers. * * Implements the MCP SDK's `OAuthClientProvider` interface against Franklin's * own on-disk store at `~/.blockrun/mcp/oauth/.json`. Each file holds * the registered client information + the current token set (access + * refresh + expiry). The SDK handles discovery, registration, PKCE, the * exchange, and refresh; we only persist + supply the saved state. * * Authorization flow (interactive): * 1. SDK calls `redirectToAuthorization(url)` — we spin up a localhost * callback listener on the port encoded into `redirectUrl`, then * open the user's browser to the authorization URL. * 2. User authorizes in browser. The provider returns `?code=...&state=...` * to our callback. We resolve the code through a one-shot promise. * 3. SDK exchanges code → tokens, calls `saveTokens()` → we write to disk. * * Headless mode is not yet supported — if there is no TTY, the OAuth flow * raises a clear error directing the user to configure manually instead. */ import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js'; import type { McpServerConfig } from './client.js'; export interface FranklinOAuthProvider { provider: OAuthClientProvider; /** Cheap signal for `/mcp` to show "authorized" without re-validating tokens. */ isAuthorized(): boolean; /** Pending callback promise — populated when the SDK requests a redirect, * awaited to get the code back. The caller (connectRemoteWithOAuth in * client.ts) then calls `transport.finishAuth(code)` to complete the flow. */ pendingCallback?: Promise<{ code: string; state?: string; }>; } export declare function createOAuthProvider(serverName: string, serverUrl: URL, config: McpServerConfig): Promise; /** * Standalone helper to drive an OAuth login outside the transport's normal * flow — used by `franklin mcp login ` to refresh tokens before any * connect attempt. Not wired by default; provided for the command layer. */ export declare function loginToMcpServer(_serverName: string, _config: McpServerConfig): Promise;