/** * Per-session registry of MCP servers. * * `acp/server.ts handleSessionNew/Load/Resume` receives an optional * `mcpServers: McpServer[]` from the ACP client. We spawn each one via * `McpClient`, list its tools, and surface them under a flat namespace so * the agent can call them like any built-in tool. * * Naming: tools are surfaced as `__` to avoid * collisions across servers and with built-in agent tools. Underscores are * legal in MCP tool names; `__` is rare enough in practice to serve as a * delimiter without escaping. */ import { SamplingCreateMessageParams, SamplingCreateMessageResult } from './mcpClient.js'; import type { McpServer } from '../acp/protocol.js'; /** * Virtual-tool suffixes for the resource/prompt wrappers we generate per * server. Keep these in lockstep with the dispatch switch in * toolExecution.ts — adding a new wrapper requires both ends. */ export declare const VIRTUAL_TOOL_SUFFIXES: { readonly resourceList: "resource_list"; readonly resourceRead: "resource_read"; readonly promptList: "prompt_list"; readonly promptGet: "prompt_get"; }; export interface RegisteredTool { /** Prefixed name as exposed to the agent (`server__tool`). */ agentName: string; /** Original tool name on the server. */ toolName: string; serverName: string; description?: string; inputSchema?: Record; } /** * Spawn the given servers and discover their tools. Failures on individual * servers are reported in the result but don't abort the whole registration * (one broken server shouldn't kill the rest). * * Idempotent: calling twice for the same sessionId disposes the prior set * first. */ export declare function registerSessionServers(sessionId: string, servers: McpServer[], opts?: { workspaceRoot?: string; /** * Host LLM callback wired to the `sampling/createMessage` server request. * Receives the originating server name so the host can rate-limit / * budget-cap per server. */ onSamplingRequest?: (params: SamplingCreateMessageParams, serverName: string) => Promise; }): Promise<{ registered: RegisteredTool[]; errors: { server: string; error: string; }[]; }>; /** * Wait for any in-flight `registerSessionServers` for this session to * finish. No-op once registration has completed. Lets `callSessionTool` * be tolerant of the race between session/new returning and the user * sending their first prompt. */ export declare function awaitSessionReady(sessionId: string): Promise; /** Return spawn errors recorded for a session, for the /mcp inspector. */ export declare function getSessionRegistrationErrors(sessionId: string): { server: string; error: string; }[]; /** * Atomically read + clear the catalog-dirty flags for a session. * Called by the agent loop between iterations: if any flag is set, * the relevant cached lists (tools / resources / prompts) should be * re-fetched before the next dispatch. Returns the set of dirty kinds. */ export declare function consumeSessionCatalogChanges(sessionId: string): Set<'tools' | 'resources' | 'prompts'>; /** Return all tools registered for a session (built from cached server tool lists). */ export declare function getSessionTools(sessionId: string): Promise; /** * Build the set of virtual tools that wrap the resource/prompt primitives * for every server in the session. The agent calls these like normal * `__` entries; toolExecution.ts dispatches them through * `callSessionResourceTool` below. * * We only emit a wrapper when the server actually exposes resources or * prompts (probed via `listResources`/`listPrompts`) — no point teaching * the model about a `read_resource` tool that always returns "no such * resource". */ export declare function getSessionVirtualTools(sessionId: string): Promise; /** * Dispatch a virtual MCP tool (resource_list, resource_read, prompt_list, * prompt_get) and return a JSON-serialised string the agent can consume. * Throws if the tool name doesn't match a virtual wrapper. */ export declare function callSessionVirtualTool(sessionId: string, agentName: string, args: Record): Promise; /** Return true if a tool name matches one of the four virtual wrappers. */ export declare function isVirtualMcpToolName(name: string): boolean; /** Return resources advertised by all session servers, grouped by server. */ export declare function getSessionResources(sessionId: string): Promise<{ serverName: string; resources: import('./mcpClient.js').McpResource[]; }[]>; /** Read a resource URI from any session server that advertises it. */ export declare function readSessionResource(sessionId: string, uri: string): Promise; /** Return prompts advertised by all session servers, grouped by server. */ export declare function getSessionPrompts(sessionId: string): Promise<{ serverName: string; prompts: import('./mcpClient.js').McpPrompt[]; }[]>; /** Resolve a `__` prompt reference, returning the materialised messages. */ export declare function getSessionPrompt(sessionId: string, serverName: string, name: string, args?: Record): Promise<{ description?: string; messages: import('./mcpClient.js').McpPromptMessage[]; }>; /** Forward a tool call to the right MCP server. Returns the tool's text output. */ export declare function callSessionTool(sessionId: string, agentName: string, args: Record): Promise; /** True when an agent tool name looks like an MCP-prefixed tool. */ export declare function isMcpToolName(name: string): boolean; /** Stop all MCP clients for a session and drop the registry entry. */ export declare function disposeSession(sessionId: string): Promise; /** * Tear down every active MCP session. Wired up as a SIGINT/SIGTERM handler * in `acp/server.ts` so killing the CLI doesn't leave orphan child processes. */ export declare function disposeAllSessions(): Promise; /** For tests / debugging — how many sessions have active MCP clients. */ export declare function sessionCount(): number;