/** * The wrapper's local HTTP MCP server — real-tool bridging plus the actual enforcement of which * bridged tools are callable. Wrapper-only — never imported by `adapter.ts`. * * @remarks * Built on the LOW-LEVEL `Server` class from `@modelcontextprotocol/sdk/server`, never * `McpServer.registerTool()` (which requires Zod-shaped schemas — incompatible with ADK's * Joi-based tools, already rendered to plain JSON Schema by the adapter before this module ever * sees them). The low-level `Server` takes MCP *protocol* schemas (`ListToolsRequestSchema`/ * `CallToolRequestSchema`), not per-tool argument schemas, so no Zod object is authored anywhere * in this file — the only Zod footprint is the two pre-built protocol-schema tokens imported from * the SDK itself. * * `--allowedTools` is kept in the CLI invocation only as a defense-in-depth, human-readable * statement of intent (see `wrapper.ts`'s argv construction) — it CANNOT be the real enforcement * mechanism, because `--dangerously-skip-permissions` removes the permission engine that an * allow-RULE feeds. The real enforcement happens here, twice over: `bridgedTools` arrives from the * adapter already pre-filtered to exclude `disallowedTools`, so a disallowed name is never even * listed; and the `CallTool` handler independently re-checks the requested name against that same * already-filtered list before ever emitting a `tool_call_request` to the adapter. */ import type { WrapperBridgedTool } from "./wire"; /** The running bridge: its bound port, and hooks to route calls to/from the adapter side. */ export interface McpBridge { /** The ephemeral loopback port the bridge is listening on. */ port: number; /** * Replaces the bridge's advertised tool set. The bridge starts with an EMPTY set at boot (so it * can bind its port and let the wrapper emit `ready` before a `run` command — carrying the real * tool list — has arrived); `wrapper.ts` calls this once, when `run` arrives, before spawning * `claude`. */ setBridgedTools(tools: WrapperBridgedTool[]): void; /** * Called by `wrapper.ts` when a `tool_call_response` command arrives from the adapter, to * settle the matching pending `CallTool` request. */ resolveToolCall(requestId: string, result: { content: Array>; isError?: boolean; }): void; /** * Reject every still-pending `CallTool` request with an `isError: true` result explaining the * bridge is shutting down. Must run BEFORE `close()` — an in-flight request is itself an active * HTTP connection, so settling it first is what lets `close()` (and the underlying `http.Server` * close callback) unblock. */ rejectPending(reason: string): void; /** Closes the MCP transport — this is what actually tears down any open SSE stream via its own `cleanup()` calls. Must run AFTER `rejectPending()` and BEFORE the HTTP listener is closed. */ closeTransport(): Promise; /** Closes the HTTP listener. Callback-based under the hood — promisified here. Must run LAST. */ closeHttpServer(): Promise; } /** * Start the bridge: bind an ephemeral loopback HTTP listener, wire a `StreamableHTTPServerTransport` * (session-scoped to this one wrapper-lifetime connection — see the `sessionIdGenerator` remark * below) to a low-level `Server` constructed with the explicit `tools` capability (required — the * SDK throws for `tools/list`/`tools/call` otherwise), and register the two handlers that make the * current `bridgedTools` set reachable over MCP. * * @remarks * Starts with an EMPTY tool set — the bridge must bind its port and let the wrapper emit `ready` * BEFORE the adapter has sent a `run` command carrying the real tool list (the adapter waits for * `ready` before sending `run`, so starting the bridge only after `run` arrives would deadlock * both sides). Call {@link McpBridge.setBridgedTools} once `run` arrives, before spawning `claude`. * * @param onToolCallRequest - Called with `(requestId, toolName, args)` for every `CallTool` the * bridge accepts; the caller (`wrapper.ts`) forwards this as a `tool_call_request` `WrapperEvent` * to the adapter and eventually calls `resolveToolCall` with the adapter's answer. */ export declare const startMcpBridge: (onToolCallRequest: (requestId: string, toolName: string, args: unknown) => void) => Promise;