import { AbstractAgent, BaseEvent, Middleware, RunAgentInput, Tool } from "@ag-ui/client"; import { Observable } from "rxjs"; //#region src/index.d.ts /** * MCP Client configuration for HTTP (streamable) transport. */ interface MCPClientConfigHTTP { type: "http"; url: string; headers?: Record; serverId?: string; } /** * MCP Client configuration for SSE transport. */ interface MCPClientConfigSSE { type: "sse"; url: string; headers?: Record; serverId?: string; } /** * MCP Client configuration — one of the supported transports. */ type MCPClientConfig = MCPClientConfigHTTP | MCPClientConfigSSE; /** * Maximum length of a tool name. Bounded by the strictest mainstream LLM * provider constraint (OpenAI function names: `^[a-zA-Z0-9_-]{1,64}$`), * which is also why `__` — not `:` or `/` — is used as the delimiter. */ declare const MAX_TOOL_NAME_LENGTH = 64; /** * The namespace prefix applied to every MCP-sourced tool. Mirrors the * Claude Agent SDK convention: `mcp__{server}__{tool}`. */ declare const MCP_TOOL_NAME_PREFIX = "mcp"; /** * Default cap on the number of MCP tool-execution rounds in a single * `run()`. Prevents a runaway loop (and unbounded cost) if the model keeps * calling MCP tools forever. */ declare const DEFAULT_MAX_ITERATIONS = 32; /** * Options for {@link MCPMiddleware}. */ interface MCPMiddlewareOptions { /** * Maximum number of MCP tool-execution rounds before the middleware stops * looping and lets the run finish. Defaults to {@link DEFAULT_MAX_ITERATIONS}. */ maxIterations?: number; } /** * A tool resolved from an MCP server, carrying the metadata needed to map * the exposed (prefixed) name back to its origin. The mapping is kept as a * descriptor — never reconstructed by string-splitting the exposed name — * so server ids or tool names containing `__` can't corrupt the round-trip. */ interface ResolvedMCPTool { /** The (prefixed, possibly truncated/deduped) tool exposed to the agent. */ tool: Tool; /** The original tool name as reported by the MCP server. */ originalName: string; /** The server this tool came from. */ serverConfig: MCPClientConfig; } /** * AG-UI middleware that lists tools from one or more MCP servers, injects * them into the agent run (namespaced as `mcp__{server}__{tool}`), and * executes the resulting MCP tool calls server-side. * * Loop, on each agent `RUN_FINISHED`: * - Find open tool calls (assistant calls without a result message). * - Of those, execute the ones that target our injected MCP tools and emit * a `TOOL_CALL_RESULT` for each. * - If no open tool calls remain afterwards, start another run with the new * result messages appended (same threadId, fresh runId). * - If open tool calls still remain (e.g. frontend tools), stop and let the * frontend resolve them. * * If a run produces no open tool calls targeting our MCP tools, the * middleware does not interfere at all — every event is forwarded verbatim. */ declare class MCPMiddleware extends Middleware { private readonly mcpServers; private readonly maxIterations; /** * Lazily-populated cache of the full `listTools` result across every * configured server. Populated on the first `run()` and reused for the * lifetime of the instance — so listing happens exactly once per * middleware instance, no matter how many runs come through. */ private listingPromise; constructor(mcpServers?: MCPClientConfig[], options?: MCPMiddlewareOptions); run(input: RunAgentInput, next: AbstractAgent): Observable; /** * Resolve injectable tool descriptors for this run. Listing is cached * per-instance (see {@link listingPromise}); only the name resolution * (prefix / truncate / dedupe) is recomputed per run, since dedupe needs * the current `input.tools` as its seed. */ private resolveTools; /** * List tools from every configured server, exactly once per instance. A * server that fails to connect or list is logged and skipped — one bad * server never blocks the other servers' tools. The failure is part of * the cached result, so we don't keep retrying broken servers. */ private listAllTools; private doListAllTools; /** * Execute a single MCP tool call against its origin server and return the * result as text. Errors are caught and returned as the result content so * the agentic loop can react rather than crash. */ private executeToolCall; /** * Open a connected MCP client for a server config. If `headers` is set on * the config, they're stamped on every outbound request via the * transport's `requestInit`. This is the seam the runtime uses to forward * per-request auth (e.g. `Authorization: Bearer …`, `X-Cpki-User-Id: …`): * the middleware is constructed per request, so static headers in the * config are effectively per-request. * * Caveat: for the SSE transport, `requestInit.headers` only applies to * the POST channel — the SSE event stream uses `eventSourceInit`. For * streamable HTTP (the typical case) it covers all traffic. * * The SSE transport is imported lazily so that `eventsource` — which it * pulls in transitively, and which only some consumers ever need — stays out * of the module graph unless an SSE server is actually configured. Under Bun * a static import of it breaks at load time: `eventsource`'s `bun` export * condition resolves to its ESM build, so the SDK's CJS `require` gets an * async module back and throws. */ private connect; } //#endregion export { DEFAULT_MAX_ITERATIONS, MAX_TOOL_NAME_LENGTH, MCPClientConfig, MCPClientConfigHTTP, MCPClientConfigSSE, MCPMiddleware, MCPMiddlewareOptions, MCP_TOOL_NAME_PREFIX, ResolvedMCPTool }; //# sourceMappingURL=index.d.mts.map