/** * @fileoverview Session-scoped BrAPI connection registry. Maps named aliases * to resolved connection state (base URL, auth header) within a tenant's * `ctx.state`. Multi-server workflows register distinct aliases; tools read * the alias from input (defaulting to `default`) and pull the base URL + * auth header for routing. Auth modes that require a token exchange * (`sgn`, `oauth2`) perform the exchange at registration time. * * @module services/server-registry/server-registry */ import type { Context } from '@cyanheads/mcp-ts-core'; import type { ServerConfig } from '../../config/server-config.js'; import type { AuthMode, ConnectAuth, RegisteredServer } from './types.js'; export declare const DEFAULT_ALIAS = "default"; export interface RegisterInput { alias?: string; auth?: ConnectAuth; baseUrl: string; } export declare class ServerRegistry { private readonly serverConfig; private readonly tokenFetcher; constructor(serverConfig: ServerConfig, tokenFetcher?: TokenFetcher); /** * Register a connection under an alias. Resolves the auth mode to a * ready-to-use header (performing token exchange for `sgn` / `oauth2`) and * persists the result in `ctx.state`. */ register(ctx: Context, input: RegisterInput): Promise; /** Fetch a registered connection or throw `NotFound`. */ get(ctx: Context, alias?: string): Promise; /** Non-throwing variant of `get`. */ getOptional(ctx: Context, alias?: string): Promise; list(ctx: Context): Promise; unregister(ctx: Context, alias?: string): Promise; /** * Resolve the state-key prefix for the current ctx. Under * `BRAPI_SESSION_ISOLATION=true` (default) and a present `ctx.sessionId` * (HTTP stateful/auto), folds the session ID in so concurrent sessions in * the same tenant don't share connection state. Falls back to the bare * tenant prefix for stdio, stateless HTTP without opt-in, or when * isolation is explicitly disabled. Used by both `connKey` (single-alias * keys) and `list` (prefix scans). */ private scopePrefix; private connKey; private resolveAuth; private exchangeSgnToken; private exchangeOAuth2Token; } /** * Swappable token-exchange fetcher. Production uses `fetchWithTimeout`; tests * inject a stub to avoid real network calls. */ export type TokenFetcher = (url: string, body: Record, ctx: Context, options: { timeoutMs: number; rejectPrivateIPs: boolean; }) => Promise; interface TokenResponse { access_token?: string; expires_in?: number; token_type?: string; [key: string]: unknown; } export declare function initServerRegistry(serverConfig: ServerConfig): void; export declare function getServerRegistry(): ServerRegistry; export declare function resetServerRegistry(): void; export type { AuthMode, ConnectAuth, RegisteredServer }; //# sourceMappingURL=server-registry.d.ts.map