import type { RegistryAgnosticEngine } from '../core/engine.ts'; import { WeftError } from '../core/weft-error.ts'; import type { Principal } from '../server/principal.ts'; import { type McpResponse } from './protocol.ts'; type NotificationTarget = (message: McpResponse | Record) => void; /** * MCP lifecycle phase tracked for one session. * * @example * ```ts * import { type McpSessionPhase } from '@lostgradient/weft/mcp'; * * const phase: McpSessionPhase = 'ready'; * void phase; * ``` */ export type McpSessionPhase = 'new' | 'initializing' | 'ready'; /** * Options for bounding remote MCP session lifetime and memory usage. * * @example * ```ts * import { createMcpSessionManager, type McpSessionManagerOptions } from '@lostgradient/weft/mcp'; * import { Engine, MemoryStorage } from '@lostgradient/weft'; * * await using storage = new MemoryStorage(); * await using engine = new Engine({ storage }); * * const options: McpSessionManagerOptions = { * maximumSessions: 256, * sessionIdleTimeoutMilliseconds: 15 * 60 * 1000, * }; * const manager = createMcpSessionManager(engine, options); * void manager; * ``` */ export type McpSessionManagerOptions = { readonly maximumSessions?: number; readonly sessionIdleTimeoutMilliseconds?: number; readonly currentTimeMilliseconds?: () => number; }; export declare class McpSessionLimitExceededError extends WeftError<'McpSessionLimitExceededError'> { constructor(); } /** * Mutable MCP session state. Remote HTTP sessions are created during * `initialize`; stdio creates one local session for the process lifetime. * * @example * ```ts * import { McpSessionManager, type McpSession } from '@lostgradient/weft/mcp'; * import { Engine, MemoryStorage } from '@lostgradient/weft'; * * await using storage = new MemoryStorage(); * await using engine = new Engine({ storage }); * await using manager = new McpSessionManager(engine); * * const session: McpSession = manager.create({ method: 'unauthenticated' }); * session.notify('notifications/initialized'); * ``` */ export declare class McpSession { #private; readonly id: string; readonly principal: Principal; /** * Per-session continuation secret minted at creation. The session {@link id} is * sent by the client on *every* continuation request (POST/GET/DELETE), so it is * routinely exposed to proxy and access logs and is not, by itself, a credential. * This token is the credential: it is disclosed to the creating client exactly * once — in the `initialize` response — and never echoed on a continuation * response. The HTTP transport requires it alongside the session id on every * continuation request for sessions whose principal carries no other * distinguishing secret (anonymous sessions under `authRequired: false`), so a * leaked session id alone cannot drive, read, or terminate another caller's * session. Authenticated sessions already re-present their credential per request * and do not gate on this token. */ readonly token: string; phase: McpSessionPhase; protocolVersion: string; readonly subscriptions: Set; readonly createdAtMilliseconds: number; lastActivityMilliseconds: number; constructor(id: string, principal: Principal, currentTimeMilliseconds?: number); /** Mark the session as active after a successful transport-level lookup. */ touch(currentTimeMilliseconds?: number): void; /** True when this session has exceeded its idle timeout. */ isIdleExpired(currentTimeMilliseconds: number, timeoutMilliseconds: number): boolean; /** Track an in-flight request that started a workflow and can be cancelled. */ trackRequest(requestId: unknown, workflowId: string): void; /** Record cancellation for a tracked in-flight request and return its workflow id. */ cancelRequest(requestId: unknown): string | undefined; /** True when an in-flight MCP request has received a cancellation notification. */ isRequestCancelled(requestId: unknown): boolean; /** Abort signal for an in-flight MCP request, if it can be cancelled. */ requestSignal(requestId: unknown): AbortSignal | undefined; /** Stop tracking an in-flight request after it completes. */ untrackRequest(requestId: unknown): void; /** Return the workflow associated with an in-flight MCP request. */ workflowForRequest(requestId: unknown): string | undefined; /** Attach a notification sink. Returns a cleanup function. */ addTarget(target: NotificationTarget): () => void; /** Broadcast a JSON-RPC notification to every live stream for this session. */ notify(method: string, params?: Record): void; close(): void; } /** * Owns MCP sessions for a running server and translates engine events into * resource update notifications. * * @example * ```ts * import { McpSessionManager } from '@lostgradient/weft/mcp'; * import { Engine, MemoryStorage } from '@lostgradient/weft'; * * await using storage = new MemoryStorage(); * await using engine = new Engine({ storage }); * await using manager = new McpSessionManager(engine); * * manager.closeAll(); * ``` */ export declare class McpSessionManager implements AsyncDisposable { #private; constructor(engine: RegistryAgnosticEngine, options?: McpSessionManagerOptions); /** Create and store a new session for a principal. */ create(principal: Principal): McpSession; /** Store an externally-created session. Used by stdio. */ add(session: McpSession): McpSession; get(sessionId: string): McpSession | undefined; /** Mark a stored session active using the manager's clock. */ touch(session: McpSession): void; delete(sessionId: string): void; closeAll(): void; [Symbol.asyncDispose](): Promise; } /** * Create an MCP session manager for an engine. * * @example * ```ts * import { createMcpSessionManager } from '@lostgradient/weft/mcp'; * import { Engine, MemoryStorage } from '@lostgradient/weft'; * * await using storage = new MemoryStorage(); * await using engine = new Engine({ storage }); * await using manager = createMcpSessionManager(engine); * * void manager; * ``` */ export declare function createMcpSessionManager(engine: RegistryAgnosticEngine, options?: McpSessionManagerOptions): McpSessionManager; export {};