import { type ActionAuthorize, type ActionRunContext } from "../action.js"; import type { McpConfig, McpServerConfig } from "./config.js"; export declare const MCP_TOOL_PREFIX = "mcp__"; export interface McpTool { source: string; name: string; originalName: string; description: string; inputSchema: Record; title?: string; outputSchema?: Record; annotations?: Record; _meta?: Record; raw: Record; } export declare function buildMcpToolName(serverId: string, toolName: string): string; export declare function parseMcpToolName(prefixedName: string): { serverId: string; toolName: string; } | null; export interface McpClientManagerOptions { debug?: boolean; connectTimeoutMs?: number; } export interface McpToolCallOptions { /** Identity and invocation source forwarded to the authorization callback. */ context?: ActionRunContext; /** Fallback used by standalone action wrappers without a manager resolver. */ authorize?: ActionAuthorize>; } export type McpToolAuthorizationResolver = (tool: McpTool) => ActionAuthorize> | undefined; export declare class McpClientManager { private readonly servers; private readonly debug; private readonly connectTimeoutMs; private started; private config; private sdk; private readonly listeners; private resolveToolAuthorization?; private reconfigureQueue; private readonly toolRefreshes; constructor(config: McpConfig | null, options?: McpClientManagerOptions); /** * Install the app-owned authorization resolver used by every MCP tool-call * surface. Passing `undefined` restores the backwards-compatible no-policy * behavior. */ setToolAuthorizationResolver(resolver?: McpToolAuthorizationResolver): void; get enabled(): boolean; getConfig(): McpConfig | null; get configuredServers(): string[]; get connectedServers(): string[]; private loadSdk; onChange(listener: () => void): () => void; private emitChange; /** * Connect to each configured MCP server (stdio or http) and enumerate tools. * Individual server failures are logged and skipped — the manager stays * usable with whichever servers did come up. * * Queued against `reconfigure()` so a `reconfigure` that lands before * `start()` finishes can't race on `this.started` / `this.servers`. */ start(): Promise; private startInternal; private addServer; private connectServer; private closeEntry; private beginRequest; private endRequest; private runRequest; private reconnectExpiredSession; private withExpiredSessionRetry; reconfigure(newConfig: McpConfig | null): Promise<{ added: string[]; removed: string[]; unchanged: string[]; reconnected: string[]; }>; private reconfigureInternal; /** * Lists a connected server's tools again over its current connection, so a * tool held back for its schema returns once the server fixes it. Unlike a * reconnect, this leaves the connection and the calls running on it alone. */ refreshTools(serverId: string): Promise; private listToolsAgain; getTools(): McpTool[]; getTool(prefixedName: string): McpTool | null; getToolsForServer(serverId: string): McpTool[]; /** The config the server's current tools were loaded from. */ getServerConfig(serverId: string): McpServerConfig | null; hasServer(serverId: string): boolean; callTool(prefixedName: string, args: unknown, options?: McpToolCallOptions): Promise; readResource(serverId: string, uri: string): Promise; readResourceForTool(prefixedName: string, uri: string): Promise; stop(): Promise; /** * `errors` holds a server's connection failure, or, for a server that is * still connected, why each of its tools left out of `tools` is unusable. */ getStatus(): { configuredServers: string[]; connectedServers: string[]; totalTools: number; tools: Array<{ source: string; name: string; description: string; }>; errors: Record; }; getConnectErrorStatus(serverId: string): number | undefined; private shouldInjectFirstPartyIdentity; private firstPartyTrust; }