import { Server as HttpServer } from 'node:http'; import { type Capability, type CaptureHeaderDecl, type IndexedDbScopeDecl, type DomSelectorDecl, type GraphqlOpDeclaration, type StoragePointerDecl, type InnerFrame } from '@fetchproxy/protocol'; import type { Identity } from './identity.js'; import { type ExtensionTrustPort } from './extension-trust.js'; export interface HostOpts { httpServer: HttpServer; ownIdentity: Identity; ownMcpId: string; ownServerName: string; ownVersion: string; ownDomains: string[]; /** * Inner-verb capabilities to declare on the server hello. Defaults * to `['fetch']` when omitted — keeps existing tests + callers that * pre-date the capability field compiling and behaving identically. */ ownCapabilities?: Capability[]; ownCookieKeys?: string[]; ownLocalStorageKeys?: string[]; ownSessionStorageKeys?: string[]; ownCaptureHeaders?: CaptureHeaderDecl[]; ownIndexedDbScopes?: IndexedDbScopeDecl[]; ownLocalStoragePointers?: StoragePointerDecl[]; ownSessionStoragePointers?: StoragePointerDecl[]; ownDomSelectors?: DomSelectorDecl[]; ownGraphqlOps?: GraphqlOpDeclaration[]; /** * 0.4.0+: invoked once on receipt of the extension hello with the * joint pair code `SHA256(mcpPub || extPub)`. The MCP can print this * for the user to verify against the popup. Optional — when the * host doesn't need to surface the code, omit it. */ onPairCode?: (code: string) => void; /** * 1.12.0+ (#208): where this MCP's pin on the extension's identity lives. * * REQUIRED, and deliberately not defaulted. A default would have to be the * file store under `$HOME`, which means every caller that forgot to think * about it — including a unit test — would either write into the user's real * identity directory or, worse, be handed a store that answers "no pin" and * so trusts anybody. Making it an argument means each caller states what its * trust store is. */ extensionTrust: ExtensionTrustPort; } export interface HostHandle { close: () => Promise; sendOwnInner: (inner: InnerFrame) => Promise; onOwnInner: (cb: (inner: InnerFrame) => void) => void; onExtensionDisconnect: (cb: () => void) => void; /** * 0.5.2+: fires when the extension reports a pair-pending state for * the host's own mcpId (user must approve in popup before tools work). * Multiple subscribers supported; called once per pair-pending frame. */ onPendingPair: (cb: (pairCode: string) => void) => void; /** The most recent pair code received via pair-pending, or null if none. */ pendingPairCode: () => string | null; } export declare function startHost(opts: HostOpts): Promise;