import type { MCPDiscoveredTool, MCPPromptDefinition } from '../../types/connector/index.js'; import type { ToolDefinition } from '../../types/tool/index.js'; import { type Logger } from '../../utils/logger.js'; import type { MCPClient } from './client.js'; import { type MCPToolDrift, type MCPToolPolicy } from './policy.js'; export interface MCPToolDiscoveryOptions { /** * What each server is allowed to contribute, keyed by server name. * `'*'` applies to every server not named explicitly. * * Absent ⇒ everything is admitted, which is the pre-existing behavior * and the reason this option exists. */ readonly policies?: Readonly>; /** * Called when a server's tool set differs from the previous discovery. * * Drift is reported rather than blocked because the right response is a * host decision: a dev server legitimately changes between turns, while * a production one changing mid-session is the "rug pull" — advertise * something benign at approval time, swap it afterwards. Only the host * knows which it is looking at. */ readonly onDrift?: (event: { serverName: string; clientId: string; drift: MCPToolDrift; }) => void; readonly logger?: Logger; } export declare class MCPToolDiscovery { private clients; private log; private options; /** * Last admitted tool set per SERVER, for drift detection. * * Keyed by server name rather than client id, and the difference is the * whole point. A client id is minted per connection, so on the path a * real MCP server actually takes — a plugin enabling, connecting, and * being disabled again — every discovery was the first one that id had * ever seen, and drift could not fire however many times the server * changed underneath. The threat is a server that advertises something * benign when a host approves it and something else afterwards, which is * a property of the SERVER across connections. */ private lastSeen; constructor(clients: MCPClient[], options?: MCPToolDiscoveryOptions); addClient(client: MCPClient): void; removeClient(clientId: string): void; discoverAll(): Promise; discoverFrom(client: MCPClient): Promise; /** * The prompts a server publishes, through the same admission gate its * tools go through. * * A server publishing a prompt is the same trust question as one * publishing a tool: the remote side must not decide what enters the * agent's registry. Policy is matched on the prompt's own name, as the * server reports it, before any namespacing. * * A server that does not implement prompts answers method-not-found; * that is an ordinary answer, not a failure, so it yields none rather * than taking discovery down. */ discoverPromptsFrom(client: MCPClient): Promise; toToolDefinitions(): Promise; private detectDrift; } //# sourceMappingURL=discovery.d.ts.map