/**
 * Transparent stdio→HTTP MCP proxy (Increment 1 of the unified multi-peer
 * editing model — see ~/.claude/plans/indexed-stirring-turtle.md).
 *
 * `studiograph mcp` no longer writes entities directly. Instead it presents an
 * MCP server to Claude Desktop over stdio and forwards every `tools/list` and
 * `tools/call` to an upstream MCP `Client`:
 *
 *   - REMOTE: a `StreamableHTTPClientTransport` to the running local server's
 *     `/mcp` endpoint, so the write goes through BodyWriteCoordinator and merges
 *     into any open live editor (this is the data-loss fix).
 *   - LOCAL: an in-process server (InMemoryTransport) built lazily on demand,
 *     used only when no live server is reachable — in which case there is no
 *     open editor to clobber, so a direct write is safe.
 *
 * The upstream is re-selected on EVERY forwarded request (`probeServer`), which
 * closes the "server started after Claude Desktop" window.
 *
 * FAIL-LOUD: if a request is routed to the remote and the transport throws, the
 * error is surfaced to Claude Desktop and the remote client is marked stale so
 * the next call re-probes. We NEVER silently retry the failed call against the
 * local in-process server — that silent fallback is exactly the data-loss path
 * this increment removes. A `probeServer` `fail` (the server rejected our token)
 * is likewise surfaced, never downgraded to a local write.
 *
 * NOTE: stdout is owned by the JSON-RPC protocol — never console.log here. Use
 * log.error (writes to stderr).
 */
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { type ProbeDeps, type ProbeResult } from './server-discovery.js';
export interface StdioProxyOptions {
    workspacePath: string;
    /** Per-user API token (or JWT) — sent only to a loopback server. */
    token: string;
    /** Builds + connects the in-process fallback client (lazy, cached). */
    buildLocalClient: () => Promise<Client>;
    /** Test seams. */
    probeFn?: (workspacePath: string, token: string, deps?: ProbeDeps) => Promise<ProbeResult>;
    buildRemoteClient?: (url: string, token: string) => Promise<Client>;
}
/** Connect an MCP Client to a running server's /mcp over Streamable HTTP. */
export declare function createRemoteClient(url: string, token: string): Promise<Client>;
export declare class StdioProxy {
    private readonly opts;
    private readonly probeFn;
    private readonly buildRemoteClient;
    private remote;
    private localClient;
    constructor(opts: StdioProxyOptions);
    /**
     * Probe + return the upstream client for this request. Throws an McpError on
     * a `fail` probe (token rejected by a live server) — never falls back local.
     */
    private selectUpstream;
    private markRemoteStale;
    /** Forward a tools/list to the selected upstream. */
    forwardListTools(params?: any): Promise<any>;
    /** Forward a tools/call to the selected upstream. */
    forwardCallTool(params: any): Promise<any>;
    /** On a transport error against the remote, drop the cached client. */
    private onUpstreamError;
    /** Wire the two forwarders onto a low-level MCP Server. */
    registerHandlers(server: Server): void;
    /** Build the stdio-facing Server and connect it to Claude Desktop. */
    start(): Promise<void>;
}
