@cyanmycelium/mcp-broker 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../provider/src/protocol/envelope.ts","../src/stdio.upstream.ts","../src/remote.transports.ts","../src/remote.upstream.ts","../src/broker/adapters/broker.adapter.info.ts","../src/broker/broker.grammars.ts","../src/broker/behaviors/broker.behavior.info.ts","../src/broker/adapters/broker.adapter.providers.ts","../src/broker/behaviors/broker.behavior.providers.ts","../src/broker/broker.guides.ts","../src/broker/adapters/broker.adapter.guide.ts","../src/broker/behaviors/broker.behavior.guide.ts","../src/broker/broker.slots.ts","../src/broker/broker.diagnostics.ts","../src/broker/adapters/broker.adapter.diagnose.ts","../src/broker/behaviors/broker.behavior.diagnose.ts","../src/broker/broker.server.ts","../src/authorization/resource.path.ts","../src/authorization/capability.classifier.ts","../src/authorization/policy.engine.ts","../src/authorization/subject.mapper.ts","../src/authorization/slot.resource.ts","../src/authorization/runtime.ts","../src/authorization/audit.ts","../src/broker/aggregate/aggregate.catalog.ts","../src/broker/aggregate/provider.client.session.ts","../src/broker/aggregate/aggregate.server.ts","../src/auth/auth.types.ts","../src/auth/jwt.validator.ts","../src/auth/resource.metadata.ts","../src/auth/http.auth.ts","../src/auth/auth.config.ts","../src/auth/provider.auth.ts","../src/version.ts","../src/ws/ws.tunnel.ts","../src/ws/ws.tunnel.builder.ts","../src/mcpb/mcpb.unzip.ts","../src/mcpb/mcpb.loader.ts","../src/config.ts"],"names":["sep","McpAdapterBase","McpToolResults","McpBehavior","tool","request","resolve","PROTOCOL_VERSION","mcpScopesOf","require","WebSocket","https2","http2","slot","state","relative","fs2","readFileSync","dirname","join","tag","existsSync"],"mappings":"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","file":"chunk-BZUZYXVA.js","sourcesContent":["/**\n * The CyanMycelium tunnel envelope protocol.\n *\n * A multiplexed tunnel socket carries traffic for several providers at once, so\n * every JSON-RPC message is wrapped with the name of the provider slot it\n * belongs to. Both ends of the tunnel encode and decode with the helpers here:\n * the client transports that publish a provider, and the broker that routes\n * between providers and MCP clients.\n *\n * This module is the single definition of that wire format. It is deliberately\n * dependency-free and isomorphic, so the browser side and the Node broker share\n * exactly one implementation rather than two that drift apart.\n *\n * Wire format:\n * ```json\n * { \"provider\": \"scene-1\", \"payload\": { \"jsonrpc\": \"2.0\", \"id\": 1, \"result\": {} } }\n * ```\n */\n\n/** One framed message on a multiplexed tunnel socket. */\nexport interface TunnelEnvelope {\n /** Name of the provider slot this message belongs to. */\n provider: string;\n\n /** The JSON-RPC message itself, already parsed. */\n payload: unknown;\n}\n\n/**\n * Notification a client sends to claim a provider slot as soon as the tunnel\n * opens, before any MCP client shows up.\n *\n * Without it the broker only discovers a provider name on its first real\n * message, so an MCP client connecting in between is told the provider is not\n * connected. It is a plain JSON-RPC notification, which any peer that does not\n * recognize it ignores.\n */\nexport const TUNNEL_REGISTER_METHOD = \"notifications/register\";\n\n/** Options carried by the registration notification, as its `params`. */\nexport interface ITunnelRegisterOptions {\n /**\n * Join the broker's `_all` aggregate slot in addition to the provider's own\n * slot, so a single MCP client sees every opted-in provider's tools and\n * prompts through one connection.\n *\n * Opt-in on purpose: `_all` is a confidentiality boundary, and a provider\n * that never asks for it stays reachable only on its own slot.\n */\n aggregate?: boolean;\n}\n\n/**\n * Builds the registration notification as a plain JSON-RPC frame, for the\n * slot-scoped path `/provider/<name>`, which carries no envelope.\n *\n * The slot name is not in the frame: on that path the broker takes it from the\n * URL at connect time, before any frame exists.\n *\n * @param options When `aggregate` is set, it is carried as `params.aggregate`.\n * Omitted entirely otherwise, which keeps the frame identical to\n * the parameterless form older brokers already accept.\n */\nexport function encodeRegisterFrame(options?: ITunnelRegisterOptions): string {\n return JSON.stringify(registerMessage(options));\n}\n\n/** The registration notification body, shared by both encoders. */\nfunction registerMessage(options?: ITunnelRegisterOptions): Record<string, unknown> {\n const message: Record<string, unknown> = { jsonrpc: \"2.0\", method: TUNNEL_REGISTER_METHOD };\n if (options?.aggregate !== undefined) {\n message.params = { aggregate: options.aggregate };\n }\n return message;\n}\n\n/** JSON-RPC error codes the broker returns on the tunnel itself. */\nexport const TunnelErrorCodes = {\n /** The slot is taken by another upstream, or the provider is not connected. */\n ProviderUnavailable: -32000,\n\n /** The provider's credentials do not allow publishing on this slot. */\n RegistrationForbidden: -32001,\n} as const;\n\nexport type TunnelErrorCode = (typeof TunnelErrorCodes)[keyof typeof TunnelErrorCodes];\n\n/** A JSON-RPC error as carried inside an envelope payload. */\nexport interface TunnelError {\n code: number;\n message: string;\n data?: unknown;\n}\n\n/**\n * Wraps an already-serialized JSON-RPC frame for `provider`.\n *\n * @throws SyntaxError when `frame` is not valid JSON. Callers hold a frame they\n * just serialized, so a failure here is a bug rather than bad input.\n */\nexport function encodeEnvelope(provider: string, frame: string): string {\n return encodeEnvelopeMessage(provider, JSON.parse(frame));\n}\n\n/** Wraps an already-parsed JSON-RPC message for `provider`. */\nexport function encodeEnvelopeMessage(provider: string, payload: unknown): string {\n const envelope: TunnelEnvelope = { provider, payload };\n return JSON.stringify(envelope);\n}\n\n/**\n * Parses a raw tunnel frame.\n *\n * Returns `undefined` for anything malformed rather than throwing: a tunnel\n * socket is a public surface, and a peer sending garbage must not take the\n * receiver down. Both ends drop such frames silently.\n */\nexport function decodeEnvelope(raw: string): TunnelEnvelope | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return undefined;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return undefined;\n\n const { provider, payload } = parsed as Partial<TunnelEnvelope>;\n if (typeof provider !== \"string\" || provider.length === 0 || payload === undefined) return undefined;\n\n return { provider, payload };\n}\n\n/** Serializes an envelope's payload back into a plain JSON-RPC frame. */\nexport function envelopeFrame(envelope: TunnelEnvelope): string {\n return JSON.stringify(envelope.payload);\n}\n\n/**\n * Builds the registration notification that claims `provider`, wrapped for the\n * multiplexed tunnel.\n *\n * @param options When `aggregate` is set, it is carried as `params.aggregate`.\n * Omitted entirely otherwise: the parameterless frame is the one\n * brokers have always received here, and it stays byte-identical.\n */\nexport function encodeRegisterEnvelope(provider: string, options?: ITunnelRegisterOptions): string {\n return encodeEnvelopeMessage(provider, registerMessage(options));\n}\n\n/**\n * Builds the error envelope the broker returns when it refuses a slot.\n *\n * The id is `null` because the refusal answers no particular request: it\n * reacts to the registration itself.\n */\nexport function encodeErrorEnvelope(provider: string, code: TunnelErrorCode | number, message: string): string {\n return encodeEnvelopeMessage(provider, { jsonrpc: \"2.0\", id: null, error: { code, message } });\n}\n\n/**\n * Reads the JSON-RPC error out of an envelope payload, when there is one.\n *\n * Lets the client side notice a refused registration instead of handing an\n * `id: null` error frame to an MCP server, which would classify it as an\n * unknown notification and drop it without a word.\n */\nexport function tunnelErrorOf(payload: unknown): TunnelError | undefined {\n if (typeof payload !== \"object\" || payload === null) return undefined;\n\n const { error } = payload as { error?: unknown };\n if (typeof error !== \"object\" || error === null) return undefined;\n\n const { code, message } = error as Partial<TunnelError>;\n if (typeof code !== \"number\" || typeof message !== \"string\") return undefined;\n\n return error as TunnelError;\n}\n","import { spawn, ChildProcess } from \"node:child_process\";\nimport type { IUpstream } from \"./upstream\";\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nexport interface IStdioUpstreamConfig {\n /** Logical name of this provider (matched against incoming WebSocket provider names). */\n name: string;\n /** Executable to spawn (e.g. `\"node\"`, `\"python\"`, an absolute path). */\n command: string;\n /** Arguments passed to the command. */\n args?: string[];\n /** Extra environment variables merged with `process.env`. */\n env?: NodeJS.ProcessEnv;\n /** When `true`, this upstream joins the `_all` aggregate slot once connected. */\n aggregate?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// StdioUpstream\n// ---------------------------------------------------------------------------\n\n/**\n * Manages a stdio-based MCP server process.\n * JSON-RPC messages are exchanged over the child process stdin/stdout using\n * newline-delimited framing (matching the MCP SDK stdio transport).\n *\n * One instance per configured provider. The broker uses this to bridge\n * WebSocket/SSE/HTTP clients to local MCP server processes.\n */\nexport class StdioUpstream implements IUpstream {\n readonly name: string;\n\n private readonly _config: IStdioUpstreamConfig;\n private _proc: ChildProcess | null = null;\n private _buffer = \"\";\n private _open = false;\n private _stopped = false;\n\n /** Called when a complete JSON-RPC line arrives from the process stdout. */\n onMessage: ((data: string) => void) | null = null;\n\n /** Called when the process has started and stdin is writable. */\n onOpen: (() => void) | null = null;\n\n /** Called when the process exits (cleanly or otherwise). */\n onClose: (() => void) | null = null;\n\n /** Called on spawn or runtime errors. */\n onError: ((error: Error) => void) | null = null;\n\n constructor(config: IStdioUpstreamConfig) {\n this.name = config.name;\n this._config = config;\n }\n\n get isOpen(): boolean {\n return this._open;\n }\n\n /** Spawns the child process and wires up stdio listeners. */\n connect(): void {\n this._stopped = false;\n const { command, args = [], env } = this._config;\n\n this._proc = spawn(command, args, {\n env: { ...process.env, ...env },\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n });\n\n this._proc.on(\"error\", (err: Error) => {\n this._open = false;\n this.onError?.(new Error(`StdioUpstream \"${this.name}\": process error, ${err.message}`));\n });\n\n this._proc.on(\"spawn\", () => {\n this._open = true;\n this.onOpen?.();\n });\n\n this._proc.stdout!.on(\"data\", (chunk: Buffer) => {\n this._buffer += chunk.toString(\"utf8\");\n let nl: number;\n while ((nl = this._buffer.indexOf(\"\\n\")) !== -1) {\n const line = this._buffer.slice(0, nl).trim();\n this._buffer = this._buffer.slice(nl + 1);\n if (line) this.onMessage?.(line);\n }\n });\n\n this._proc.on(\"close\", (code) => {\n this._open = false;\n this._proc = null;\n this.onClose?.();\n if (!this._stopped) {\n this.onError?.(new Error(`StdioUpstream \"${this.name}\": process exited with code ${code ?? \"null\"}`));\n }\n });\n }\n\n /** Sends a JSON-RPC message to the process stdin (appends newline). */\n send(data: string): void {\n if (!this._open || !this._proc?.stdin?.writable) return;\n this._proc.stdin.write(data + \"\\n\", \"utf8\");\n }\n\n /** Kills the child process and prevents further reconnection attempts. */\n close(): void {\n this._stopped = true;\n this._open = false;\n this._proc?.stdin?.end();\n this._proc?.kill();\n this._proc = null;\n }\n}\n\n/** @deprecated Use {@link IStdioUpstreamConfig}. */\nexport type StdioUpstreamConfig = IStdioUpstreamConfig;\n","/**\n * Hand-rolled client transports for reaching a remote MCP server by URL.\n *\n * No `@modelcontextprotocol/sdk` dependency: the broker stays SDK-free, the\n * official SDK is only used outside the broker (in the demo) to prove the\n * broker is implementation-agnostic. Each transport is a thin frame relay ,\n * it does not interpret MCP, it pipes JSON-RPC strings both ways.\n */\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport type { ClientRequest, IncomingMessage, RequestOptions } from \"node:http\";\nimport { WebSocket } from \"ws\";\n\n/** Lifecycle + callbacks shared by every remote client transport. */\nexport interface IRemoteTransport {\n onMessage: ((data: string) => void) | null;\n onOpen: (() => void) | null;\n onClose: (() => void) | null;\n onError: ((error: Error) => void) | null;\n connect(): void;\n send(data: string): void;\n close(): void;\n}\n\n/** The three supported remote transports. */\nexport type RemoteTransportKind = \"streamable-http\" | \"sse\" | \"websocket\";\n\n/** Issues an http/https request, picking the module from the URL scheme. */\nfunction makeRequest(url: URL, options: RequestOptions, onResponse: (res: IncomingMessage) => void): ClientRequest {\n return url.protocol === \"https:\" ? https.request(url, options, onResponse) : http.request(url, options, onResponse);\n}\n\n/** First delay before reopening a dropped standalone GET stream. */\nconst STREAM_REOPEN_BASE_MS = 500;\n\n/** Ceiling for the standalone GET stream reopen backoff. */\nconst STREAM_REOPEN_MAX_MS = 30_000;\n\n/** Number of doublings applied to {@link STREAM_REOPEN_BASE_MS} before the cap. */\nconst STREAM_REOPEN_MAX_DOUBLINGS = 6;\n\n/**\n * How long a standalone GET stream must stay up before its drop counts as a\n * one-off rather than a flap. Below this, the backoff keeps growing, so a server\n * that accepts the GET and closes it immediately is not polled twice a second\n * forever.\n */\nconst STREAM_HEALTHY_MS = 10_000;\n\n/** How much of an unparseable upstream body is echoed into the log. */\nconst BODY_EXCERPT_LIMIT = 300;\n\n/**\n * Collapses a response body to a single-line, length-capped excerpt. Logging the\n * body is the whole point of the diagnostic (an HTML error page is instantly\n * recognizable), but a full page in a log line is not.\n */\nfunction bodyExcerpt(body: string): string {\n const oneLine = body.replace(/\\s+/g, \" \").trim();\n return oneLine.length <= BODY_EXCERPT_LIMIT ? oneLine : `${oneLine.slice(0, BODY_EXCERPT_LIMIT)}... (${oneLine.length} chars total)`;\n}\n\n/**\n * Incremental Server-Sent-Events decoder. Normalizes line endings, buffers\n * across chunks, and emits one `(event, data)` pair per complete SSE block.\n */\nclass SseDecoder {\n private _buf = \"\";\n\n feed(chunk: string, emit: (event: string, data: string) => void): void {\n this._buf += chunk.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n let sep: number;\n while ((sep = this._buf.indexOf(\"\\n\\n\")) !== -1) {\n const block = this._buf.slice(0, sep);\n this._buf = this._buf.slice(sep + 2);\n let event = \"message\";\n const data: string[] = [];\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\":\")) continue; // comment\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) value = value.slice(1);\n if (field === \"event\") event = value;\n else if (field === \"data\") data.push(value);\n }\n if (data.length > 0) emit(event, data.join(\"\\n\"));\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket\n// ---------------------------------------------------------------------------\n\nclass WebSocketRemoteTransport implements IRemoteTransport {\n onMessage: ((data: string) => void) | null = null;\n onOpen: (() => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private _ws: WebSocket | null = null;\n\n constructor(\n private readonly _url: string,\n private readonly _headers: Record<string, string>\n ) {}\n\n connect(): void {\n const ws = new WebSocket(this._url, { headers: this._headers });\n this._ws = ws;\n ws.on(\"open\", () => this.onOpen?.());\n ws.on(\"message\", (data: Buffer) => this.onMessage?.(data.toString(\"utf8\")));\n ws.on(\"close\", () => this.onClose?.());\n ws.on(\"error\", (err: Error) => this.onError?.(err));\n }\n\n send(data: string): void {\n if (this._ws && this._ws.readyState === WebSocket.OPEN) this._ws.send(data);\n }\n\n close(): void {\n this._ws?.close();\n this._ws = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Legacy MCP SSE (GET event stream + POST message endpoint)\n// ---------------------------------------------------------------------------\n\nclass SseRemoteTransport implements IRemoteTransport {\n onMessage: ((data: string) => void) | null = null;\n onOpen: (() => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private readonly _decoder = new SseDecoder();\n private _streamReq: ClientRequest | null = null;\n private _postUrl: string | null = null;\n private _closed = false;\n\n constructor(\n private readonly _url: string,\n private readonly _headers: Record<string, string>\n ) {}\n\n connect(): void {\n const req = makeRequest(new URL(this._url), { method: \"GET\", headers: { ...this._headers, Accept: \"text/event-stream\" } }, (res) => {\n const status = res.statusCode ?? 0;\n if (status >= 400) {\n this.onError?.(new Error(`SSE GET responded ${status}`));\n res.resume();\n return;\n }\n res.setEncoding(\"utf8\");\n res.on(\"data\", (chunk: string) => this._decoder.feed(chunk, (ev, data) => this._onEvent(ev, data)));\n res.on(\"end\", () => {\n if (!this._closed) this.onClose?.();\n });\n });\n this._streamReq = req;\n req.on(\"error\", (err: Error) => {\n if (!this._closed) this.onError?.(err);\n });\n req.end();\n }\n\n private _onEvent(event: string, data: string): void {\n if (event === \"endpoint\") {\n this._postUrl = new URL(data, this._url).toString();\n this.onOpen?.();\n } else if (event === \"message\") {\n this.onMessage?.(data);\n }\n }\n\n send(data: string): void {\n if (!this._postUrl) return;\n const req = makeRequest(new URL(this._postUrl), { method: \"POST\", headers: { ...this._headers, \"Content-Type\": \"application/json\" } }, (res) => res.resume());\n req.on(\"error\", (err: Error) => this.onError?.(err));\n req.end(data);\n }\n\n close(): void {\n this._closed = true;\n this._streamReq?.destroy();\n this._streamReq = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Streamable HTTP (MCP 2025-03-26)\n// ---------------------------------------------------------------------------\n\nclass StreamableHttpRemoteTransport implements IRemoteTransport {\n onMessage: ((data: string) => void) | null = null;\n onOpen: (() => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private _sessionId: string | null = null;\n private _streamReq: ClientRequest | null = null;\n private _closed = false;\n /** Reopen attempts since the standalone GET stream last stayed up healthily. */\n private _streamAttempt = 0;\n /** Pending reopen timer, `null` when no reopen is scheduled. */\n private _streamRetryTimer: ReturnType<typeof setTimeout> | null = null;\n /** Set once the server says it has no standalone GET stream (405 / 501). */\n private _streamUnsupported = false;\n\n constructor(\n private readonly _url: string,\n private readonly _headers: Record<string, string>,\n /** Human name of the upstream, used in every diagnostic this class emits. */\n private readonly _label: string\n ) {}\n\n connect(): void {\n // Streamable HTTP is stateless, there is no connection to open. The\n // transport is usable as soon as connect() is called; the session id\n // is captured later from the first response that carries one.\n this._closed = false;\n this._streamAttempt = 0;\n this._streamUnsupported = false;\n this.onOpen?.();\n }\n\n send(data: string): void {\n if (this._closed) return;\n const headers: Record<string, string> = {\n ...this._headers,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n };\n if (this._sessionId) headers[\"Mcp-Session-Id\"] = this._sessionId;\n const req = makeRequest(new URL(this._url), { method: \"POST\", headers }, (res) => this._handleResponse(res));\n req.on(\"error\", (err: Error) => {\n if (!this._closed) this.onError?.(err);\n });\n req.end(data);\n }\n\n private _handleResponse(res: IncomingMessage): void {\n const sid = res.headers[\"mcp-session-id\"];\n if (typeof sid === \"string\" && sid.length > 0 && sid !== this._sessionId) {\n this._sessionId = sid;\n this._openServerStream();\n }\n const status = res.statusCode ?? 0;\n if (status === 202) {\n res.resume();\n return;\n }\n if (status >= 400) {\n this.onError?.(new Error(`Streamable HTTP POST responded ${status}`));\n res.resume();\n return;\n }\n res.setEncoding(\"utf8\");\n if (String(res.headers[\"content-type\"] ?? \"\").includes(\"text/event-stream\")) {\n const decoder = new SseDecoder();\n res.on(\"data\", (chunk: string) =>\n decoder.feed(chunk, (ev, data) => {\n if (ev === \"message\") this.onMessage?.(data);\n })\n );\n } else {\n let body = \"\";\n res.on(\"data\", (chunk: string) => {\n body += chunk;\n });\n res.on(\"end\", () => this._emitJsonBody(body));\n }\n }\n\n private _emitJsonBody(body: string): void {\n const trimmed = body.trim();\n if (!trimmed) return;\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n for (const message of parsed) this.onMessage?.(JSON.stringify(message));\n return;\n }\n } catch {\n // Not JSON at all. In practice this is a reverse proxy or gateway\n // answering in place of the MCP server, classically an HTML error\n // page served with status 200. The body is still forwarded verbatim\n // so the client fails fast instead of hanging, but it has to be named\n // here: otherwise the only symptom is an \"unexpected token <\" on the\n // client with nothing saying which upstream produced it.\n console.error(\n `[broker] upstream \"${this._label}\": ${this._url} answered a POST with a body that is not JSON. Forwarding it verbatim to the slot's clients, which will report a parse error. ` +\n `Body: ${bodyExcerpt(trimmed)} ` +\n `Something in front of the MCP server is answering instead of it: make the proxy pass POST ${this._url} through untouched, or point this upstream's url straight at the MCP server.`\n );\n }\n this.onMessage?.(trimmed);\n }\n\n /**\n * Opens the optional standalone GET stream that carries server-initiated\n * messages (`notifications/tools/list_changed`, sampling requests, log\n * messages).\n *\n * POST traffic keeps working without it, so a stream that dies quietly\n * presents as \"the tool list went stale and never refreshes\" while the slot\n * still reports as connected. Every drop is therefore named and the stream\n * is reopened with backoff.\n */\n private _openServerStream(): void {\n if (this._closed || this._streamReq || this._streamUnsupported) return;\n this._clearStreamRetry();\n const headers: Record<string, string> = { ...this._headers, Accept: \"text/event-stream\" };\n if (this._sessionId) headers[\"Mcp-Session-Id\"] = this._sessionId;\n const req = makeRequest(new URL(this._url), { method: \"GET\", headers }, (res) => {\n const status = res.statusCode ?? 0;\n // 405 / 501 is the documented \"this server has no standalone GET\n // stream\" answer. Nothing is wrong and a retry cannot change it.\n if (status === 405 || status === 501) {\n this._streamUnsupported = true;\n res.resume();\n this._streamReq = null;\n return;\n }\n if (status >= 400) {\n res.resume();\n this._streamReq = null;\n this._scheduleServerStreamReopen(\n `the standalone GET stream was refused with HTTP ${status}` +\n (status === 401 || status === 403\n ? `. POST requests are still accepted, so the upstream is reachable but the GET stream is not authorized: check that the headers configured for this upstream are also honored on GET ${this._url}`\n : \"\")\n );\n return;\n }\n const openedAt = Date.now();\n const decoder = new SseDecoder();\n res.setEncoding(\"utf8\");\n res.on(\"data\", (chunk: string) =>\n decoder.feed(chunk, (ev, data) => {\n if (ev === \"message\") this.onMessage?.(data);\n })\n );\n res.on(\"end\", () => {\n this._streamReq = null;\n // A stream that stayed up was healthy, so the next drop starts the\n // backoff over and recovers fast. One that died on arrival keeps\n // the backoff growing instead of hot-looping.\n if (Date.now() - openedAt >= STREAM_HEALTHY_MS) this._streamAttempt = 0;\n this._scheduleServerStreamReopen(\"the standalone GET stream ended\");\n });\n });\n this._streamReq = req;\n req.on(\"error\", (err: Error) => {\n this._streamReq = null;\n this._scheduleServerStreamReopen(`the standalone GET stream failed: ${err.message}`);\n });\n req.end();\n }\n\n /**\n * Names a lost GET stream and schedules a reopen with exponential backoff.\n * Gated on `_closed` so a deliberate {@link close} never reconnects, and on\n * `_streamUnsupported` so a server without the stream is not retried.\n */\n private _scheduleServerStreamReopen(reason: string): void {\n if (this._closed || this._streamUnsupported || this._streamRetryTimer) return;\n const attempt = ++this._streamAttempt;\n const delay = Math.min(STREAM_REOPEN_MAX_MS, STREAM_REOPEN_BASE_MS * 2 ** Math.min(attempt - 1, STREAM_REOPEN_MAX_DOUBLINGS));\n console.error(\n `[broker] upstream \"${this._label}\": ${reason}. Server-initiated messages from ${this._url} (tool and prompt list_changed notifications, sampling requests) stop until it is back, ` +\n `while POST requests keep working and the slot keeps reporting as connected. Reopening in ${delay}ms (attempt ${attempt}).`\n );\n const timer = setTimeout(() => {\n this._streamRetryTimer = null;\n this._openServerStream();\n }, delay);\n timer.unref();\n this._streamRetryTimer = timer;\n }\n\n /** Cancels a pending reopen, if any. */\n private _clearStreamRetry(): void {\n if (!this._streamRetryTimer) return;\n clearTimeout(this._streamRetryTimer);\n this._streamRetryTimer = null;\n }\n\n close(): void {\n this._closed = true;\n this._clearStreamRetry();\n this._streamReq?.destroy();\n this._streamReq = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the transport of the given kind.\n *\n * `label` is the provider slot name this transport serves. It appears in every\n * diagnostic the transport emits, so an operator reading a broker log knows\n * which upstream is misbehaving without correlating URLs by hand. It defaults to\n * the URL when the caller has nothing better.\n */\nexport function createRemoteTransport(url: string, kind: RemoteTransportKind, headers: Record<string, string>, label: string = url): IRemoteTransport {\n switch (kind) {\n case \"websocket\":\n return new WebSocketRemoteTransport(url, headers);\n case \"sse\":\n return new SseRemoteTransport(url, headers);\n case \"streamable-http\":\n return new StreamableHttpRemoteTransport(url, headers, label);\n }\n}\n\n/** @deprecated Use {@link IRemoteTransport}. */\nexport type RemoteTransport = IRemoteTransport;\n\n/** Heuristic transport detection from the URL when none is configured. */\nexport function detectTransport(url: string): RemoteTransportKind {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"streamable-http\";\n }\n if (parsed.protocol === \"ws:\" || parsed.protocol === \"wss:\") return \"websocket\";\n if (parsed.pathname.replace(/\\/+$/, \"\").endsWith(\"/sse\")) return \"sse\";\n return \"streamable-http\";\n}\n","import type { IUpstream } from \"./upstream\";\nimport { createRemoteTransport, detectTransport, type IRemoteTransport, type RemoteTransportKind } from \"./remote.transports\";\n\nexport interface IRemoteUpstreamConfig {\n /** Provider slot name this upstream is bound to. */\n name: string;\n /** URL of the remote MCP server. */\n url: string;\n /** Transport to use. Auto-detected from the URL scheme/path when omitted. */\n transport?: RemoteTransportKind;\n /** Extra HTTP / WebSocket headers (e.g. an `Authorization` header). */\n headers?: Record<string, string>;\n /** When `true`, this upstream joins the `_all` aggregate slot once connected. */\n aggregate?: boolean;\n}\n\n/**\n * Bridges a remote MCP server (reachable by URL) into a broker provider slot.\n *\n * The broker-facing contract is identical to {@link StdioUpstream}: the broker\n * muxes the slot's clients onto this single upstream. The only difference is\n * the transport, Streamable HTTP / SSE / WebSocket instead of a child process.\n */\nexport class RemoteUpstream implements IUpstream {\n readonly name: string;\n\n onMessage: ((data: string) => void) | null = null;\n onOpen: (() => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private readonly _config: IRemoteUpstreamConfig;\n private _transport: IRemoteTransport | null = null;\n private _open = false;\n\n constructor(config: IRemoteUpstreamConfig) {\n this.name = config.name;\n this._config = config;\n }\n\n get isOpen(): boolean {\n return this._open;\n }\n\n connect(): void {\n const kind = this._config.transport ?? detectTransport(this._config.url);\n // The slot name is handed to the transport so its own diagnostics (a lost\n // server stream, a non-JSON body) name the upstream an operator configured\n // rather than a bare URL.\n const transport = createRemoteTransport(this._config.url, kind, this._config.headers ?? {}, this.name);\n this._transport = transport;\n\n transport.onOpen = (): void => {\n this._open = true;\n this.onOpen?.();\n };\n transport.onMessage = (data: string): void => this.onMessage?.(data);\n transport.onClose = (): void => {\n this._open = false;\n this.onClose?.();\n };\n transport.onError = (err: Error): void => {\n this.onError?.(new Error(`RemoteUpstream \"${this.name}\": ${err.message}`));\n };\n\n transport.connect();\n }\n\n send(data: string): void {\n this._transport?.send(data);\n }\n\n close(): void {\n this._open = false;\n this._transport?.close();\n this._transport = null;\n }\n}\n\n/** @deprecated Use {@link IRemoteUpstreamConfig}. */\nexport type RemoteUpstreamConfig = IRemoteUpstreamConfig;\n","import { McpAdapterBase, McpToolResults } from \"@cyanmycelium/mcp-core\";\nimport type { McpResourceContent, McpToolResult } from \"@cyanmycelium/mcp-core\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/** URI of the static resource backing the `broker_info` snapshot. */\nexport const BROKER_INFO_URI = \"broker://info\";\n\n/**\n * Read-only adapter that produces a snapshot of the broker's identity and\n * configuration. Backed by the live {@link IBrokerContext}.\n */\nexport class BrokerInfoAdapter extends McpAdapterBase {\n constructor(private readonly _context: IBrokerContext) {\n super(\"broker\");\n }\n\n public async readResourceAsync(uri: string): Promise<McpResourceContent | undefined> {\n if (uri !== BROKER_INFO_URI) return undefined;\n return {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(this._snapshot()),\n };\n }\n\n public async executeToolAsync(_uri: string, toolName: string, _args: Record<string, unknown>): Promise<McpToolResult> {\n if (toolName !== \"broker_info\") {\n return McpToolResults.error(`Unknown tool: ${toolName}`);\n }\n return McpToolResults.json(this._snapshot());\n }\n\n private _snapshot() {\n const c = this._context;\n return {\n name: c.name,\n version: c.version,\n startedAt: c.startedAt?.toISOString() ?? null,\n uptimeSeconds: c.uptimeSeconds,\n host: c.host ?? \"0.0.0.0\",\n port: c.port,\n tls: c.tls,\n paths: c.paths,\n };\n }\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { McpGrammar } from \"@cyanmycelium/mcp-core\";\n\n// ---------------------------------------------------------------------------\n// Open string types, extensibility by convention\n// ---------------------------------------------------------------------------\n\n/**\n * Locale identifier used to look up a grammar JSON file under\n * `<userAgent>/<locale>.json`. Open string: a host application can use any\n * value its grammar resources support.\n *\n * The broker registers each `(userAgent, locale)` pair found on disk as a\n * separate `McpGrammar` keyed by {@link brokerGrammarKey}. The actual\n * resolution of \"which key to use for this session\" is delegated to\n * `@cyanmycelium/mcp-core@0.3.0`'s `grammarResolverFromOptions`, which\n * handles BCP-47 narrowing (`fr-CA` → `fr` → `en`), agent-family fallback,\n * and the optional version dimension natively.\n */\nexport type BrokerLocale = string;\n\n/**\n * User-agent family identifier used to look up a grammar JSON file under\n * `<userAgent>/<locale>.json`. Open string. Conventional values follow\n * the defaults emitted by `grammarResolverFromOptions`: `claude`, `gpt`,\n * `mistral`, `copilot`, plus the universal `default`. Custom families\n * are supported by passing a custom `agents` map in\n * `IStartBrokerServerOptions.grammarResolverOptions`.\n */\nexport type BrokerUserAgent = string;\n\n// ---------------------------------------------------------------------------\n// Canonical grammar key\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the canonical grammar key for the `(userAgent, locale, version?)`\n * matrix the broker registers on disk.\n *\n * Pattern:\n * - `\"<userAgent>:<locale>\"` (no version), e.g. `\"claude:fr\"`, `\"default:en\"`\n * - `\"<userAgent>:<locale>@<version>\"` (versioned), e.g. `\"claude:fr@v2\"`\n *\n * The colon separator is reserved for the `<ua>:<locale>` composition; the\n * `@` separator is reserved for the optional version suffix. Neither\n * character is allowed inside the identifier segments. This matches the\n * default `composeKey` of `grammarResolverFromOptions` exactly, so a\n * broker-loaded grammar at `claude/fr@v2.json` is automatically picked up\n * when a Claude session resolves to the `claude:fr@v2` candidate.\n */\nexport function brokerGrammarKey(userAgent: BrokerUserAgent, locale: BrokerLocale, version?: string): string {\n const base = `${userAgent}:${locale}`;\n return version ? `${base}@${version}` : base;\n}\n\n/**\n * Parses a grammar JSON filename of the form `<locale>.json` or\n * `<locale>@<version>.json` (without the `.json` suffix) into its\n * components. The first `@` (if any) separates locale from version; any\n * additional `@` is folded into the version string.\n *\n * Returns `null` when the input cannot be split into a usable locale.\n */\nexport function parseBrokerGrammarStem(stem: string): { locale: BrokerLocale; version?: string } | null {\n const at = stem.indexOf(\"@\");\n if (at < 0) return stem.length > 0 ? { locale: stem } : null;\n const locale = stem.slice(0, at);\n const version = stem.slice(at + 1);\n if (locale.length === 0 || version.length === 0) return null;\n return { locale, version };\n}\n\n// ---------------------------------------------------------------------------\n// JSON resource loading\n// ---------------------------------------------------------------------------\n\n/**\n * Absolute path of the directory holding the grammar JSON resources.\n *\n * Layout (one folder per user-agent family, one JSON file per locale):\n * ```\n * <GRAMMARS_DIR>/\n * ├── default/\n * │ ├── en.json\n * │ ├── fr.json\n * │ └── zh.json\n * └── claude/\n * ├── en.json\n * └── fr.json\n * ```\n *\n * JSON files live alongside this module in `src/broker/grammars/` during\n * development and are mirrored under `dist/broker/grammars/` at build time\n * by `scripts/copy-assets.mjs`. Adding a new `(userAgent, locale)` pair is\n * just a matter of dropping a new JSON file: no code change required.\n */\nconst GRAMMARS_DIR = join(dirname(fileURLToPath(import.meta.url)), \"grammars\");\n\nconst _cache = new Map<string, McpGrammar>();\n\n/**\n * Loads and caches the grammar for a given `(userAgent, locale, version?)`\n * combination. Returns `undefined` (instead of throwing) when the resource\n * file is missing, so the caller can implement a fallback chain.\n *\n * Filename convention on disk:\n * - `<userAgent>/<locale>.json` (no version)\n * - `<userAgent>/<locale>@<version>.json` (versioned)\n */\nexport function loadBrokerGrammar(userAgent: BrokerUserAgent, locale: BrokerLocale, version?: string): McpGrammar | undefined {\n const key = brokerGrammarKey(userAgent, locale, version);\n const cached = _cache.get(key);\n if (cached) return cached;\n\n const filename = version ? `${locale}@${version}.json` : `${locale}.json`;\n const path = join(GRAMMARS_DIR, userAgent, filename);\n if (!existsSync(path)) return undefined;\n\n const raw = readFileSync(path, \"utf-8\");\n const data = JSON.parse(raw);\n const grammar = McpGrammar.fromJSON(data);\n _cache.set(key, grammar);\n return grammar;\n}\n\n/**\n * Walks a grammars directory and yields every `(userAgent, locale)` pair\n * found on disk. The directory must follow the layout\n * `<dir>/<userAgent>/<locale>.json`.\n *\n * Used by the broker server at startup to bulk-register both the packaged\n * grammars and any local overrides. No hard-coded list of supported\n * user-agents or locales, adding a new grammar is dropping a JSON file.\n */\nexport interface IBrokerGrammarEntry {\n userAgent: BrokerUserAgent;\n locale: BrokerLocale;\n /** Set only for filenames carrying an `@<version>` suffix. */\n version?: string;\n /** Composed via {@link brokerGrammarKey} from the three segments above. */\n key: string;\n grammar: McpGrammar;\n}\n\nexport function* iterBrokerGrammarsFrom(grammarsDir: string): Generator<IBrokerGrammarEntry> {\n if (!existsSync(grammarsDir)) return;\n\n const userAgents = readdirSync(grammarsDir).sort();\n for (const userAgent of userAgents) {\n const uaDir = join(grammarsDir, userAgent);\n if (!statSync(uaDir).isDirectory()) continue;\n\n const files = readdirSync(uaDir).sort();\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n const stem = file.slice(0, -\".json\".length);\n const parsed = parseBrokerGrammarStem(stem);\n if (!parsed) {\n process.stderr.write(`[mcp-broker] Skipping unparseable grammar filename ${file} in ${uaDir}\\n`);\n continue;\n }\n const { locale, version } = parsed;\n const path = join(uaDir, file);\n try {\n const raw = readFileSync(path, \"utf-8\");\n const data = JSON.parse(raw);\n const grammar = McpGrammar.fromJSON(data);\n yield {\n userAgent,\n locale,\n version,\n key: brokerGrammarKey(userAgent, locale, version),\n grammar,\n };\n } catch (err) {\n process.stderr.write(`[mcp-broker] Failed to load grammar ${path}: ${(err as Error).message}\\n`);\n }\n }\n }\n}\n\n/**\n * Walks the **packaged** grammars directory (the one shipped with the\n * mcp-broker package). Equivalent to `iterBrokerGrammarsFrom(<packaged-dir>)`.\n *\n * For local user overrides, see {@link iterBrokerGrammarsFrom} with a custom\n * directory, typically `.mcp-broker/grammars/` next to the config file.\n */\nexport function* iterAvailableBrokerGrammars(): Generator<IBrokerGrammarEntry> {\n yield* iterBrokerGrammarsFrom(GRAMMARS_DIR);\n}\n\n/** @deprecated Use {@link IBrokerGrammarEntry}. */\nexport type BrokerGrammarEntry = IBrokerGrammarEntry;\n\n// ---------------------------------------------------------------------------\n// Baseline helpers (used by behaviors to source their inline descriptions)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the baseline grammar used by the broker behaviors as their\n * source-of-truth for inline tool / property descriptions.\n *\n * Conventionally this is `default:en`. Session-specific grammars selected by\n * the resolver override individual entries on top of this baseline.\n *\n * Throws if the JSON resource is missing: the broker behaviors cannot be\n * built without baseline descriptions.\n */\nexport function brokerBaselineGrammar(): McpGrammar {\n const g = loadBrokerGrammar(\"default\", \"en\");\n if (!g) {\n throw new Error(`Required baseline broker grammar \"default:en\" is missing, expected at ${join(GRAMMARS_DIR, \"default\", \"en.json\")}.`);\n }\n return g;\n}\n\n/**\n * Convenience accessor for a baseline tool description. Throws when the\n * tool is not listed in the baseline grammar, i.e. the JSON file is missing\n * an entry for a tool the code knows about.\n */\nexport function brokerBaselineToolDescription(toolName: string): string {\n const desc = brokerBaselineGrammar().getToolDescription(toolName);\n if (!desc) {\n throw new Error(`Missing baseline description for tool \"${toolName}\" in default/en.json.`);\n }\n return desc;\n}\n\n/**\n * Convenience accessor for a baseline property description. Throws when the\n * property is not listed under the tool in the baseline grammar.\n */\nexport function brokerBaselinePropertyDescription(toolName: string, propertyName: string): string {\n const desc = brokerBaselineGrammar().getPropertyDescription(toolName, propertyName);\n if (!desc) {\n throw new Error(`Missing baseline description for property \"${propertyName}\" of tool \"${toolName}\" in default/en.json.`);\n }\n return desc;\n}\n\n/**\n * Convenience accessor for a baseline resource name. Throws when the resource\n * URI has no entry in the baseline grammar.\n */\nexport function brokerBaselineResourceName(uri: string): string {\n const name = brokerBaselineGrammar().getResourceName(uri);\n if (!name) {\n throw new Error(`Missing baseline name for resource \"${uri}\" in default/en.json.`);\n }\n return name;\n}\n\n/**\n * Convenience accessor for a baseline resource description. Throws when the\n * resource URI has no entry in the baseline grammar.\n */\nexport function brokerBaselineResourceDescription(uri: string): string {\n const desc = brokerBaselineGrammar().getResourceDescription(uri);\n if (!desc) {\n throw new Error(`Missing baseline description for resource \"${uri}\" in default/en.json.`);\n }\n return desc;\n}\n\n/**\n * Convenience accessor for a baseline resource template name. Throws when the\n * template URI has no entry in the baseline grammar.\n */\nexport function brokerBaselineResourceTemplateName(uriTemplate: string): string {\n const name = brokerBaselineGrammar().getResourceTemplateName(uriTemplate);\n if (!name) {\n throw new Error(`Missing baseline name for resource template \"${uriTemplate}\" in default/en.json.`);\n }\n return name;\n}\n\n/**\n * Convenience accessor for a baseline resource template description. Throws\n * when the template URI has no entry in the baseline grammar.\n */\nexport function brokerBaselineResourceTemplateDescription(uriTemplate: string): string {\n const desc = brokerBaselineGrammar().getResourceTemplateDescription(uriTemplate);\n if (!desc) {\n throw new Error(`Missing baseline description for resource template \"${uriTemplate}\" in default/en.json.`);\n }\n return desc;\n}\n","import { McpBehavior } from \"@cyanmycelium/mcp-core\";\nimport type { McpResource, McpTool } from \"@cyanmycelium/mcp-core\";\nimport { BROKER_INFO_URI, BrokerInfoAdapter } from \"../adapters/broker.adapter.info\";\nimport { brokerBaselineResourceDescription, brokerBaselineResourceName, brokerBaselineToolDescription } from \"../broker.grammars\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Exposes basic broker identity (name, version, uptime, listening config) as\n * one tool (`broker_info`) and one resource (`broker://info`).\n *\n * An MCP agent typically calls `broker_info` first to learn who it is talking to.\n */\nexport class BrokerInfoBehavior extends McpBehavior {\n public static readonly NAMESPACE = \"broker\";\n\n constructor(context: IBrokerContext) {\n super(new BrokerInfoAdapter(context), {\n namespace: BrokerInfoBehavior.NAMESPACE,\n });\n }\n\n protected override _buildResources(): McpResource[] {\n return [\n {\n uri: BROKER_INFO_URI,\n name: brokerBaselineResourceName(BROKER_INFO_URI),\n mimeType: \"application/json\",\n description: brokerBaselineResourceDescription(BROKER_INFO_URI),\n },\n ];\n }\n\n protected override _buildTools(): McpTool[] {\n return [\n {\n name: \"broker_info\",\n description: brokerBaselineToolDescription(\"broker_info\"),\n inputSchema: {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n },\n },\n ];\n }\n}\n","import { McpAdapterBase, McpToolResults } from \"@cyanmycelium/mcp-core\";\nimport type { McpResourceContent, McpToolResult } from \"@cyanmycelium/mcp-core\";\nimport type { IBrokerContext, IBrokerProviderInfo } from \"../broker.context\";\n\n/** URI of the static resource that lists every provider slot. */\nexport const PROVIDERS_URI = \"broker://providers\";\n\n/** RFC 6570 URI template for one specific provider slot. */\nexport const PROVIDER_URI_TEMPLATE = \"broker://providers/{name}\";\n\n/**\n * Adapter that exposes the broker's current provider slots, both as a list\n * (read of `broker://providers`) and individually (`broker://providers/<name>`).\n */\nexport class BrokerProvidersAdapter extends McpAdapterBase {\n constructor(private readonly _context: IBrokerContext) {\n super(\"broker\");\n }\n\n public async readResourceAsync(uri: string): Promise<McpResourceContent | undefined> {\n if (uri === PROVIDERS_URI) {\n return {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(this._listSnapshot()),\n };\n }\n\n // broker://providers/<name>\n const match = /^broker:\\/\\/providers\\/([^/]+)$/.exec(uri);\n if (match) {\n const name = decodeURIComponent(match[1]);\n const info = this._context.getProviderInfo(name);\n if (!info) return undefined;\n return {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(info),\n };\n }\n\n return undefined;\n }\n\n public async executeToolAsync(_uri: string, toolName: string, args: Record<string, unknown>): Promise<McpToolResult> {\n switch (toolName) {\n case \"providers_list\":\n return McpToolResults.json(this._listSnapshot());\n\n case \"provider_status\": {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n if (!name) return McpToolResults.error('Missing required argument: \"name\" (string).');\n const info = this._context.getProviderInfo(name);\n if (!info) return McpToolResults.error(`Unknown provider: \"${name}\".`);\n return McpToolResults.json(info);\n }\n\n default:\n return McpToolResults.error(`Unknown tool: ${toolName}`);\n }\n }\n\n private _listSnapshot(): { count: number; providers: IBrokerProviderInfo[] } {\n const providers = this._context.getProvidersInfo();\n return { count: providers.length, providers };\n }\n}\n","import { McpBehavior } from \"@cyanmycelium/mcp-core\";\nimport type { McpResource, McpResourceTemplate, McpTool } from \"@cyanmycelium/mcp-core\";\nimport { BrokerProvidersAdapter, PROVIDERS_URI, PROVIDER_URI_TEMPLATE } from \"../adapters/broker.adapter.providers\";\nimport {\n brokerBaselinePropertyDescription,\n brokerBaselineResourceDescription,\n brokerBaselineResourceName,\n brokerBaselineResourceTemplateDescription,\n brokerBaselineResourceTemplateName,\n brokerBaselineToolDescription,\n} from \"../broker.grammars\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Exposes the broker's provider slots so an MCP agent can discover what is\n * currently routable behind the broker, with two tools:\n *\n * - `providers_list`: every slot (including disconnected ones).\n * - `provider_status({ name })`, detail on one slot.\n *\n * Plus matching resources at `broker://providers` and `broker://providers/<name>`.\n */\nexport class BrokerProvidersBehavior extends McpBehavior {\n public static readonly NAMESPACE = \"broker_providers\";\n\n constructor(context: IBrokerContext) {\n super(new BrokerProvidersAdapter(context), {\n namespace: BrokerProvidersBehavior.NAMESPACE,\n });\n }\n\n protected override _buildResources(): McpResource[] {\n return [\n {\n uri: PROVIDERS_URI,\n name: brokerBaselineResourceName(PROVIDERS_URI),\n mimeType: \"application/json\",\n description: brokerBaselineResourceDescription(PROVIDERS_URI),\n },\n ];\n }\n\n protected override _buildTemplate(): McpResourceTemplate[] {\n return [\n {\n uriTemplate: PROVIDER_URI_TEMPLATE,\n name: brokerBaselineResourceTemplateName(PROVIDER_URI_TEMPLATE),\n mimeType: \"application/json\",\n description: brokerBaselineResourceTemplateDescription(PROVIDER_URI_TEMPLATE),\n },\n ];\n }\n\n protected override _buildTools(): McpTool[] {\n return [\n {\n name: \"providers_list\",\n description: brokerBaselineToolDescription(\"providers_list\"),\n inputSchema: {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: \"provider_status\",\n description: brokerBaselineToolDescription(\"provider_status\"),\n inputSchema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description: brokerBaselinePropertyDescription(\"provider_status\", \"name\"),\n },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n },\n ];\n }\n}\n","/**\n * The broker's self-documentation, as plain Markdown constants.\n *\n * This module is the **source of truth** for how to integrate with an\n * mcp-broker instance. It is served live over MCP by\n * {@link BrokerGuideBehavior} (resources `broker://guide/*` and the\n * `broker_guide` tool), so an agent that can reach the reserved `_broker`\n * slot, or `_all` which aggregates it, learns the integration rules without\n * ever opening a README.\n *\n * Every statement here is derived from the broker's own source, not from the\n * repository's prose documentation. When the two disagree, this file is right\n * and the prose is stale. The markdown docs and the samples import these\n * constants rather than restating them, so there is exactly one copy of the\n * rules to keep correct.\n *\n * Content is written for a machine reader with no prior knowledge of this\n * project: rules are stated as rules, failure modes name their observable\n * signature, and every diagnosis ends in an action.\n */\n\n// ---------------------------------------------------------------------------\n// Topics\n// ---------------------------------------------------------------------------\n\n/**\n * Identifier of one guide page. Also the last URI segment of the matching\n * `broker://guide/<topic>` resource, and the value accepted by the\n * `broker_guide` tool's `topic` argument.\n */\nexport type BrokerGuideTopic = \"index\" | \"publish-provider\" | \"connect-client\" | \"host-config\" | \"deploy\" | \"troubleshooting\";\n\n/** Scheme + path prefix shared by every guide resource URI. */\nexport const BROKER_GUIDE_URI_PREFIX = \"broker://guide/\";\n\n/** RFC 6570 URI template covering every guide page. */\nexport const BROKER_GUIDE_URI_TEMPLATE = \"broker://guide/{topic}\";\n\n/** One guide page: its identity, its one-line pitch, and its Markdown body. */\nexport interface IBrokerGuide {\n /** Stable topic id, used by the tool argument and the resource URI. */\n topic: BrokerGuideTopic;\n\n /** Canonical resource URI, `broker://guide/<topic>`. */\n uri: string;\n\n /** Short human title, e.g. \"Publish a provider\". */\n title: string;\n\n /** One line describing when to read this page. Shown in the index. */\n summary: string;\n\n /** The page body, Markdown, self-contained. */\n content: string;\n}\n\n// ---------------------------------------------------------------------------\n// Shared fragments\n// ---------------------------------------------------------------------------\n\n/**\n * The pairing rule, verbatim in every page that can be reached by someone\n * about to make the mistake. Restated rather than cross-referenced on\n * purpose: an agent may read exactly one page.\n */\nconst PAIRING_RULE = [\n \"```\",\n \" DirectTransport <-> ws://<host>/provider/<name> plain JSON-RPC frames\",\n \" MultiplexTransport <-> ws://<host>/providers envelope frames { provider, payload }\",\n \"```\",\n \"\",\n \"`ws://<host>/providers/<name>` is NEITHER of those two. The broker's router\",\n \"matches `/providers` exactly and `/provider/` as a prefix, so a URL that starts\",\n \"with `/providers/` falls through to the client branch and is accepted as an MCP\",\n \"**client** on a slot literally named `providers/<name>`. Nothing errors. Your\",\n \"provider is not published, and the slot you meant stays empty forever.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// index\n// ---------------------------------------------------------------------------\n\nconst GUIDE_INDEX = [\n \"# mcp-broker integration guide\",\n \"\",\n \"You are reading the built-in documentation of a running mcp-broker instance.\",\n \"It is authoritative for THIS broker. You do not need a README, and you should\",\n \"not trust one that disagrees with this text.\",\n \"\",\n \"## What the broker is\",\n \"\",\n \"One process that puts N MCP servers behind one host and one port. Each server\",\n \"occupies a named **slot**. Servers reach a slot from the inside as *providers*;\",\n \"MCP clients reach a slot from the outside over HTTP, SSE, WebSocket or stdio.\",\n \"Slots are created lazily: any name works, there is no registry to declare.\",\n \"\",\n \"## The one rule that costs the most time\",\n \"\",\n \"A provider's transport and its URL path are a matched pair.\",\n \"\",\n PAIRING_RULE,\n \"\",\n \"Get it wrong in the DirectTransport-on-`/providers` direction and the slot is\",\n \"never claimed. Get it wrong the other way and the slot reports itself connected\",\n \"while every client request hangs. This broker detects both on your first frame\",\n \"and closes the socket with code `1008` and a reason naming the correction, but\",\n \"it cannot detect a provider that connects and never sends anything, and older\",\n \"brokers say nothing at all. See `broker://guide/publish-provider`.\",\n \"\",\n \"## The pages\",\n \"\",\n \"| topic | read it when |\",\n \"|---|---|\",\n \"| `publish-provider` | you have an MCP server and want this broker to expose it |\",\n \"| `connect-client` | you have an MCP client and want to reach a slot |\",\n \"| `host-config` | you are wiring Claude Desktop or another stdio MCP host |\",\n \"| `deploy` | you are choosing between embedding the broker and running it |\",\n \"| `troubleshooting` | something is already broken: symptom, cause, fix |\",\n \"\",\n \"Read a page as a resource (`broker://guide/<topic>`) or call\",\n '`broker_guide({ topic: \"<topic>\" })`. Calling `broker_guide` with no argument',\n \"returns this index.\",\n \"\",\n \"## Tools on this slot\",\n \"\",\n \"| tool | what it answers |\",\n \"|---|---|\",\n \"| `broker_info` | identity, version, uptime, bind address, TLS, effective URL paths |\",\n \"| `providers_list` | every known slot, connected or not, with live counters |\",\n \"| `provider_status({ name })` | one slot in detail |\",\n \"| `broker_guide({ topic? })` | these pages |\",\n \"| `broker_diagnose({ slot? })` | live state PLUS detected problems, each with a fix |\",\n \"\",\n \"When something does not work, call `broker_diagnose` before reading anything.\",\n \"It does the correlation for you and names the fix.\",\n \"\",\n \"## Reserved slots\",\n \"\",\n \"- `_broker`: this slot. Introspection only. It routes to nothing else.\",\n \"- `_all`: an aggregate that unions the tools and prompts of every opted-in\",\n \" provider, including `_broker`. Tool names are prefixed `<slot>-<original>`.\",\n \" It is the correct target for a stdio MCP host. See `broker://guide/host-config`.\",\n \"\",\n \"## Vocabulary\",\n \"\",\n \"- **slot**: a name. Providers publish into it; clients connect to it.\",\n \"- **provider**: an MCP *server* that connects INTO the broker to serve a slot.\",\n \"- **client**: an MCP *client* that connects to the broker to reach a slot.\",\n \"- **upstream**: a provider the broker itself starts or dials out to\",\n \" (a child process, a remote URL, a signed `.mcpb` bundle).\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// publish-provider\n// ---------------------------------------------------------------------------\n\nconst GUIDE_PUBLISH_PROVIDER = [\n \"# Publish an MCP server into a broker slot\",\n \"\",\n \"## 1. The pairing rule\",\n \"\",\n \"A provider's transport and its URL path are a matched pair. This is the single\",\n \"most expensive mistake to make against this broker: both ways of getting it\",\n \"wrong leave every side believing it succeeded.\",\n \"\",\n PAIRING_RULE,\n \"\",\n \"Two more paths that look plausible and are not. Both are now refused at the\",\n \"WebSocket handshake with HTTP 400, and the response body is the full\",\n \"diagnosis; a Node client reads it off the `unexpected-response` event, a\",\n \"browser sees only a bare `error` event and you have to read the broker log:\",\n \"\",\n \"- `ws://<host>/provider` with no name. It used to be accepted and to occupy a\",\n \" slot literally named `(unnamed)`, which no client could address.\",\n \"- `ws://<host>/provider/a/b`, more than one segment after the prefix. A slot\",\n \" name containing `/` must be percent-encoded: `/provider/a%2Fb`. Both\",\n \" spellings resolve to the same slot, so only the encoded one is accepted and\",\n \" nothing is lost. Prefer a flat name anyway.\",\n \"\",\n \"## 2. How each mismatch presents\",\n \"\",\n \"The broker inspects the first frame on a provider socket and refuses both\",\n \"directions: it answers in the framing the peer can actually decode, then\",\n \"closes with code `1008` and a reason naming both corrections. Only an\",\n \"unambiguous frame triggers this (an envelope with no `jsonrpc` on the\",\n \"slot-scoped path, a `jsonrpc` frame that is not an envelope on the multiplex\",\n \"path), so a dialect the broker does not recognize is still left alone.\",\n \"\",\n \"Do not rely on the refusal. It cannot fire before your first frame, so a\",\n \"provider that connects and stays silent still looks connected, and older\",\n \"brokers say nothing at all. The signatures below are what you read then.\",\n \"\",\n \"**MultiplexTransport pointed at `/provider/<name>`.** The slot-scoped path takes\",\n \"the slot name from the URL at connect time, so registration succeeds before any\",\n 'frame exists: `providers_list` reports `connected: true, transport: \"ws\"`. But',\n \"the broker now writes plain JSON-RPC onto that socket, and MultiplexTransport\",\n \"drops every frame that is not an envelope. Your MCP server never receives\",\n \"`initialize`. Meanwhile your envelope-wrapped replies carry no top-level `id`,\",\n \"so the broker classifies them as notifications and broadcasts them instead of\",\n \"answering the waiting request.\",\n \"\",\n \" Observable signature: `provider_status` shows `connected: true`,\",\n ' `transport: \"ws\"`, `pendingCount` climbing and never returning to 0, while the',\n \" client's `initialize` never resolves. `broker_diagnose` reports this as\",\n \" `transport-path-mismatch`.\",\n \"\",\n \"**DirectTransport pointed at `/providers`.** The multiplex path learns slot names\",\n \"only from envelopes. A plain JSON-RPC frame has no `provider`/`payload` pair, so\",\n \"it is dropped and no slot is ever claimed.\",\n \"\",\n \" Observable signature: the socket is open on your side, and the slot does not\",\n \" appear in `providers_list` at all. Clients get\",\n ' `-32000 Provider \"<name>\" not connected`.',\n \"\",\n \"## 3. Dedicated socket (DirectTransport)\",\n \"\",\n \"One socket per slot. The slot is claimed the instant the socket opens, before\",\n \"any frame is sent, so a client arriving first is served immediately.\",\n \"\",\n \"```ts\",\n 'import { DirectTransport } from \"@cyanmycelium/mcp-broker-provider\";',\n 'import { McpServerBuilder } from \"@cyanmycelium/mcp-core\";',\n \"\",\n 'const transport = new DirectTransport(\"ws://localhost:3000/provider/my-slot\");',\n \"const server = new McpServerBuilder()\",\n ' .withName(\"my-slot\")',\n \" .withTransport(transport)\",\n \" .register(/* your behaviors */)\",\n \" .build();\",\n \"\",\n \"await server.start(); // opens the socket\",\n \"```\",\n \"\",\n \"`server.start()` resolving means the socket reported itself open. It does NOT\",\n \"mean the broker accepted the slot: a refusal arrives after the open as a\",\n \"WebSocket close with code 1008, and the reason string says which refusal it was.\",\n \"\",\n \"## 4. Shared socket (MultiplexTransport)\",\n \"\",\n \"One socket carrying N slots, keyed per frame. Use it when one page or one\",\n \"process publishes several servers.\",\n \"\",\n \"```ts\",\n 'import { MultiplexTransport } from \"@cyanmycelium/mcp-broker-provider\";',\n \"\",\n 'const a = MultiplexTransport.create(\"scene-1\", \"ws://localhost:3000/providers\");',\n 'const b = MultiplexTransport.create(\"scene-2\", \"ws://localhost:3000/providers\");',\n \"// a and b share one WebSocket. Same URL means same socket.\",\n \"```\",\n \"\",\n \"On open it sends one registration notification per slot,\",\n '`{ \"provider\": \"<name>\", \"payload\": { \"jsonrpc\": \"2.0\", \"method\": \"notifications/register\" } }`,',\n \"so the broker creates the slot before your first MCP frame. MultiplexTransport\",\n \"reconnects on its own with exponential backoff and jitter, capped at 30s.\",\n \"DirectTransport does not reconnect at all: if you need that, reconnect yourself\",\n \"in `onClose`.\",\n \"\",\n \"## 5. Wire format\",\n \"\",\n \"Slot-scoped socket, both directions, plain MCP frames:\",\n \"\",\n \"```json\",\n '{ \"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools/list\" }',\n \"```\",\n \"\",\n \"Multiplex socket, both directions, every frame wrapped:\",\n \"\",\n \"```json\",\n '{ \"provider\": \"scene-1\", \"payload\": { \"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools/list\" } }',\n \"```\",\n \"\",\n \"A frame the broker cannot decode on the multiplex socket is dropped, and the\",\n \"first drop per socket is logged with the reason. A plain JSON-RPC frame there\",\n \"is not merely dropped: it is the DirectTransport-on-`/providers` mismatch, so\",\n \"it is answered with a bare JSON-RPC error and the socket is closed with `1008`.\",\n \"A tunnel-level refusal comes back as an envelope whose payload is a JSON-RPC\",\n \"error with `id: null` and code `-32000` (slot unavailable) or `-32001`\",\n \"(registration forbidden).\",\n \"\",\n \"## 6. Joining the `_all` aggregate\",\n \"\",\n \"A provider is NOT in `_all` by default. Opting in is per provider and depends on\",\n \"how the provider reaches the broker.\",\n \"\",\n \"| provider kind | how it joins `_all` |\",\n \"|---|---|\",\n \"| WebSocket on `/provider/<name>` | send the aggregate opt-in as the socket's **first** frame, see below |\",\n \"| WebSocket on `/providers` (multiplex) | announce it in the registration envelope, see below |\",\n '| `stdioUpstreams[]` config entry | set `\"aggregate\": true` (omitted means NOT aggregated) |',\n '| `mcpServers[]` config entry | aggregated by default; set `\"aggregate\": false` to opt out |',\n '| `mcpbBundles[]` config entry | aggregated by default; set `\"aggregate\": false` to opt out |',\n \"| `_broker` | always, automatically |\",\n \"\",\n \"### From the SDK\",\n \"\",\n \"```ts\",\n 'new DirectTransport(\"ws://localhost:3000/provider/my-slot\", { aggregate: true });',\n 'MultiplexTransport.create(\"my-slot\", \"ws://localhost:3000/providers\", { aggregate: true });',\n \"```\",\n \"\",\n \"Both send the JSON-RPC-shaped registration notification on open,\",\n '`{\"jsonrpc\":\"2.0\",\"method\":\"notifications/register\",\"params\":{\"aggregate\":true}}`,',\n \"wrapped in an envelope on the shared socket.\",\n \"\",\n \"### The raw control frame\",\n \"\",\n \"The broker also accepts a non-JSON-RPC control frame on the slot-scoped path,\",\n \"which is what to send when you drive the socket yourself:\",\n \"\",\n \"```ts\",\n 'const ws = new WebSocket(\"ws://localhost:3000/provider/my-slot\");',\n \"ws.onopen = () => {\",\n ' ws.send(JSON.stringify({ type: \"register\", aggregate: true }));',\n \" // ... then hand the socket to your transport / start the server\",\n \"};\",\n \"```\",\n \"\",\n \"It must be the FIRST frame on that socket. The broker inspects exactly one frame\",\n \"per socket for this, and a frame carrying `jsonrpc` is routed as traffic, so a\",\n \"socket that has already sent an MCP frame stays non-aggregated for its whole life.\",\n \"\",\n \"**Do not assume the opt-in took.** The two shapes are honored by different\",\n \"broker versions, and a refused or ignored opt-in produces no error. Verify:\",\n \"call `tools/list` on the `_all` slot and look for your `<slot>-<tool>` names, or\",\n \"call `broker_diagnose()`, which reports `aggregate-empty` and\",\n \"`aggregate-missing-live-slots` when a connected slot is not in the aggregate.\",\n \"\",\n \"**Install your MCP message handler before you opt in.** The moment the broker\",\n \"accepts the aggregate registration it opens an internal client and sends\",\n \"`initialize`. A provider that is not listening yet fails that handshake and is\",\n \"dropped from `_all` silently, with no log and no retry.\",\n \"\",\n \"## 7. Lifecycle: connect, register, release\",\n \"\",\n \"1. **Connect.** Open the WebSocket at the path that matches your transport.\",\n \"2. **Register.** Slot-scoped: automatic, from the URL. Multiplex: from the first\",\n \" envelope, which the SDK sends on open. Optionally opt into `_all` first.\",\n \"3. **Release.** Close the socket. There is no release message: the only control\",\n \" frame the broker understands is the registration frame. On close the broker\",\n \" clears the slot and fails every in-flight request with\",\n ' `-32000 Provider \"<name>\" disconnected`, echoing the original request id.',\n \"\",\n \"**Release explicitly anyway.** A slot is occupied while the incumbent socket is\",\n \"`readyState === OPEN`, and a socket that dies without sending a close frame (a\",\n \"hard kill, a crashed tab, a suspended laptop, devtools set to offline) stays\",\n \"OPEN until the OS TCP keepalive gives up, which is hours.\",\n \"\",\n \"```ts\",\n \"// Browsers fire pagehide reliably on reload, navigation and tab close.\",\n 'addEventListener(\"pagehide\", () => transport.close());',\n \"```\",\n \"\",\n \"A ws-level ping/pong heartbeat is what stops that from wedging the slot\",\n \"forever. Each provider socket is pinged every `providerHeartbeatIntervalMs`\",\n \"(default 30000; `0` disables it), and one that misses a full interval is\",\n \"terminated and its slot freed. So a reconnect in the gap is still refused with\",\n 'close code 1008 and reason `Provider \"<name>\" is already connected`, but the',\n \"window is one interval rather than hours. Releasing on `pagehide` is what makes\",\n \"it instant instead.\",\n \"\",\n '`providerTakeover` decides who wins the contention: `\"liveness\"` (default) lets',\n 'the newcomer in only once the incumbent has missed a heartbeat, `\"reject\"` never',\n 'hands a slot over, and `\"always\"` is honored only when provider authentication',\n \"is configured and the newcomer authenticated as the same principal (otherwise\",\n 'the broker logs why and falls back to `\"liveness\"`).',\n \"\",\n \"One honest limit: an RFC 6455 pong is answered by the browser's network stack,\",\n \"so the heartbeat proves the process is alive, not that the page's JS thread is\",\n \"serving. A throttled background tab answers pings and still never replies to a\",\n \"request; `providerRequestTimeoutMs` is what covers that case.\",\n \"\",\n \"## 8. Refusals you can receive\",\n \"\",\n \"On the slot-scoped socket a refusal is a WebSocket close with code 1008; the\",\n \"reason string is the message below. On the multiplex socket it is an error\",\n \"envelope for that slot name and the socket stays open.\",\n \"\",\n \"| reason | cause | fix |\",\n \"|---|---|---|\",\n '| `Provider \"<n>\" is already connected` | a live socket holds the slot | release on `pagehide`; a genuinely dead holder is reaped within one heartbeat interval (default 30s), so retry |',\n '| `Provider \"<n>\" is reserved by the broker` | you targeted `_broker` or `_all` | pick another slot name |',\n '| `Provider \"<n>\" is managed by a stdio upstream` | the name collides with a configured upstream | rename one of them |',\n \"| HTTP 401 at the handshake | provider auth is on and no credential was presented | see below |\",\n \"| HTTP 403 at the handshake | your principal may not publish on that slot | widen `allowedResources` |\",\n \"\",\n \"## 9. In a browser\",\n \"\",\n \"- **A bundler is required.** Both packages ship ESM under `dist/`, with no\",\n \" `browser` field and no UMD build, so a plain `<script>` tag will not do.\",\n \"- **Provider authentication cannot work from a browser.** The broker reads the\",\n \" provider secret from the `X-Provider-Token` header or from\",\n \" `Authorization: Bearer`, and the browser `WebSocket` constructor cannot set\",\n \" headers. Neither transport accepts a credential. If the broker is configured\",\n \" with a provider secret, every browser provider is refused at the handshake\",\n \" with HTTP 401, which reaches your page as a bare `error` event with no status.\",\n \" Run the broker without a provider secret, or terminate provider auth in a\",\n \" reverse proxy that injects the header.\",\n \"- A page served by the broker's own static mount is still a browser origin for\",\n \" the purposes of the client-side origin check. Serving the page does not\",\n \" exempt it. See `broker://guide/connect-client`.\",\n \"\",\n \"## 10. In Node\",\n \"\",\n \"Both transports call the **global** `WebSocket` constructor with no import. Node\",\n \"22 and later provide one. On Node 20 assign a polyfill before connecting:\",\n \"\",\n \"```ts\",\n 'import WebSocket from \"ws\";',\n \"globalThis.WebSocket = WebSocket as unknown as typeof globalThis.WebSocket;\",\n \"```\",\n \"\",\n \"If the MCP server and the broker live in the same process, skip WebSockets\",\n \"entirely and call `tunnel.registerLoopbackProvider(name, transport)` with an\",\n \"in-process transport. See `broker://guide/deploy`.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// connect-client\n// ---------------------------------------------------------------------------\n\nconst GUIDE_CONNECT_CLIENT = [\n \"# Reach a slot as an MCP client\",\n \"\",\n \"## 1. Endpoints, per slot\",\n \"\",\n \"| transport | endpoint | notes |\",\n \"|---|---|---|\",\n \"| Streamable HTTP | `POST`, `GET`, `DELETE` `http(s)://<host>/<slot>/mcp` | current MCP transport, use this |\",\n \"| Legacy SSE | `GET http(s)://<host>/<slot>/sse` then `POST .../<slot>/messages` | 2024-11-05 HTTP+SSE, kept for old hosts |\",\n \"| Raw WebSocket | `ws(s)://<host>/<slot>` | bare JSON-RPC frames, no session layer |\",\n \"| stdio bridge | the broker process itself | one slot per broker process, see `broker://guide/host-config` |\",\n \"\",\n \"`<slot>` is the slot name. The HTTP router splits the path on `/` and requires\",\n \"exactly two segments, so a slot name containing `/` must be percent-encoded:\",\n \"slot `a/b` is reachable at `/a%2Fb/mcp`.\",\n \"\",\n \"Default path suffixes are `/mcp`, `/sse` and `/messages`; call `broker_info` to\",\n \"read the effective values if the deployment customized them.\",\n \"\",\n \"## 2. Connecting to a slot that has no provider\",\n \"\",\n \"Slots are lazy. Connecting to a name nobody serves is not an error: the\",\n \"connection succeeds and every request is answered with\",\n '`-32000 Provider \"<slot>\" not connected`. Call `providers_list` on `_broker` to',\n \"see which names actually exist, or `broker_diagnose` to be told why one is empty.\",\n \"\",\n \"## 3. Reserved slots\",\n \"\",\n \"### `_broker`\",\n \"\",\n \"The broker's own introspection server, and nothing else. It exposes\",\n \"`broker_info`, `providers_list`, `provider_status`, `broker_guide` and\",\n \"`broker_diagnose`, plus the resources `broker://info`, `broker://providers`,\",\n \"`broker://providers/{name}` and `broker://guide/{topic}`. It does not proxy any\",\n \"other provider. It is available from the moment the broker finishes starting.\",\n \"\",\n \"### `_all`\",\n \"\",\n \"An aggregate, not a proxy. It presents the union of the tools and prompts of\",\n \"every **opted-in** provider as one MCP server. Membership covers configured\",\n \"upstreams (`stdioUpstreams`, `mcpServers`, `mcpbBundles`), `_broker` itself, and\",\n \"WebSocket provider slots that sent the aggregate opt-in frame. See\",\n \"`broker://guide/publish-provider` for how a provider opts in.\",\n \"\",\n \"Names are prefixed with the origin slot:\",\n \"\",\n \"```\",\n \" <slot>-<original> e.g. weather-forecast, _broker-broker_info\",\n \"```\",\n \"\",\n \"**Never reconstruct a prefixed name.** The prefixed name is capped at 64\",\n \"characters, and an overlong one is truncated and given a hash suffix; a\",\n \"collision between two providers is broken with a `-2`, `-3` suffix. The mapping\",\n \"back to `(provider, original)` is a lookup table, not a parse. Call `tools/list`\",\n \"on `_all` and pass the returned string back verbatim in `tools/call`.\",\n \"\",\n \"Descriptions are tagged with their origin, `[<slot>] <original description>`, so\",\n \"you can tell where a tool came from without parsing its name.\",\n \"\",\n \"`_all` implements `initialize`, `ping`, `tools/list`, `tools/call`,\",\n \"`prompts/list` and `prompts/get`. **Everything else returns\",\n \"`-32601 Method not found`**, including `resources/list` and `resources/read`. If\",\n \"you need a provider's resources, connect to that provider's own slot.\",\n \"\",\n \"`_all` emits `notifications/tools/list_changed` and\",\n \"`notifications/prompts/list_changed` whenever a provider joins, leaves, or\",\n \"changes its catalog. A client that subscribes sees a provider that arrives\",\n \"mid-session without reconnecting.\",\n \"\",\n \"## 4. Browser clients and the origin check\",\n \"\",\n \"All three HTTP client endpoints, `/<slot>/mcp`, `/<slot>/sse` and\",\n \"`/<slot>/messages`, refuse any request carrying an `Origin` header that is not\",\n \"on the allow list, with HTTP 403. **The list is empty by default**, so out of\",\n \"the box no browser origin passes while every non-browser client (which sends no\",\n \"`Origin`) passes. This is deliberate: without the check any page in the user's\",\n \"browser could drive the broker.\",\n \"\",\n \"Serving the page from the broker's own static mount does NOT exempt it. Set the\",\n \"origins explicitly:\",\n \"\",\n \"```json\",\n '{ \"allowedOrigins\": [\"http://localhost:3000\", \"https://app.example.com\"] }',\n \"```\",\n \"\",\n \"or `MCP_BROKER_ALLOWED_ORIGINS=http://localhost:3000,https://app.example.com`.\",\n \"Match the scheme, host and port exactly, as the browser sends them; if the\",\n \"broker runs with TLS the origin is `https://`, not `http://`.\",\n \"\",\n \"The 403 body names the refused origin, says whether the list was unset or set\",\n \"but non-matching, and states the comparison rule, so the usual causes (a\",\n \"trailing slash, `http` against a TLS broker, a missing port) are readable off\",\n \"the response.\",\n \"\",\n \"The **WebSocket** endpoints carry no origin check at all: `ws://<host>/<slot>`\",\n \"and the two provider paths are gated by authorization and by provider auth,\",\n \"never by `Origin`. Do not treat a working WebSocket as evidence that the same\",\n \"page's HTTP requests will pass.\",\n \"\",\n \"## 5. Authorization\",\n \"\",\n \"When OAuth 2.1 is enabled, every HTTP request to a slot must carry\",\n \"`Authorization: Bearer <token>` issued for that slot's canonical resource URI. A\",\n \"missing or invalid token gets 401 with an RFC 9728 `WWW-Authenticate` challenge;\",\n \"a valid token lacking the required scope gets 403 with the missing scope named\",\n \"in the challenge. Protected Resource Metadata is served unauthenticated so a\",\n \"client can discover the authorization server after the first 401.\",\n \"\",\n \"On `_all`, authorization filters the catalog rather than rejecting the call: a\",\n \"caller sees only the providers it is scoped for, and a tool it may not see\",\n \"answers `-32602 Unknown aggregated tool`, deliberately indistinguishable from a\",\n \"name that does not exist.\",\n \"\",\n \"## 6. Errors you can receive, and what they mean\",\n \"\",\n \"| error | meaning |\",\n \"|---|---|\",\n '| `-32000 Provider \"<n>\" ... not connected` | the slot exists but nothing is serving it right now |',\n '| `-32000 Provider \"<n>\" disconnected` | the provider dropped while your request was in flight |',\n '| `-32000 Provider \"<n>\" is no longer connected` | `_all` routed to a provider that left between list and call |',\n '| `-32000 Provider \"<n>\" did not respond within <ms>ms` | the provider stayed connected and never answered; raise `providerRequestTimeoutMs` for genuinely long tools |',\n \"| `-32601 Method not found` | on `_all`, a method outside tools and prompts |\",\n \"| `-32602 Unknown aggregated tool` | on `_all`, a stale or invisible prefixed name; re-list |\",\n \"| HTTP 403 `invalid_origin` | your `Origin` is not on the allow list |\",\n \"| HTTP 401 / 403 | bearer token missing, invalid, or missing a scope |\",\n \"\",\n \"A request that produces no reply at all is not in this table. That is the\",\n \"transport/path mismatch described in `broker://guide/troubleshooting`; call\",\n \"`broker_diagnose` and it will name it.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// host-config\n// ---------------------------------------------------------------------------\n\nconst GUIDE_HOST_CONFIG = [\n \"# Wiring an MCP host (Claude Desktop and friends)\",\n \"\",\n \"## 1. Point the bridge at `_all`, not at your slot\",\n \"\",\n \"This is the second most expensive mistake against this broker, and unlike the\",\n \"transport pairing it is a pure ordering problem.\",\n \"\",\n \"An MCP host starts its servers when the host application launches. It sends\",\n \"`initialize` immediately and treats a failure as a dead server: no retry, no\",\n \"backoff, the entry is disabled for the session. Your provider, meanwhile, does\",\n \"not exist yet. A browser provider needs a human to open a page; a provider in\",\n \"another process needs that process to start.\",\n \"\",\n \"So pinning the stdio bridge to a real slot fails every single time: the bridge\",\n \"answers the host's very first `initialize` with\",\n '`-32000 Provider \"<slot>\" not connected`, and the host gives up.',\n \"\",\n \"**Pin it to `_all`.** `_all` is registered before the broker resumes stdin, it\",\n \"answers `initialize` itself, it already aggregates `_broker` so the host always\",\n \"has at least the introspection tools, and it pushes\",\n \"`notifications/tools/list_changed` when a provider joins, so a page opened ten\",\n \"minutes into the session appears in the host's tool list live.\",\n \"\",\n \"`_broker` is the fallback if you want introspection only. It is also always up,\",\n \"but it will never show you anything except the broker's own five tools.\",\n \"\",\n \"## 2. Claude Desktop recipe\",\n \"\",\n \"```json\",\n \"{\",\n ' \"mcpServers\": {',\n ' \"mcp-broker\": {',\n ' \"command\": \"npx\",',\n ' \"args\": [\"-y\", \"@cyanmycelium/mcp-broker\"],',\n ' \"env\": {',\n ' \"MCP_BROKER_STDIO_PROVIDER\": \"_all\",',\n ' \"MCP_BROKER_PORT\": \"3000\",',\n ' \"MCP_BROKER_HOST\": \"127.0.0.1\"',\n \" }\",\n \" }\",\n \" }\",\n \"}\",\n \"```\",\n \"\",\n \"`MCP_BROKER_STDIO_PROVIDER` is what turns the process into a stdio bridge: stdin\",\n \"carries the host's JSON-RPC, stdout carries the replies, and all logging is\",\n \"redirected to stderr so it cannot corrupt the channel. The broker keeps\",\n \"listening on its port at the same time, so providers can still tunnel in.\",\n \"\",\n \"## 3. One broker per port. Exactly one.\",\n \"\",\n \"Do not add a second host entry that spawns another broker. The second process\",\n \"cannot bind the port and dies; the host reports `Connection closed` with no\",\n \"cause, and the real cause (`EADDRINUSE`) is only in the host's\",\n \"`mcp-server-<name>.log`. If you want two logical servers visible to the host,\",\n \"publish both into the one broker and let `_all` union them. That is the entire\",\n \"point of `_all`.\",\n \"\",\n \"If a broker is already running on the port from another launcher, give the host\",\n \"entry a different `MCP_BROKER_PORT`, or drop the host entry and reach the\",\n \"running broker over Streamable HTTP instead.\",\n \"\",\n \"## 4. The bridge is anonymous\",\n \"\",\n \"The stdio bridge forwards frames to `_all` with **no principal attached**. While\",\n \"no authorization is configured that is invisible. The moment you enable\",\n \"per-provider scopes or a policy that denies an anonymous subject, the host's\",\n \"tool list silently empties: `tools/list` still returns 200 with `tools: []`, and\",\n \"nothing anywhere says why. If you enable authorization and the host goes blank,\",\n \"this is why.\",\n \"\",\n \"## 5. Environment variables the host entry can set\",\n \"\",\n \"| variable | default | meaning |\",\n \"|---|---|---|\",\n \"| `MCP_BROKER_STDIO_PROVIDER` | unset | slot the stdin/stdout bridge serves. Use `_all`. |\",\n \"| `MCP_BROKER_PORT` | `3000` | TCP port |\",\n \"| `MCP_BROKER_HOST` | `0.0.0.0` | bind interface; `127.0.0.1` keeps it local |\",\n \"| `MCP_BROKER_CONFIG` | unset | path to a JSON config file |\",\n \"| `MCP_BROKER_LOCALE` | `en` | locale for the `_broker` tool descriptions |\",\n \"| `MCP_BROKER_ALLOWED_ORIGINS` | unset | comma-separated browser origins for `/<slot>/mcp` |\",\n \"| `MCP_BROKER_TLS_CERT` / `_KEY` | unset | PEM paths; both set means HTTPS and WSS |\",\n \"| `MCP_BROKER_PROTOCOL` | auto | force `http` or `https` |\",\n \"| `MCP_BROKER_WWW_DIR` | unset | serve this directory at `/` |\",\n \"| `MCP_BROKER_BUNDLE_DIR` | unset | serve this directory at `/bundle` |\",\n \"\",\n \"Environment variables win over the config file. Paths in env vars resolve\",\n \"against the working directory; paths in the config file resolve against the\",\n \"config file's own directory.\",\n \"\",\n \"## 6. Verifying the wiring\",\n \"\",\n \"From inside the host, the aggregated introspection tools are named\",\n \"`_broker-broker_info`, `_broker-providers_list`, `_broker-provider_status`,\",\n \"`_broker-broker_guide` and `_broker-broker_diagnose`. If you can see those, the\",\n \"bridge works and `_all` is alive. If you can see nothing else, no provider has\",\n \"opted into the aggregate: call `_broker-broker_diagnose` and it will say so.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// deploy\n// ---------------------------------------------------------------------------\n\nconst GUIDE_DEPLOY = [\n \"# Deploying the broker\",\n \"\",\n \"## 1. Two ways to run it\",\n \"\",\n \"**As a process.** `npx @cyanmycelium/mcp-broker`, configured by\",\n \"`.mcp-broker/config.json` and `MCP_BROKER_*` environment variables. Choose this\",\n \"when the broker is infrastructure: a host entry, a container, a service.\",\n \"\",\n \"**As a library.** Build a tunnel and start it inside your own process. Choose\",\n \"this when your application already owns the port, or when it hosts MCP servers\",\n \"itself and you want them served without a WebSocket round trip.\",\n \"\",\n \"```ts\",\n 'import { WsTunnelBuilder } from \"@cyanmycelium/mcp-broker\";',\n \"\",\n \"const tunnel = new WsTunnelBuilder()\",\n \" .withPort(3000)\",\n ' .withHost(\"127.0.0.1\")',\n ' .withAllowedOrigins([\"http://localhost:5173\"])',\n ' .withStaticMount(\"/\", \"/abs/path/to/www\")',\n \" .build();\",\n \"\",\n \"await tunnel.start();\",\n \"// ... later\",\n \"await tunnel.stop();\",\n \"```\",\n \"\",\n \"An MCP server living in the same process skips the network entirely:\",\n \"\",\n \"```ts\",\n 'import { LoopbackTransport } from \"@cyanmycelium/mcp-core\";',\n \"\",\n \"const [serverEnd, clientEnd] = LoopbackTransport.createPair();\",\n \"const server = new McpServerBuilder().withTransport(serverEnd).register(/* ... */).build();\",\n \"await server.start();\",\n 'tunnel.registerLoopbackProvider(\"in-process\", clientEnd);',\n \"```\",\n \"\",\n \"A loopback slot outranks a WebSocket provider of the same name: the WebSocket\",\n 'one is refused with `Provider \"<n>\" is reserved by the broker`.',\n \"\",\n \"## 2. What `start()` does, in order\",\n \"\",\n \"1. Creates the HTTP(S) server and attaches the WebSocket server.\",\n \"2. Binds the port.\",\n \"3. Starts the provider heartbeat and the request-timeout sweep, both on\",\n \" `unref`'d timers so they never hold a process open.\",\n \"4. Registers the `_all` aggregate slot.\",\n \"5. Wires and connects every configured upstream (`stdioUpstreams`, `mcpServers`,\",\n \" `mcpbBundles`). Upstreams marked `aggregate` join `_all` when they open.\",\n \"6. Attaches the stdio bridge, if configured, and resumes stdin.\",\n \"7. Starts the embedded `_broker` server and adds it to `_all`.\",\n \"\",\n \"Step 4 before step 6 is what makes `_all` a safe stdio bridge target: the slot\",\n \"exists before the host's first byte arrives. Nothing in this sequence waits for\",\n \"a WebSocket provider, because none can exist yet.\",\n \"\",\n \"`start()` **rejects** on a listen failure, and the rejection names the port, the\",\n \"one-broker-per-port rule and the URL to attach to the broker already holding it.\",\n \"Await it and catch it: `void tunnel.start()` turns that into an unhandled\",\n \"rejection. The original errno is preserved as `err.cause`.\",\n \"\",\n \"## 3. Topologies\",\n \"\",\n \"**Browser app plus broker.** The broker serves the page from a static mount and\",\n \"the page publishes a provider over WebSocket. Needs `allowedOrigins` for the\",\n \"page's own origin if the page is also an MCP client, and needs provider auth\",\n \"OFF, because a browser cannot present the provider secret.\",\n \"\",\n \"**Stdio host plus broker plus browser provider.** The host launches the broker\",\n \"pinned to `_all`; the human opens the page later; `_all` pushes\",\n \"`list_changed` and the tools appear. This is the topology `broker://guide/host-config`\",\n \"is written for.\",\n \"\",\n \"**Broker in front of remote MCP servers.** `mcpServers[]` entries: the broker\",\n \"dials out over Streamable HTTP, SSE or WebSocket and republishes each as a slot.\",\n \"Aggregated into `_all` by default.\",\n \"\",\n \"**Broker running signed bundles.** `mcpbBundles[]` entries: each `.mcpb` is a ZIP\",\n \"with a manifest, signature-verified against a trusted public key before being\",\n \"unpacked and spawned as a stdio upstream. A bundle that fails verification is\",\n \"skipped and never spawned. Aggregated into `_all` by default.\",\n \"\",\n \"## 4. Configuration\",\n \"\",\n \"The CLI reads `.mcp-broker/config.json` (or `MCP_BROKER_CONFIG`). Environment\",\n \"variables win over the file. Relative paths in the file resolve against the\",\n \"file's directory; relative paths in env vars resolve against the working\",\n \"directory.\",\n \"\",\n \"```json\",\n \"{\",\n ' \"port\": 3000,',\n ' \"host\": \"127.0.0.1\",',\n ' \"allowedOrigins\": [\"http://localhost:3000\"],',\n ' \"stdioProvider\": \"_all\",',\n ' \"www\": { \"mounts\": [{ \"urlPrefix\": \"/\", \"dir\": \"./www\" }] },',\n ' \"stdioUpstreams\": [',\n ' { \"name\": \"fs\", \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/data\"], \"aggregate\": true }',\n \" ],\",\n ' \"mcpServers\": [{ \"name\": \"geo\", \"url\": \"https://geo.example.com/mcp\" }]',\n \"}\",\n \"```\",\n \"\",\n \"Note the asymmetry, it is real and it bites: a `stdioUpstreams` entry is NOT\",\n 'aggregated unless you write `\"aggregate\": true`, while `mcpServers` and',\n '`mcpbBundles` entries ARE aggregated unless you write `\"aggregate\": false`.',\n \"\",\n \"All six `paths.*` keys are read by the CLI, as `env ?? config ?? default`. One\",\n \"key is still library-only: `brokerName` is a valid config key and `WsTunnel`\",\n \"honors it, but `WsTunnelBuilder` has no `withBrokerName()`, so the CLI cannot\",\n \"forward it and setting it in the file changes nothing. `enableBrokerProvider`\",\n \"and `enableAggregateProvider` are `IWsTunnelOptions` fields only, not config\",\n \"keys at all. Confirm the effective values with `broker_info` rather than\",\n \"assuming the file won.\",\n \"\",\n \"## 5. Static files\",\n \"\",\n \"Mounts are matched longest-prefix-first and JSON-RPC routes always win over\",\n \"them, so a slot named like a directory shadows that directory. Directory\",\n \"requests serve `index.html`. Paths escaping the mount are refused with 403.\",\n \"`MCP_BROKER_WWW_DIR` is a shortcut for a mount at `/`, `MCP_BROKER_BUNDLE_DIR`\",\n \"for one at `/bundle`; a directory that does not exist is skipped with a warning\",\n \"rather than failing startup.\",\n \"\",\n \"## 6. TLS\",\n \"\",\n \"Setting both a certificate and a key switches the whole server to HTTPS and WSS\",\n \"at once. There is no mixed mode: providers then connect with `wss://` and\",\n \"clients with `https://`, and browser origins in `allowedOrigins` must be spelled\",\n \"with `https://`. The files are read synchronously when the tunnel is built, so a\",\n \"wrong path throws before the port is bound.\",\n \"\",\n \"## 7. Shutdown\",\n \"\",\n \"`stop()` tears down in the reverse order of `start()`: the embedded broker\",\n \"server first, then the aggregate, then the stdio bridge, then every session,\",\n \"client socket, provider socket and upstream, then the heartbeat and\",\n \"request-timeout timers, then the listener. It resolves when the HTTP server is\",\n \"fully closed, and a second `stop()` is silent rather than an error. Call it\",\n \"before your process exits so providers see a clean close rather than a dropped\",\n \"connection.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// troubleshooting\n// ---------------------------------------------------------------------------\n\nconst GUIDE_TROUBLESHOOTING = [\n \"# Troubleshooting\",\n \"\",\n \"Call `broker_diagnose()` first. It reads the live state and names the problems\",\n \"it can prove, each with a fix. This page is the reference behind it, and covers\",\n \"the failures the broker cannot see from the inside.\",\n \"\",\n \"## Symptom table\",\n \"\",\n \"| symptom | cause | fix |\",\n \"|---|---|---|\",\n \"| Client hangs forever on `initialize`, and the provider shows connected | transport / path mismatch: a MultiplexTransport on `/provider/<name>` | move the provider to `ws://<host>/providers`, or switch it to `DirectTransport` on `/provider/<name>` |\",\n \"| Provider socket is open, but the slot never appears in `providers_list` | transport / path mismatch the other way: a DirectTransport on `/providers` | move it to `ws://<host>/provider/<name>`, or switch it to `MultiplexTransport` |\",\n \"| Provider connects to `/providers/<name>` and nothing works | that path is neither endpoint: it is accepted as a CLIENT on a slot named `providers/<name>` | drop the name from the URL for multiplex, or add `/provider/` for a dedicated socket |\",\n \"| WebSocket upgrade refused with HTTP 400 before it opens | the path cannot work: bare `/provider` (no slot name) or `/provider/a/b` (more than one segment) | append one slot name; percent-encode a `/` inside it. The 400 body is the full diagnosis; a browser sees only a bare `error` event, so read the broker log |\",\n \"| Socket opens, then closes immediately with 1008 naming DirectTransport or MultiplexTransport | the broker detected the transport/path mismatch on your first frame | apply either correction the reason names; do not reconnect unchanged |\",\n \"| WebSocket closes with 1008 `already connected` right after a page reload | a stale socket still holds the slot | release on `pagehide`; a dead holder is reaped within one heartbeat interval (default 30s), so retry rather than restart |\",\n \"| MCP host reports `Connection closed` with no cause | a second broker could not bind the port | one broker per port; do not spawn one per host entry. `EADDRINUSE` is in the host's `mcp-server-<name>.log` |\",\n \"| HTTP 403 `invalid_origin` from a page the broker itself serves | a static mount does not exempt the origin it serves | set `allowedOrigins` (or `MCP_BROKER_ALLOWED_ORIGINS`) to that exact origin, scheme and port included |\",\n '| `Provider \"<slot>\" not connected` at host start | ordering: the host starts before any provider exists | point `MCP_BROKER_STDIO_PROVIDER` at `_all` |',\n \"| Tool list is stale and never refreshes | a remote upstream's server-to-client stream dropped and is not reopened | restart the broker; the slot keeps answering requests, which is why nothing looks broken |\",\n \"| `_all` shows only `_broker-*` tools | no provider opted into the aggregate, or the opt-in shape this broker honors differs from the one the provider sent | see the aggregate opt-in section in `broker://guide/publish-provider`, and never assume an opt-in took: verify with `tools/list` on `_all` |\",\n \"| Host's tool list goes empty after enabling authorization | the stdio bridge reaches `_all` anonymously | grant the anonymous subject, or stop using the bridge for authorized deployments |\",\n \"| Browser provider gets a bare `error` event and never connects | provider auth is on; a browser cannot send the required header | run without a provider secret, or authenticate in a reverse proxy |\",\n \"| `-32601 Method not found` on `_all` for `resources/list` | `_all` covers tools and prompts only | connect to the provider's own slot for resources |\",\n \"| `-32602 Unknown aggregated tool` on a name you built yourself | prefixed names are capped, hashed and de-duplicated | re-run `tools/list` and pass the returned name back verbatim |\",\n \"\",\n \"## The transport/path mismatch, in detail\",\n \"\",\n \"This one deserves its own section because it produces the least evidence.\",\n \"\",\n \"The broker refuses both directions on the first frame, answering in the framing\",\n \"the peer can decode and closing with `1008` and a reason naming both\",\n \"corrections. That covers the common case. It cannot cover a provider that\",\n \"connects and sends nothing, and it does not exist in brokers before 1.3.0, so\",\n \"the manual diagnosis below is still what you fall back to.\",\n \"\",\n \"`DirectTransport` speaks plain JSON-RPC; `MultiplexTransport` speaks\",\n \"`{ provider, payload }` envelopes. The broker decides which language to speak on\",\n \"a socket from the URL that socket connected to, not from what arrives on it.\",\n \"\",\n \"- Slot-scoped path `/provider/<name>`: the broker registers the slot from the\",\n \" URL at connect time and then writes plain frames. A multiplex provider on that\",\n \" path shows `connected: true` while silently discarding everything the broker\",\n \" sends, because it is not an envelope.\",\n \"- Multiplex path `/providers`: the broker learns slot names from envelopes only.\",\n \" A plain frame decodes to nothing and is dropped, so no slot is ever created.\",\n \"\",\n \"**How to confirm it in ten seconds.** Call\",\n '`provider_status({ name: \"<slot>\" })` while a client request is outstanding:',\n \"\",\n '- `connected: true`, `transport: \"ws\"`, `pendingCount` > 0 and never falling:',\n \" a multiplex provider is sitting on the slot-scoped path. This is the case.\",\n \"- the slot is absent from `providers_list` entirely while your socket is open:\",\n \" a direct provider is sitting on the multiplex path.\",\n \"\",\n \"`broker_diagnose` runs exactly these two checks for you.\",\n \"\",\n \"## The slot is wedged after a crash\",\n \"\",\n \"A slot is occupied while the incumbent socket is `readyState === OPEN`, and a\",\n \"socket killed without a close frame stays OPEN until the OS TCP keepalive\",\n \"expires, which is hours. The heartbeat is what bounds that: every provider\",\n \"socket is pinged every `providerHeartbeatIntervalMs` (default 30000), and one\",\n \"that misses a full interval is terminated and its slot freed. So the wedge\",\n \"lasts one interval, not a restart.\",\n \"\",\n \"If it lasts longer, check the three things that disable the recovery:\",\n \"\",\n \"- `providerHeartbeatIntervalMs: 0` turns the heartbeat off entirely. With no\",\n \" liveness evidence the broker refuses every takeover, by design.\",\n '- `providerTakeover: \"reject\"` never hands a live slot over, whatever the',\n \" heartbeat says.\",\n \"- The incumbent is answering pings but not serving. An RFC 6455 pong comes from\",\n \" the network stack, so a throttled or wedged JS thread still looks alive. The\",\n \" request timeout below is what catches that.\",\n \"\",\n \"The broker prints the reason it refused a takeover on every 1008, including\",\n \"which of these applies. Prevention is still cheaper: release explicitly on\",\n \"`pagehide` in a browser and on `SIGTERM` / `SIGINT` in a process.\",\n \"\",\n \"## Requests that never come back\",\n \"\",\n \"A pending entry is released by a matching response, by the provider\",\n \"disconnecting, by the caller's own connection closing, or by\",\n \"`providerRequestTimeoutMs` expiring (default 60000; `0` disables it). On expiry\",\n 'the caller gets `-32000 Provider \"<name>\" did not respond within <ms>ms`,',\n \"addressed to its own request id, and the broker logs the three usual causes.\",\n \"\",\n \"So a request that hangs *forever* now means either the timeout is disabled or\",\n \"the request never reached a provider at all, which is the transport/path\",\n \"mismatch above. A request that fails at the deadline means the provider is\",\n \"connected and not answering: the ordinary case is a throttled background browser\",\n \"tab. `pendingCount` in `provider_status` is the number of requests in flight,\",\n \"and one that only grows is the signal. Raise the timeout only if you host\",\n \"genuinely long-running tools.\",\n \"\",\n \"## Sessions outliving their clients\",\n \"\",\n \"Streamable HTTP and SSE sessions do not expire. A client that closes its tab\",\n \"without sending `DELETE /<slot>/mcp` leaves its session alive, and every\",\n \"notification the provider broadcasts is queued into it, without bound.\",\n \"\",\n \"The broker cannot tell a live session from an abandoned one, so no single\",\n \"reading proves a leak. `sessionCount` in `provider_status` growing monotonically\",\n \"across a run, and never falling when clients go away, is the signal. Note that\",\n \"`clientCount` counts raw WebSocket clients only: a perfectly healthy HTTP client\",\n \"shows as `clientCount: 0, sessionCount: 1`. Send the DELETE when a client is\",\n \"done; restart the broker if the count is already large.\",\n \"\",\n \"## Reading the console\",\n \"\",\n \"The broker prints one line per accepted WebSocket upgrade, naming the path, the\",\n \"role the router assigned (`dedicated-provider`, `multiplex-provider` or\",\n \"`client`) and the slot it landed on. A provider URL that came out as\",\n \"`role=client` is the mismatch, caught for free. In stdio mode every log goes to\",\n \"stderr, so look in the host's `mcp-server-<name>.log`, never on stdout.\",\n \"\",\n \"Do not read silence as success or as failure. Client sessions, routed frames and\",\n \"provider replies are not logged at all. `providers_list` and `broker_diagnose`\",\n \"are the ground truth for what is actually connected.\",\n].join(\"\\n\");\n\n// ---------------------------------------------------------------------------\n// Catalog\n// ---------------------------------------------------------------------------\n\n/**\n * Every guide page, in the order an agent should meet them: the index first,\n * then the two integration directions, then deployment, then the failure\n * reference.\n */\nexport const BROKER_GUIDES: readonly IBrokerGuide[] = [\n {\n topic: \"index\",\n uri: `${BROKER_GUIDE_URI_PREFIX}index`,\n title: \"Guide index\",\n summary: \"What the broker is, the transport pairing rule, and which page to read next.\",\n content: GUIDE_INDEX,\n },\n {\n topic: \"publish-provider\",\n uri: `${BROKER_GUIDE_URI_PREFIX}publish-provider`,\n title: \"Publish a provider\",\n summary: \"Put an MCP server into a slot: the transport/path pairing rule, the aggregate opt-in, the lifecycle, browser limits.\",\n content: GUIDE_PUBLISH_PROVIDER,\n },\n {\n topic: \"connect-client\",\n uri: `${BROKER_GUIDE_URI_PREFIX}connect-client`,\n title: \"Connect a client\",\n summary: \"Reach a slot: the four client transports, the reserved `_broker` and `_all` slots, origins, authorization, error codes.\",\n content: GUIDE_CONNECT_CLIENT,\n },\n {\n topic: \"host-config\",\n uri: `${BROKER_GUIDE_URI_PREFIX}host-config`,\n title: \"MCP host configuration\",\n summary: \"Wire Claude Desktop or another stdio host: why the bridge must target `_all`, the recipe, the one-broker-per-port rule.\",\n content: GUIDE_HOST_CONFIG,\n },\n {\n topic: \"deploy\",\n uri: `${BROKER_GUIDE_URI_PREFIX}deploy`,\n title: \"Deploy the broker\",\n summary: \"Embed as a library or run as a process: startup ordering, topologies, configuration, static files, TLS, shutdown.\",\n content: GUIDE_DEPLOY,\n },\n {\n topic: \"troubleshooting\",\n uri: `${BROKER_GUIDE_URI_PREFIX}troubleshooting`,\n title: \"Troubleshooting\",\n summary: \"Symptom to cause to fix, starting with the silent failures that produce no log line anywhere.\",\n content: GUIDE_TROUBLESHOOTING,\n },\n];\n\n/** Every topic id, in catalog order. */\nexport const BROKER_GUIDE_TOPICS: readonly BrokerGuideTopic[] = BROKER_GUIDES.map((g) => g.topic);\n\n/** MIME type every guide page is served with. */\nexport const BROKER_GUIDE_MIME_TYPE = \"text/markdown\";\n\n/** Builds the canonical resource URI for a topic. */\nexport function brokerGuideUri(topic: BrokerGuideTopic): string {\n return `${BROKER_GUIDE_URI_PREFIX}${topic}`;\n}\n\n/** Looks a guide page up by topic id. `undefined` when the topic is unknown. */\nexport function brokerGuide(topic: string): IBrokerGuide | undefined {\n return BROKER_GUIDES.find((g) => g.topic === topic);\n}\n\n/**\n * Extracts the topic from a `broker://guide/<topic>` URI, or `undefined` when\n * the URI is not a guide URI or names a topic that does not exist.\n *\n * Percent-encoding is decoded so `broker://guide/publish%2Dprovider` resolves,\n * and a decode failure is treated as \"not a guide URI\" rather than throwing:\n * the URI comes off the wire.\n */\nexport function brokerGuideTopicFromUri(uri: string): BrokerGuideTopic | undefined {\n if (!uri.startsWith(BROKER_GUIDE_URI_PREFIX)) return undefined;\n const raw = uri.slice(BROKER_GUIDE_URI_PREFIX.length);\n if (!raw || raw.includes(\"/\")) return undefined;\n let decoded: string;\n try {\n decoded = decodeURIComponent(raw);\n } catch {\n return undefined;\n }\n return brokerGuide(decoded)?.topic;\n}\n\n/**\n * The index rendered as data rather than prose: one entry per page, for a\n * client that would rather plan its reads than parse a Markdown table.\n */\nexport function brokerGuideIndex(): Array<{ topic: BrokerGuideTopic; uri: string; title: string; summary: string }> {\n return BROKER_GUIDES.map(({ topic, uri, title, summary }) => ({ topic, uri, title, summary }));\n}\n","import { McpAdapterBase, McpToolResults } from \"@cyanmycelium/mcp-core\";\nimport type { McpResourceContent, McpToolResult } from \"@cyanmycelium/mcp-core\";\nimport { BROKER_GUIDES, BROKER_GUIDE_MIME_TYPE, BROKER_GUIDE_TOPICS, brokerGuide, brokerGuideIndex, brokerGuideTopicFromUri } from \"../broker.guides\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Serves the broker's own integration documentation, so an agent that can\n * reach this slot never has to find a README.\n *\n * The prose lives in `broker.guides.ts` and is static, which is what makes it\n * safe to cache and to re-export to the markdown docs. What is NOT static is\n * the deployment it describes: port, scheme and URL paths are per-instance.\n * Rather than templating the guides, the adapter appends one short block of\n * effective values to every page, so a reader never has to guess whether the\n * defaults in the prose are the values in force here.\n */\nexport class BrokerGuideAdapter extends McpAdapterBase {\n constructor(private readonly _context: IBrokerContext) {\n super(\"broker\");\n }\n\n public async readResourceAsync(uri: string): Promise<McpResourceContent | undefined> {\n const topic = brokerGuideTopicFromUri(uri);\n if (!topic) return undefined;\n const guide = brokerGuide(topic);\n if (!guide) return undefined;\n return {\n uri: guide.uri,\n mimeType: BROKER_GUIDE_MIME_TYPE,\n text: this._render(guide.content),\n };\n }\n\n public async executeToolAsync(_uri: string, toolName: string, args: Record<string, unknown>): Promise<McpToolResult> {\n if (toolName !== \"broker_guide\") {\n return McpToolResults.error(`Unknown tool: ${toolName}`);\n }\n\n const raw = args[\"topic\"];\n if (raw === undefined || raw === null || raw === \"\") {\n // No topic is the discovery call: hand back the index page itself,\n // not a list of links, so a single call is already useful.\n const index = brokerGuide(\"index\");\n return McpToolResults.text(this._render(index ? index.content : BROKER_GUIDES.map((g) => `- ${g.topic}: ${g.summary}`).join(\"\\n\")));\n }\n if (typeof raw !== \"string\") {\n return McpToolResults.error(`Invalid argument \"topic\": expected a string, got ${typeof raw}. Valid topics: ${BROKER_GUIDE_TOPICS.join(\", \")}.`);\n }\n\n const guide = brokerGuide(raw.trim());\n if (!guide) {\n return McpToolResults.error(\n `Unknown guide topic \"${raw}\". Valid topics: ${BROKER_GUIDE_TOPICS.join(\", \")}. ` +\n `Call broker_guide with no argument for the index, which says which one to read.`\n );\n }\n return McpToolResults.text(this._render(guide.content));\n }\n\n /**\n * Machine-readable form of the index, for a caller that wants to plan its\n * reads without parsing a Markdown table. Exposed for the behavior's tool\n * schema documentation and for tests.\n */\n public index(): ReturnType<typeof brokerGuideIndex> {\n return brokerGuideIndex();\n }\n\n /**\n * Appends the effective configuration of THIS broker to a guide page.\n *\n * Everything in the block is read live from the context, so a deployment\n * that moved a path or enabled TLS does not silently contradict the prose\n * above it.\n */\n private _render(content: string): string {\n const c = this._context;\n const paths = c.paths;\n const scheme = c.tls ? \"https\" : \"http\";\n const wsScheme = c.tls ? \"wss\" : \"ws\";\n const authority = `${c.host && c.host !== \"0.0.0.0\" ? c.host : \"localhost\"}:${c.port}`;\n\n const block = [\n \"\",\n \"---\",\n \"\",\n \"## Effective configuration of this broker\",\n \"\",\n \"The prose above uses the default paths. These are the values actually in\",\n \"force on the instance you are talking to.\",\n \"\",\n \"| what | value |\",\n \"|---|---|\",\n `| broker | \\`${c.name}\\` ${c.version} |`,\n `| listening | \\`${scheme}://${authority}\\`${c.tls ? \" (TLS on: providers use `wss://`, browser origins are `https://`)\" : \"\"} |`,\n `| provider, dedicated socket | \\`${wsScheme}://${authority}${paths.provider}/<slot>\\` |`,\n `| provider, shared socket | \\`${wsScheme}://${authority}${paths.providers}\\` |`,\n `| client, Streamable HTTP | \\`${scheme}://${authority}/<slot>${paths.mcp}\\` |`,\n `| client, legacy SSE | \\`${scheme}://${authority}/<slot>${paths.sse}\\` + \\`${scheme}://${authority}/<slot>${paths.messages}\\` |`,\n `| client, raw WebSocket | \\`${wsScheme}://${authority}/<slot>\\` |`,\n \"\",\n \"Call `broker_diagnose()` for the live state and the problems this broker can\",\n \"detect about its own wiring.\",\n ].join(\"\\n\");\n\n return content + \"\\n\" + block + \"\\n\";\n }\n}\n","import { McpBehavior } from \"@cyanmycelium/mcp-core\";\nimport type { McpResource, McpResourceTemplate, McpTool } from \"@cyanmycelium/mcp-core\";\nimport { BrokerGuideAdapter } from \"../adapters/broker.adapter.guide\";\nimport { BROKER_GUIDES, BROKER_GUIDE_MIME_TYPE, BROKER_GUIDE_TOPICS, BROKER_GUIDE_URI_TEMPLATE } from \"../broker.guides\";\nimport {\n brokerBaselinePropertyDescription,\n brokerBaselineResourceDescription,\n brokerBaselineResourceName,\n brokerBaselineResourceTemplateDescription,\n brokerBaselineResourceTemplateName,\n brokerBaselineToolDescription,\n} from \"../broker.grammars\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Teaches an agent how to integrate with this broker, from inside the broker.\n *\n * Every page is exposed twice: as a resource (`broker://guide/<topic>`, plus\n * the `broker://guide/{topic}` template) and through the `broker_guide` tool,\n * because a fair number of MCP clients implement tools and ignore resources\n * entirely. Both return the same text.\n *\n * This is the answer to \"an agent asked to embed mcp-broker has to find and\n * read several READMEs across two packages\": it does not, it reads this.\n */\nexport class BrokerGuideBehavior extends McpBehavior {\n public static readonly NAMESPACE = \"broker_guide\";\n\n constructor(context: IBrokerContext) {\n super(new BrokerGuideAdapter(context), {\n namespace: BrokerGuideBehavior.NAMESPACE,\n });\n }\n\n protected override _buildResources(): McpResource[] {\n // Every page is listed individually rather than hidden behind the\n // template: a client that only reads `resources/list` must be able to\n // see that a troubleshooting page exists without guessing its name.\n return BROKER_GUIDES.map((guide) => ({\n uri: guide.uri,\n name: brokerBaselineResourceName(guide.uri),\n mimeType: BROKER_GUIDE_MIME_TYPE,\n description: brokerBaselineResourceDescription(guide.uri),\n }));\n }\n\n protected override _buildTemplate(): McpResourceTemplate[] {\n return [\n {\n uriTemplate: BROKER_GUIDE_URI_TEMPLATE,\n name: brokerBaselineResourceTemplateName(BROKER_GUIDE_URI_TEMPLATE),\n mimeType: BROKER_GUIDE_MIME_TYPE,\n description: brokerBaselineResourceTemplateDescription(BROKER_GUIDE_URI_TEMPLATE),\n },\n ];\n }\n\n protected override _buildTools(): McpTool[] {\n return [\n {\n name: \"broker_guide\",\n description: brokerBaselineToolDescription(\"broker_guide\"),\n inputSchema: {\n type: \"object\",\n properties: {\n topic: {\n type: \"string\",\n // Enumerated in the schema so a client cannot invent\n // a topic: the valid set is small and closed.\n enum: [...BROKER_GUIDE_TOPICS],\n description: brokerBaselinePropertyDescription(\"broker_guide\", \"topic\"),\n },\n },\n additionalProperties: false,\n },\n },\n ];\n }\n}\n","/**\n * The broker's reserved slot names, in one dependency-free module.\n *\n * They live here rather than next to the code that registers them because\n * three unrelated layers need them: `broker.server.ts` registers `_broker`,\n * `AggregateServer` owns `_all`, and the diagnostics engine has to tell a\n * reserved slot from a user slot without importing either. Importing the\n * registrars would close a module cycle; importing this does not.\n */\n\n/**\n * Reserved provider slot name under which the broker exposes itself as an MCP\n * server. Clients reach it via `<host>/_broker/mcp` (or any other client\n * transport).\n *\n * Prefixed with `_` to make it unambiguously a system slot, and to reduce the\n * chance of collision with user-supplied provider names.\n */\nexport const BROKER_PROVIDER_NAME = \"_broker\";\n\n/**\n * Reserved provider slot name under which the broker exposes the aggregate of\n * every opted-in provider. Mirrors `AggregateServer.SLOT`.\n */\nexport const BROKER_AGGREGATE_NAME = \"_all\";\n\n/** Every slot name the broker reserves for itself. */\nexport const BROKER_RESERVED_SLOTS: readonly string[] = [BROKER_PROVIDER_NAME, BROKER_AGGREGATE_NAME];\n\n/**\n * `true` when `name` is one of the broker's own slots rather than a slot a\n * provider may claim. A provider connecting to a reserved name is refused.\n */\nexport function isReservedBrokerSlot(name: string): boolean {\n return name === BROKER_PROVIDER_NAME || name === BROKER_AGGREGATE_NAME;\n}\n","/**\n * The broker's self-diagnosis: live state plus the problems the broker can\n * *prove* about its own wiring, each carrying the fix.\n *\n * The point is to do the correlation an integrator would otherwise have to do\n * by hand. `provider_status` already exposes the raw counters, and the field\n * evidence is that `pendingCount` is what finally located a transport/path\n * mismatch. That inference is mechanical, so the broker should make it instead\n * of making a caller notice a number.\n *\n * Two rules govern what lands in {@link IBrokerDiagnosisProblem}:\n *\n * 1. **Evidence or nothing.** A problem is reported only when the state\n * actually observed implies it. A check whose input is not reachable on this\n * host is reported as skipped (see {@link IBrokerDiagnosisSkippedCheck}),\n * never guessed at.\n * 2. **Every problem ends in an action.** `fix` must be executable by a reader\n * that has read nothing else, so it names paths, slots and settings in full\n * rather than pointing at a document.\n *\n * The engine is a pure function of {@link IBrokerContext}, so it is testable\n * without a socket and reusable by anything holding a context.\n */\n\nimport type { IBrokerContext, IBrokerProviderInfo } from \"./broker.context\";\nimport { BROKER_AGGREGATE_NAME, BROKER_PROVIDER_NAME, isReservedBrokerSlot } from \"./broker.slots\";\n\n// ---------------------------------------------------------------------------\n// Result shapes\n// ---------------------------------------------------------------------------\n\n/**\n * How much a problem matters.\n *\n * - `error`: something is broken right now and a caller is being hurt by it.\n * - `warning`: a configuration that will break under a foreseeable condition.\n * - `info`: worth knowing, nothing is wrong.\n */\nexport type BrokerDiagnosisSeverity = \"error\" | \"warning\" | \"info\";\n\n/** Stable identifier of a diagnostic rule. Safe to branch on programmatically. */\nexport type BrokerDiagnosisRuleId =\n | \"broker-not-started\"\n | \"transport-path-mismatch\"\n | \"provider-not-responding\"\n | \"upstream-not-responding\"\n | \"sessions-without-clients\"\n | \"no-providers\"\n | \"slot-never-connected\"\n | \"aggregate-disabled\"\n | \"aggregate-empty\"\n | \"aggregate-missing-live-slots\"\n | \"stdio-bridge-target-unreachable\"\n | \"self-served-page-blocked\";\n\n/** One detected problem: what is wrong, what proves it, and what to do. */\nexport interface IBrokerDiagnosisProblem {\n /** Stable rule id. */\n id: BrokerDiagnosisRuleId;\n\n severity: BrokerDiagnosisSeverity;\n\n /** Slot the problem is about, when it is about one. */\n slot?: string;\n\n /** What a caller of this broker actually observes. */\n symptom: string;\n\n /** The state that proves the symptom, verbatim from the live snapshot. */\n evidence: Record<string, unknown>;\n\n /** A concrete action, executable without reading anything else. */\n fix: string;\n}\n\n/** A rule that could not run, and why. Never a silent omission. */\nexport interface IBrokerDiagnosisSkippedCheck {\n id: BrokerDiagnosisRuleId;\n reason: string;\n}\n\n/** One slot as the diagnosis sees it: the live counters plus its role. */\nexport interface IBrokerDiagnosisSlot extends IBrokerProviderInfo {\n /** `true` for `_broker` and `_all`, which no provider may claim. */\n reserved: boolean;\n\n /** `true` when this slot currently contributes to `_all`. `undefined` when unknown. */\n aggregated?: boolean;\n}\n\n/** The whole answer of `broker_diagnose`. */\nexport interface IBrokerDiagnosis {\n /** Identity and listening configuration, enough to build a URL. */\n broker: {\n name: string;\n version: string;\n startedAt: string | null;\n uptimeSeconds: number;\n listening: string;\n tls: boolean;\n paths: IBrokerContext[\"paths\"];\n endpoints: {\n provider: string;\n providers: string;\n client: string;\n streamableHttp: string;\n };\n };\n\n /** Slots in scope: every slot, or just the one the caller asked about. */\n slots: IBrokerDiagnosisSlot[];\n\n /** Counts, so a caller does not have to reduce the array itself. */\n summary: {\n slots: number;\n connected: number;\n providerSlots: number;\n connectedProviderSlots: number;\n pendingRequests: number;\n clients: number;\n sessions: number;\n };\n\n /** Membership of `_all`, when the host can report it. */\n aggregate?: { enabled: boolean; providers: readonly string[] };\n\n /** Detected problems, most severe first. Empty means nothing was provable. */\n problems: IBrokerDiagnosisProblem[];\n\n /** Rules that could not run here. */\n checksSkipped: IBrokerDiagnosisSkippedCheck[];\n\n /**\n * Statements that are true and worth acting on but are not faults, e.g. a\n * configuration that only breaks a topology this broker cannot see.\n */\n notes: string[];\n\n /** Where to read the rule behind a problem. */\n seeAlso: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Reusable prose\n// ---------------------------------------------------------------------------\n\n/**\n * The transport/path pairing rule, as a single fix string.\n *\n * Repeated in full inside the `fix` of every rule that can be caused by it,\n * rather than referenced: a caller acting on one problem entry must not have\n * to go read a second one.\n */\nconst PAIRING_FIX =\n \"A provider's transport and its URL path are a matched pair. \" +\n 'DirectTransport speaks plain JSON-RPC and belongs on the slot-scoped path \"<providerPath>/<slot>\". ' +\n 'MultiplexTransport speaks { provider, payload } envelopes and belongs on the shared path \"<providersPath>\" with no name appended. ' +\n 'Note that \"<providersPath>/<slot>\" is neither: the router accepts it as an MCP CLIENT on a slot of that name, so nothing ever answers it. ' +\n \"Move the provider to the path that matches its transport, or swap the transport to match the path it is on.\";\n\nconst SEE_PUBLISH = \"broker://guide/publish-provider\";\nconst SEE_TROUBLESHOOTING = \"broker://guide/troubleshooting\";\nconst SEE_HOST_CONFIG = \"broker://guide/host-config\";\nconst SEE_CONNECT = \"broker://guide/connect-client\";\n\nconst SEVERITY_ORDER: Record<BrokerDiagnosisSeverity, number> = { error: 0, warning: 1, info: 2 };\n\n/**\n * Number of long-lived sessions on one slot above which the count is worth\n * mentioning.\n *\n * One or two sessions is the normal steady state of a slot serving Streamable\n * HTTP or SSE clients, so reporting those would drown the real signal. The\n * leak this catches is monotonic accumulation, and three concurrent sessions\n * on a single slot is already unusual for a hand-driven integration.\n */\nconst SESSION_ACCUMULATION_THRESHOLD = 3;\n\n// ---------------------------------------------------------------------------\n// Engine\n// ---------------------------------------------------------------------------\n\n/**\n * Runs every rule that has the evidence to run, against a live broker context.\n *\n * @param context Read-only view of the broker.\n * @param slot Narrows the report to one slot. Problems that are not about a\n * slot (no providers at all, a blocked self-served page) are\n * dropped in that mode, because they are not answers to the\n * question that was asked.\n * @returns The full diagnosis. `undefined` only when `slot` names a slot the\n * broker has never heard of, which the caller should report as an\n * error naming `providers_list`.\n */\nexport function diagnoseBroker(context: IBrokerContext, slot?: string): IBrokerDiagnosis | undefined {\n if (slot !== undefined && !context.getProviderInfo(slot)) return undefined;\n\n const all = context.getProvidersInfo();\n const aggregate = context.getAggregateInfo?.();\n const security = context.getSecurityInfo?.();\n const bridgeTarget = context.getStdioBridgeTarget?.();\n\n const aggregateMembers = aggregate ? new Set(aggregate.providers) : null;\n const slots: IBrokerDiagnosisSlot[] = all.map((info) => ({\n ...info,\n reserved: isReservedBrokerSlot(info.name),\n ...(aggregateMembers ? { aggregated: aggregateMembers.has(info.name) } : {}),\n }));\n\n const problems: IBrokerDiagnosisProblem[] = [];\n const checksSkipped: IBrokerDiagnosisSkippedCheck[] = [];\n const paths = context.paths;\n const scheme = context.tls ? \"https\" : \"http\";\n const wsScheme = context.tls ? \"wss\" : \"ws\";\n const authority = `${context.host && context.host !== \"0.0.0.0\" ? context.host : \"localhost\"}:${context.port}`;\n const pairingFix = PAIRING_FIX.replace(/<providerPath>/g, paths.provider).replace(/<providersPath>/g, paths.providers);\n\n // -- Rule: the broker never finished starting --------------------------\n if (!context.startedAt) {\n problems.push({\n id: \"broker-not-started\",\n severity: \"error\",\n symptom: \"The broker reports no start time, so it is not listening and nothing can reach it.\",\n evidence: { startedAt: null, uptimeSeconds: context.uptimeSeconds },\n fix: \"Call start() on the tunnel (or launch the CLI) and wait for it to resolve before connecting anything. If start() already ran, it rejected: a listen failure on the configured port is the usual cause, so check that nothing else holds it.\",\n });\n }\n\n // -- Per-slot rules ----------------------------------------------------\n const scoped = slot === undefined ? slots : slots.filter((s) => s.name === slot);\n\n for (const s of scoped) {\n // A slot with requests in flight and a live WebSocket provider is the\n // signature of the mismatch: the slot-scoped path registers from the\n // URL before any frame exists, so an envelope-speaking provider is\n // reported connected while it discards every plain frame the broker\n // writes. `pendingCount` is the only externally visible trace.\n if (s.connected && s.transport === \"ws\" && s.pendingCount > 0) {\n problems.push({\n id: \"transport-path-mismatch\",\n severity: \"error\",\n slot: s.name,\n symptom: `Slot \"${s.name}\" has ${s.pendingCount} request(s) in flight and a WebSocket provider that reports itself connected, yet nothing is coming back. Clients on this slot hang on initialize with no error.`,\n evidence: { transport: s.transport, connected: s.connected, pendingCount: s.pendingCount, clientCount: s.clientCount, sessionCount: s.sessionCount },\n fix:\n `Most likely a MultiplexTransport connected to \"${paths.provider}/${s.name}\". ` +\n pairingFix +\n ` If the provider really is a DirectTransport on \"${paths.provider}/${s.name}\", then it received the request and did not answer: check that it is not a backgrounded browser tab, and that its MCP message handler was installed before the socket opened.`,\n });\n } else if (s.connected && s.transport === \"ws-multiplex\" && s.pendingCount > 0) {\n problems.push({\n id: \"provider-not-responding\",\n severity: \"warning\",\n slot: s.name,\n symptom: `Slot \"${s.name}\" has ${s.pendingCount} request(s) in flight on a multiplexed provider socket and no reply yet.`,\n evidence: { transport: s.transport, pendingCount: s.pendingCount, clientCount: s.clientCount, sessionCount: s.sessionCount },\n fix:\n \"The framing is right (a multiplex socket only registers a slot from a valid envelope), so the provider received the request and has not answered. \" +\n \"Check that the provider's page or process is not throttled, and that it replies with the SAME id it received, wrapped in an envelope for this slot. \" +\n \"Each entry is released by a matching response, by the provider disconnecting, by the caller closing, or by providerRequestTimeoutMs expiring (default 60000ms), \" +\n \"which fails the caller with a named error rather than leaving it to hang. If this count is not falling and no timeout error ever arrives, providerRequestTimeoutMs is set to 0.\",\n });\n } else if (s.connected && s.transport === \"stdio\" && s.pendingCount > 0) {\n // Deliberately NOT extended to `loopback`. The diagnosis is itself\n // an in-flight request on whichever loopback slot is serving it\n // (`_broker` directly, plus `_all` when it is reached through the\n // aggregate), so a loopback rule would fire on every single call\n // and be wrong every time.\n problems.push({\n id: \"upstream-not-responding\",\n severity: \"warning\",\n slot: s.name,\n symptom: `Slot \"${s.name}\" is served by a configured upstream (a child process or a remote URL) with ${s.pendingCount} request(s) outstanding and no reply yet.`,\n evidence: { transport: s.transport, pendingCount: s.pendingCount },\n fix:\n \"A brief spike is normal. A count that only grows means the upstream is not answering: for a child process check its stderr, for a remote URL check that the server is up and returning JSON-RPC rather than an HTML error page with status 200. \" +\n \"providerRequestTimeoutMs (default 60000ms) applies to configured upstreams too, so the caller gets a named error rather than hanging; if none ever arrives, that setting is 0.\",\n });\n }\n\n // Long-lived sessions are torn down by their own transport, and a\n // Streamable HTTP session that is never DELETEd outlives the client\n // that opened it. The broker genuinely cannot tell a live session from\n // an abandoned one, and a healthy HTTP client is `clientCount: 0,\n // sessionCount: 1` (clientCount counts raw WebSocket clients only), so\n // this is reported as information above a threshold rather than\n // asserted as a fault. Below the threshold the number carries no\n // signal at all and reporting it would be noise.\n if (s.sessionCount >= SESSION_ACCUMULATION_THRESHOLD) {\n problems.push({\n id: \"sessions-without-clients\",\n severity: \"info\",\n slot: s.name,\n symptom:\n `Slot \"${s.name}\" holds ${s.sessionCount} long-lived session(s) (${s.clientCount} raw WebSocket client(s) besides). ` +\n \"Sessions on this broker never expire, and it cannot tell a live one from one whose client walked away.\",\n evidence: { clientCount: s.clientCount, sessionCount: s.sessionCount },\n fix:\n `A Streamable HTTP or SSE client that closes without sending DELETE ${scheme}://${authority}/${s.name}${paths.mcp} leaves its session alive, and every notification the provider broadcasts is queued into it, without bound. ` +\n \"Send that DELETE when a client is done. If this count only ever grows across a session, that is the leak, and a broker restart is the only way to reclaim it today.\",\n });\n }\n\n // A slot exists as soon as anything mentions it, so an empty one is a\n // client waiting for a provider that never arrived. Reserved slots are\n // excluded: no provider may claim them, so the fix would be wrong.\n if (!s.reserved && !s.connected && s.transport === \"none\") {\n problems.push({\n id: \"slot-never-connected\",\n severity: s.clientCount + s.sessionCount > 0 ? \"error\" : \"info\",\n slot: s.name,\n symptom: `Slot \"${s.name}\" exists but no provider is serving it. Requests to it are answered with -32000 \"Provider \\\\\"${s.name}\\\\\" not connected\".`,\n evidence: { transport: s.transport, connected: s.connected, clientCount: s.clientCount, sessionCount: s.sessionCount },\n fix:\n `Slots are created lazily by whoever mentions them first, so this name may simply be a typo on the client side. ` +\n `If a provider is meant to serve it, connect it to ${wsScheme}://${authority}${paths.provider}/${s.name} with a DirectTransport, ` +\n `or to ${wsScheme}://${authority}${paths.providers} with a MultiplexTransport created for the name \"${s.name}\". ` +\n (s.clientCount + s.sessionCount > 0\n ? `${s.clientCount + s.sessionCount} caller(s) are attached and getting nothing.`\n : \"No caller is attached, so nothing is being hurt yet.\"),\n });\n }\n }\n\n // -- Broker-wide rules -------------------------------------------------\n const providerSlots = slots.filter((s) => !s.reserved);\n const connectedProviderSlots = providerSlots.filter((s) => s.connected);\n\n if (slot === undefined && connectedProviderSlots.length === 0) {\n problems.push({\n id: \"no-providers\",\n severity: \"warning\",\n symptom: \"No provider is connected. Only the reserved slots answer, so every other slot returns -32000 not-connected.\",\n evidence: { knownSlots: slots.map((s) => s.name), providerSlots: providerSlots.length },\n fix:\n `Connect an MCP server to ${wsScheme}://${authority}${paths.provider}/<slot> with a DirectTransport (plain JSON-RPC frames), ` +\n `or to ${wsScheme}://${authority}${paths.providers} with a MultiplexTransport (envelope frames, slot named per envelope). ` +\n `Do not use ${wsScheme}://${authority}${paths.providers}/<slot>: that is neither endpoint and is accepted as a client. ` +\n `Configured upstreams are another route: add a stdioUpstreams, mcpServers or mcpbBundles entry to the config file.`,\n });\n }\n\n // -- Aggregate rules ---------------------------------------------------\n if (!aggregate) {\n checksSkipped.push({\n id: \"aggregate-empty\",\n reason: \"This broker context does not implement getAggregateInfo(), so `_all` membership cannot be read. Call tools/list on the _all slot to see it directly.\",\n });\n } else if (!aggregate.enabled) {\n problems.push({\n id: \"aggregate-disabled\",\n severity: \"info\",\n slot: BROKER_AGGREGATE_NAME,\n symptom: `The reserved \"${BROKER_AGGREGATE_NAME}\" aggregate slot is disabled on this broker.`,\n evidence: { enabled: false },\n fix: `Nothing will union the providers, and a stdio MCP host has no always-available target except \"${BROKER_PROVIDER_NAME}\". Leave enableAggregateProvider unset (or set it to true) when building the tunnel if you want \"${BROKER_AGGREGATE_NAME}\" back.`,\n });\n } else if (slot === undefined) {\n const aggregatedProviders = aggregate.providers.filter((name) => !isReservedBrokerSlot(name));\n const liveOutside = connectedProviderSlots.filter((s) => !aggregate.providers.includes(s.name));\n\n if (aggregatedProviders.length === 0) {\n problems.push({\n id: \"aggregate-empty\",\n severity: connectedProviderSlots.length > 0 ? \"warning\" : \"info\",\n slot: BROKER_AGGREGATE_NAME,\n symptom: `\"${BROKER_AGGREGATE_NAME}\" contains no provider beyond the broker's own introspection tools, so a client on it sees only the _broker-* tools.`,\n evidence: { aggregateProviders: aggregate.providers, connectedProviderSlots: connectedProviderSlots.map((s) => s.name) },\n fix: aggregateOptInFix(),\n });\n } else if (liveOutside.length > 0) {\n problems.push({\n id: \"aggregate-missing-live-slots\",\n severity: \"info\",\n slot: BROKER_AGGREGATE_NAME,\n symptom: `${liveOutside.length} connected slot(s) are not in \"${BROKER_AGGREGATE_NAME}\": ${liveOutside.map((s) => s.name).join(\", \")}. Clients on the aggregate cannot see their tools.`,\n evidence: { missing: liveOutside.map((s) => ({ name: s.name, transport: s.transport })), aggregateProviders: aggregate.providers },\n fix: aggregateOptInFix(),\n });\n }\n }\n\n // -- stdio bridge target ------------------------------------------------\n if (bridgeTarget === undefined) {\n checksSkipped.push({\n id: \"stdio-bridge-target-unreachable\",\n reason: \"This broker context does not implement getStdioBridgeTarget(), so the stdio bridge's target cannot be read. Check MCP_BROKER_STDIO_PROVIDER by hand.\",\n });\n } else if (bridgeTarget !== null && !isReservedBrokerSlot(bridgeTarget)) {\n const target = slots.find((s) => s.name === bridgeTarget);\n problems.push({\n id: \"stdio-bridge-target-unreachable\",\n severity: target?.connected ? \"warning\" : \"error\",\n slot: bridgeTarget,\n symptom:\n `The stdio bridge is pinned to \"${bridgeTarget}\", which is not a reserved slot. ` +\n (target?.connected\n ? \"It happens to be connected right now, but it will not be at the next host start.\"\n : `It is not connected, so the MCP host's very first initialize is answered with -32000 not-connected and the host will treat this server as dead with no retry.`),\n evidence: { stdioBridgeTarget: bridgeTarget, targetConnected: target?.connected ?? false, targetTransport: target?.transport ?? \"none\" },\n fix:\n `Set MCP_BROKER_STDIO_PROVIDER (or stdioProvider in the config file) to \"${BROKER_AGGREGATE_NAME}\". ` +\n `An MCP host starts its servers before any provider can exist, so pinning a real slot fails every time. \"${BROKER_AGGREGATE_NAME}\" is registered before stdin is resumed, answers initialize itself, ` +\n `already aggregates \"${BROKER_PROVIDER_NAME}\", and pushes notifications/tools/list_changed when a provider joins, so a provider that appears mid-session shows up live. ` +\n `Use \"${BROKER_PROVIDER_NAME}\" instead if you only want the broker's introspection tools.`,\n });\n }\n\n // -- Origin check on a self-served page ---------------------------------\n if (!security) {\n checksSkipped.push({\n id: \"self-served-page-blocked\",\n reason: \"This broker context does not implement getSecurityInfo(), so the origin allow-list and the static mounts cannot be read. Check allowedOrigins by hand if a browser page is involved.\",\n });\n } else if (slot === undefined && security.staticMountPrefixes.length > 0 && !security.allowedOriginsConfigured) {\n problems.push({\n id: \"self-served-page-blocked\",\n severity: \"warning\",\n symptom: `This broker serves static files (${security.staticMountPrefixes.join(\", \")}) while no browser origin is allowed on the client endpoint, so a page it serves gets HTTP 403 invalid_origin the moment it calls /<slot>${paths.mcp}.`,\n evidence: { staticMountPrefixes: security.staticMountPrefixes, allowedOriginsConfigured: false },\n fix:\n `Serving a page does not exempt its origin. Add the page's exact origin to allowedOrigins, or set MCP_BROKER_ALLOWED_ORIGINS=${scheme}://${authority}. ` +\n `Match scheme, host and port exactly as the browser sends them (${context.tls ? \"this broker runs TLS, so the origin is https://\" : \"this broker is plain HTTP, so the origin is http://\"}). ` +\n \"Leave it unset if only non-browser clients (which send no Origin header) reach this broker.\",\n });\n }\n\n // -- Notes: true, actionable, but not a fault ---------------------------\n const notes: string[] = [];\n if (security?.providerAuthEnabled) {\n // Not a problem on its own: it is only fatal for browser-hosted\n // providers, and the broker cannot tell from here whether any provider\n // is a browser. Stated so a reader wiring one is not surprised.\n notes.push(\n \"Provider authentication is enabled. A browser-hosted provider can never satisfy it: the WebSocket constructor cannot set the X-Provider-Token or Authorization header, and neither shipped transport accepts a credential. \" +\n \"Such a provider is refused at the handshake with HTTP 401, which reaches the page as a bare error event with no status. Run without a provider secret, or authenticate in a reverse proxy.\"\n );\n }\n if (security?.clientAuthEnabled && bridgeTarget === BROKER_AGGREGATE_NAME) {\n notes.push(\n `OAuth is enabled and the stdio bridge is pinned to \"${BROKER_AGGREGATE_NAME}\". The bridge forwards frames with no principal attached, so once per-provider scopes or a policy denying an anonymous subject are configured, ` +\n \"the host's tool list silently empties: tools/list still answers 200 with an empty array. Grant the anonymous subject, or reach the broker over Streamable HTTP with a token instead of the bridge.\"\n );\n }\n\n problems.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);\n\n return {\n broker: {\n name: context.name,\n version: context.version,\n startedAt: context.startedAt?.toISOString() ?? null,\n uptimeSeconds: context.uptimeSeconds,\n listening: `${scheme}://${authority}`,\n tls: context.tls,\n paths,\n endpoints: {\n provider: `${wsScheme}://${authority}${paths.provider}/<slot>`,\n providers: `${wsScheme}://${authority}${paths.providers}`,\n client: `${wsScheme}://${authority}/<slot>`,\n streamableHttp: `${scheme}://${authority}/<slot>${paths.mcp}`,\n },\n },\n slots: scoped,\n summary: {\n slots: slots.length,\n connected: slots.filter((s) => s.connected).length,\n providerSlots: providerSlots.length,\n connectedProviderSlots: connectedProviderSlots.length,\n pendingRequests: slots.reduce((n, s) => n + s.pendingCount, 0),\n clients: slots.reduce((n, s) => n + s.clientCount, 0),\n sessions: slots.reduce((n, s) => n + s.sessionCount, 0),\n },\n ...(aggregate ? { aggregate: { enabled: aggregate.enabled, providers: aggregate.providers } } : {}),\n problems,\n checksSkipped,\n notes,\n seeAlso: [SEE_PUBLISH, SEE_CONNECT, SEE_HOST_CONFIG, SEE_TROUBLESHOOTING],\n };\n}\n\n/**\n * The aggregate opt-in, spelled out per provider kind. Shared by the two\n * aggregate rules so both give the same complete answer.\n */\nfunction aggregateOptInFix(): string {\n return (\n `Membership in \"${BROKER_AGGREGATE_NAME}\" is opt-in, per provider, and the opt-in differs per kind. ` +\n \"A WebSocket provider asks for it at registration: from the SDK, pass { aggregate: true } to the DirectTransport constructor or to MultiplexTransport.create; \" +\n 'driving the socket by hand on the slot-scoped path, send {\"type\":\"register\",\"aggregate\":true} as the very FIRST frame, before any MCP traffic. ' +\n \"Install your MCP message handler before either, because the broker sends initialize the moment it accepts the opt-in, and a provider that misses that handshake is dropped from the aggregate silently. \" +\n 'A stdioUpstreams config entry needs \"aggregate\": true written explicitly, while mcpServers and mcpbBundles entries are aggregated unless you write \"aggregate\": false. ' +\n `Never assume an opt-in took: a refused or unrecognized one produces no error. Verify with tools/list on the \"${BROKER_AGGREGATE_NAME}\" slot, where aggregated tools are named <slot>-<original>.`\n );\n}\n","import { McpAdapterBase, McpToolResults } from \"@cyanmycelium/mcp-core\";\nimport type { McpResourceContent, McpToolResult } from \"@cyanmycelium/mcp-core\";\nimport { diagnoseBroker } from \"../broker.diagnostics\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Runs the broker's self-diagnosis on demand.\n *\n * Deliberately tool-only, with no backing resource: the answer is a snapshot\n * of live state, and a resource read can be served from the behavior's content\n * cache, which would hand a caller a stale diagnosis at exactly the moment it\n * matters. `broker://providers` is the resource for state you want cached;\n * this is the one you want fresh.\n */\nexport class BrokerDiagnoseAdapter extends McpAdapterBase {\n constructor(private readonly _context: IBrokerContext) {\n super(\"broker\");\n }\n\n public async readResourceAsync(_uri: string): Promise<McpResourceContent | undefined> {\n return undefined;\n }\n\n public async executeToolAsync(_uri: string, toolName: string, args: Record<string, unknown>): Promise<McpToolResult> {\n if (toolName !== \"broker_diagnose\") {\n return McpToolResults.error(`Unknown tool: ${toolName}`);\n }\n\n const raw = args[\"slot\"];\n if (raw !== undefined && raw !== null && typeof raw !== \"string\") {\n return McpToolResults.error(`Invalid argument \"slot\": expected a string, got ${typeof raw}. Omit it to diagnose the whole broker.`);\n }\n\n const slot = typeof raw === \"string\" && raw !== \"\" ? raw : undefined;\n const diagnosis = diagnoseBroker(this._context, slot);\n if (!diagnosis) {\n return McpToolResults.error(\n `Unknown slot: \"${slot}\". The broker has never seen that name. ` +\n `Call providers_list to see the slots that exist, and note that slot names are case-sensitive. ` +\n `Omit the argument to diagnose the whole broker.`\n );\n }\n return McpToolResults.json(diagnosis);\n }\n}\n","import { McpBehavior } from \"@cyanmycelium/mcp-core\";\nimport type { McpTool } from \"@cyanmycelium/mcp-core\";\nimport { BrokerDiagnoseAdapter } from \"../adapters/broker.adapter.diagnose\";\nimport { brokerBaselinePropertyDescription, brokerBaselineToolDescription } from \"../broker.grammars\";\nimport type { IBrokerContext } from \"../broker.context\";\n\n/**\n * Exposes `broker_diagnose({ slot? })`: the live state of the broker plus the\n * problems it can prove about its own wiring, each with a symptom, the\n * evidence, and a fix.\n *\n * It exists because the raw counters were not enough. `provider_status`\n * already reported `pendingCount`, and that number is what located a\n * transport/path mismatch in the field, but only after someone thought to\n * correlate it with the transport kind. That correlation is mechanical, so\n * the broker does it here instead of leaving it to the reader.\n *\n * Tool-only, no resource: a diagnosis must never be served from a cache.\n */\nexport class BrokerDiagnoseBehavior extends McpBehavior {\n public static readonly NAMESPACE = \"broker_diagnostics\";\n\n constructor(context: IBrokerContext) {\n super(new BrokerDiagnoseAdapter(context), {\n namespace: BrokerDiagnoseBehavior.NAMESPACE,\n });\n }\n\n protected override _buildTools(): McpTool[] {\n return [\n {\n name: \"broker_diagnose\",\n description: brokerBaselineToolDescription(\"broker_diagnose\"),\n inputSchema: {\n type: \"object\",\n properties: {\n slot: {\n type: \"string\",\n description: brokerBaselinePropertyDescription(\"broker_diagnose\", \"slot\"),\n },\n },\n additionalProperties: false,\n },\n },\n ];\n }\n}\n","import { McpServerBuilder, LoopbackTransport } from \"@cyanmycelium/mcp-core\";\nimport type { GrammarResolverOptions, IMcpServer, IMessageTransport } from \"@cyanmycelium/mcp-core\";\nimport { BrokerInfoBehavior } from \"./behaviors/broker.behavior.info\";\nimport { BrokerProvidersBehavior } from \"./behaviors/broker.behavior.providers\";\nimport { BrokerGuideBehavior } from \"./behaviors/broker.behavior.guide\";\nimport { BrokerDiagnoseBehavior } from \"./behaviors/broker.behavior.diagnose\";\nimport { iterAvailableBrokerGrammars, iterBrokerGrammarsFrom } from \"./broker.grammars\";\nimport { BROKER_PROVIDER_NAME } from \"./broker.slots\";\nimport type { IBrokerContext } from \"./broker.context\";\n\n/**\n * Reserved provider slot name under which the broker exposes itself as an MCP\n * server. Clients reach it via `<host>/_broker/mcp` (or any other client transport).\n *\n * Defined in `broker.slots.ts`, which is where the reserved names live so the\n * diagnostics engine can classify a slot without importing this module (which\n * would close a cycle through the behaviors). Re-exported here so every\n * existing importer of `broker.server` keeps working unchanged.\n */\nexport { BROKER_PROVIDER_NAME };\n\n/**\n * Optional knobs passed to {@link startBrokerServer}. Lets the embedder\n * replace either resolver with custom logic without touching mcp-broker\n * internals.\n */\nexport interface IStartBrokerServerOptions {\n /**\n * Overrides for the built-in grammar resolver from `@cyanmycelium/mcp-core`.\n *\n * The broker installs sensible defaults: `localeSource` reads\n * `process.env.MCP_BROKER_LOCALE`, the `agents` map uses the mcp-core\n * defaults (`claude`, `gpt`, `mistral`, `copilot`, `default`), the\n * narrowing chain is BCP-47-style, and `fallbackKey` is `default:en`\n * so the baseline grammar always matches as last resort.\n *\n * Pass partial overrides here to inject a custom `localeSource` (e.g.\n * pull from an HTTP header proxied by your transport), enable the\n * `versionFrom` dimension, or extend the `agents` map with additional\n * LLM families. Anything you omit keeps the broker default.\n */\n grammarResolverOptions?: Partial<GrammarResolverOptions>;\n\n /**\n * Path to a user-supplied grammars directory whose `<userAgent>/<locale>.json`\n * files are registered **in addition to** the packaged grammars.\n *\n * Both packaged and local entries are registered raw against the server\n * via `withGrammar(brokerGrammarKey(ua, locale), grammar)`. The\n * candidate-chain resolution implemented by `McpServer.initialize` in\n * mcp-core@0.3.0 then walks the chain and merges the four layers\n * (behavior, adapter, static, store) for the first matching key ,\n * the old hand-rolled pre-merge cascade is no longer needed.\n *\n * When `undefined` (default), only the packaged grammars are loaded.\n */\n localGrammarsDir?: string;\n}\n\n/**\n * Constructs the broker's own MCP server and returns the running server plus\n * the loopback transport that must be registered against the {@link WsTunnel}\n * as the `_broker` provider slot.\n *\n * Four behaviors are registered, in the order an agent meets them:\n *\n * - {@link BrokerInfoBehavior}: `broker_info`, `broker://info`.\n * - {@link BrokerProvidersBehavior}: `providers_list`, `provider_status`,\n * `broker://providers`, `broker://providers/{name}`.\n * - {@link BrokerGuideBehavior}: `broker_guide`, `broker://guide/*`. The\n * broker's own integration documentation, so an agent wiring something to\n * this broker never has to go find a README.\n * - {@link BrokerDiagnoseBehavior}: `broker_diagnose`. Live state plus the\n * problems the broker can prove about its own wiring, each with a fix.\n *\n * Usage from {@link WsTunnel.start}:\n * ```ts\n * const { server, clientTransport } = await startBrokerServer(this, { ... });\n * this._registerLoopbackProvider(BROKER_PROVIDER_NAME, clientTransport);\n * ```\n *\n * @param context Read-only view of the broker's state.\n * @param options Optional resolver overrides.\n * @returns The running {@link IMcpServer} (call `.stop()` on shutdown) and the\n * loopback transport to attach to the tunnel.\n */\nexport async function startBrokerServer(\n context: IBrokerContext,\n options: IStartBrokerServerOptions = {}\n): Promise<{\n server: IMcpServer;\n clientTransport: IMessageTransport;\n}> {\n const [serverEnd, clientEnd] = LoopbackTransport.createPair();\n\n // Without an initializer, McpServerBuilder reports `version: \"0.0.0\"` in the\n // `initialize` handshake. Supply the real package version from the context.\n const builder = new McpServerBuilder()\n .withName(BROKER_PROVIDER_NAME)\n .withTransport(serverEnd)\n .withInitializer({\n initialize: () => ({\n protocolVersion: \"2024-11-05\",\n serverInfo: { name: BROKER_PROVIDER_NAME, version: context.version },\n }),\n })\n .register(new BrokerInfoBehavior(context), new BrokerProvidersBehavior(context), new BrokerGuideBehavior(context), new BrokerDiagnoseBehavior(context));\n\n // Register every `(userAgent, locale)` JSON found on disk as a raw\n // grammar layer. The candidate-chain resolution in\n // McpServer.initialize (mcp-core@0.3.0) walks the resolver's chain\n // and merges all matching layers: so partial user-agent files no\n // longer need to be pre-merged with the default-locale baseline at\n // boot. Local overrides come after packaged entries; identical keys\n // get overlaid via the registry's last-write-wins.\n for (const entry of iterAvailableBrokerGrammars()) {\n builder.withGrammar(entry.key, entry.grammar);\n }\n if (options.localGrammarsDir) {\n for (const entry of iterBrokerGrammarsFrom(options.localGrammarsDir)) {\n builder.withGrammar(entry.key, entry.grammar);\n }\n }\n\n // Wire the resolver via mcp-core's declarative helper. The broker\n // ships sensible defaults (locale from MCP_BROKER_LOCALE env, agents\n // from mcp-core's catalogue, BCP-47 narrowing, default:en fallback);\n // anything the host application sets via `grammarResolverOptions`\n // takes precedence.\n builder.withGrammarResolver({\n localeSource: () => process.env[\"MCP_BROKER_LOCALE\"],\n ...(options.grammarResolverOptions ?? {}),\n });\n\n // No reconnect policy → the McpServer does not attempt to reopen the loopback\n // when WsTunnel.stop() closes it. Clean shutdown.\n const server = builder.build();\n\n await server.start();\n\n return { server, clientTransport: clientEnd };\n}\n\n/** @deprecated Use {@link IStartBrokerServerOptions}. */\nexport type StartBrokerServerOptions = IStartBrokerServerOptions;\n","const WILDCARD = \"*\";\nconst RECURSIVE_WILDCARD = \"**\";\n\nfunction assertString(value: string, label: string): void {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${label}: a non-empty string is required.`);\n }\n}\n\nfunction splitAbsolutePath(value: string, label: string): readonly string[] {\n assertString(value, label);\n if (!value.startsWith(\"/\")) {\n throw new Error(`${label}: \"${value}\" must start with \"/\".`);\n }\n if (value === \"/\") return [];\n\n const withoutTrailingSlash = value.endsWith(\"/\") ? value.slice(0, -1) : value;\n const segments = withoutTrailingSlash.slice(1).split(\"/\");\n for (const segment of segments) {\n if (!segment) {\n throw new Error(`${label}: \"${value}\" contains an empty path segment.`);\n }\n if (segment === \".\" || segment === \"..\") {\n throw new Error(`${label}: \"${value}\" contains a forbidden \"${segment}\" segment.`);\n }\n }\n return segments;\n}\n\nfunction normalizedValue(segments: readonly string[]): string {\n return segments.length === 0 ? \"/\" : `/${segments.join(\"/\")}`;\n}\n\n/**\n * A normalized, case-sensitive hierarchical resource path.\n *\n * Parsing is deliberately independent from URLs and transports. A path is a\n * stable resource identity, not a network address.\n */\nexport class ResourcePath {\n readonly value: string;\n readonly segments: readonly string[];\n\n private constructor(segments: readonly string[]) {\n this.segments = Object.freeze([...segments]);\n this.value = normalizedValue(this.segments);\n }\n\n static parse(value: string): ResourcePath {\n const segments = splitAbsolutePath(value, \"resource path\");\n for (const segment of segments) {\n if (segment === WILDCARD || segment === RECURSIVE_WILDCARD) {\n throw new Error(`resource path: wildcards are not allowed in \"${value}\".`);\n }\n }\n return new ResourcePath(segments);\n }\n\n static tryParse(value: string): ResourcePath | undefined {\n try {\n return ResourcePath.parse(value);\n } catch {\n return undefined;\n }\n }\n\n toString(): string {\n return this.value;\n }\n}\n\n/**\n * A compiled resource expression supporting exact segments, `*` for one\n * segment, and a final `**` for zero or more trailing segments.\n */\nexport class ResourcePathPattern {\n readonly value: string;\n readonly segments: readonly string[];\n readonly specificity: number;\n\n private constructor(segments: readonly string[]) {\n this.segments = Object.freeze([...segments]);\n this.value = normalizedValue(this.segments);\n this.specificity = this.segments.reduce((score, segment) => {\n if (segment === RECURSIVE_WILDCARD) return score;\n if (segment === WILDCARD) return score + 1;\n return score + 4;\n }, this.segments.length);\n }\n\n static parse(value: string): ResourcePathPattern {\n const canonical = value === RECURSIVE_WILDCARD ? `/${RECURSIVE_WILDCARD}` : value;\n const segments = splitAbsolutePath(canonical, \"resource pattern\");\n let recursiveSeen = false;\n for (let index = 0; index < segments.length; index += 1) {\n const segment = segments[index];\n if (segment === RECURSIVE_WILDCARD) {\n if (index !== segments.length - 1) {\n throw new Error(`resource pattern: \"**\" must be the final segment in \"${value}\".`);\n }\n recursiveSeen = true;\n } else if (recursiveSeen) {\n throw new Error(`resource pattern: no segment may follow \"**\" in \"${value}\".`);\n } else if (segment !== WILDCARD && segment.includes(WILDCARD)) {\n throw new Error(`resource pattern: wildcards must occupy a complete segment in \"${value}\".`);\n }\n }\n return new ResourcePathPattern(segments);\n }\n\n matches(path: ResourcePath): boolean {\n const pattern = this.segments;\n const target = path.segments;\n for (let index = 0; index < pattern.length; index += 1) {\n const segment = pattern[index];\n if (segment === RECURSIVE_WILDCARD) return true;\n if (index >= target.length) return false;\n if (segment !== WILDCARD && segment !== target[index]) return false;\n }\n return target.length === pattern.length;\n }\n\n toString(): string {\n return this.value;\n }\n}\n","import { ResourcePath, ResourcePathPattern } from \"./resource.path\";\n\nexport interface IMcpOperation {\n readonly method?: string;\n readonly params?: unknown;\n}\n\nexport interface IClassifiedCapability {\n readonly capability: string;\n readonly tool?: string;\n}\n\nexport interface ICapabilityClassifier {\n classify(operation: IMcpOperation, resource: ResourcePath, provider?: string): IClassifiedCapability | undefined;\n}\n\ninterface IProviderMapping {\n readonly pattern: ResourcePathPattern;\n readonly tools: Readonly<Record<string, string>>;\n}\n\nconst STATIC_CAPABILITIES: Readonly<Record<string, string>> = {\n \"resources/list\": \"mcp.resources.read\",\n \"resources/read\": \"mcp.resources.read\",\n \"tools/list\": \"mcp.tools.list\",\n \"prompts/list\": \"mcp.prompts.read\",\n \"prompts/get\": \"mcp.prompts.read\",\n \"completion/complete\": \"mcp.completion.use\",\n \"notifications/resources/list_changed\": \"mcp.resources.read\",\n \"notifications/resources/updated\": \"mcp.resources.read\",\n \"notifications/tools/list_changed\": \"mcp.tools.list\",\n \"notifications/prompts/list_changed\": \"mcp.prompts.read\",\n};\n\nconst BROKER_READ_TOOLS = new Set([\"broker_info\", \"providers_list\", \"provider_status\"]);\n\nfunction toolNameFrom(params: unknown): string | undefined {\n if (typeof params !== \"object\" || params === null || Array.isArray(params)) return undefined;\n const name = (params as Readonly<Record<string, unknown>>)[\"name\"];\n return typeof name === \"string\" && name ? name : undefined;\n}\n\nexport function validateCapability(capability: string, label = \"capability\"): void {\n if (typeof capability !== \"string\" || (capability !== \"*\" && !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(capability))) {\n throw new Error(`authorization ${label}: \"${capability}\" is malformed.`);\n }\n}\n\n/**\n * Classifies MCP methods without deriving privilege from arbitrary tool names.\n * Provider-qualified mappings win over global mappings, then tools/call falls\n * back to `mcp.tools.call`.\n */\nexport class ConfiguredCapabilityClassifier implements ICapabilityClassifier {\n private readonly _globalTools: Readonly<Record<string, string>>;\n private readonly _providerMappings: readonly IProviderMapping[];\n\n constructor(toolCapabilities: Readonly<Record<string, string>> = {}, providerToolCapabilities: Readonly<Record<string, Readonly<Record<string, string>>>> = {}) {\n for (const [tool, capability] of Object.entries(toolCapabilities)) {\n if (!tool) throw new Error(\"authorization toolCapabilities: tool names must not be empty.\");\n validateCapability(capability, `toolCapabilities[\"${tool}\"]`);\n }\n this._globalTools = Object.freeze({ ...toolCapabilities });\n\n const mappings: IProviderMapping[] = [];\n for (const [patternValue, tools] of Object.entries(providerToolCapabilities)) {\n const pattern = ResourcePathPattern.parse(patternValue);\n for (const [tool, capability] of Object.entries(tools)) {\n if (!tool) throw new Error(`authorization providerToolCapabilities[\"${patternValue}\"]: tool names must not be empty.`);\n validateCapability(capability, `providerToolCapabilities[\"${patternValue}\"][\"${tool}\"]`);\n }\n mappings.push({ pattern, tools: Object.freeze({ ...tools }) });\n }\n mappings.sort((left, right) => right.pattern.specificity - left.pattern.specificity || left.pattern.value.localeCompare(right.pattern.value));\n this._providerMappings = Object.freeze(mappings);\n }\n\n classify(operation: IMcpOperation, resource: ResourcePath, provider?: string): IClassifiedCapability | undefined {\n const method = operation.method;\n if (!method) return undefined;\n\n if (provider === \"_broker\") {\n if (method === \"tools/list\" || method === \"resources/list\" || method === \"resources/read\") {\n return { capability: \"broker.providers.read\" };\n }\n if (method === \"tools/call\") {\n const tool = toolNameFrom(operation.params);\n if (tool && BROKER_READ_TOOLS.has(tool)) return { capability: \"broker.providers.read\", tool };\n }\n }\n\n if (method !== \"tools/call\") {\n const capability = STATIC_CAPABILITIES[method];\n return capability ? { capability } : undefined;\n }\n\n const tool = toolNameFrom(operation.params);\n if (!tool) return { capability: \"mcp.tools.call\" };\n for (const mapping of this._providerMappings) {\n if (mapping.pattern.matches(resource)) {\n const capability = mapping.tools[tool];\n if (capability) return { capability, tool };\n }\n }\n return { capability: this._globalTools[tool] ?? \"mcp.tools.call\", tool };\n }\n}\n\n/** @deprecated Use {@link IMcpOperation}. */\nexport type McpOperation = IMcpOperation;\n/** @deprecated Use {@link IClassifiedCapability}. */\nexport type ClassifiedCapability = IClassifiedCapability;\n/** @deprecated Use {@link ICapabilityClassifier}. */\nexport type CapabilityClassifier = ICapabilityClassifier;\n","import { validateCapability } from \"./capability.classifier\";\nimport type { IAuthorizationDecision, IAuthorizationRequest, IDenyPolicy, IPolicyAssignment, IPolicyEngine, IRoleDefinition } from \"./policy.types\";\nimport { ResourcePathPattern } from \"./resource.path\";\n\ninterface ICompiledAssignment {\n readonly id: string;\n readonly subject: string;\n readonly capabilities: ReadonlySet<string>;\n readonly resource: ResourcePathPattern;\n}\n\ninterface ICompiledDeny {\n readonly id: string;\n readonly subject: string;\n readonly capabilities: ReadonlySet<string>;\n readonly resource: ResourcePathPattern;\n}\n\nfunction validateName(value: string, label: string): void {\n if (typeof value !== \"string\" || !value || value.trim() !== value || value.includes(\"/\")) {\n throw new Error(`authorization ${label}: \"${value}\" is invalid.`);\n }\n}\n\nfunction validateSubject(subject: string, label: string): void {\n if (typeof subject !== \"string\" || !/^[A-Za-z][A-Za-z0-9_-]*:.+$/.test(subject)) {\n throw new Error(`authorization ${label}: subject \"${subject}\" must use a non-empty extensible prefix such as \"user:alice\".`);\n }\n}\n\nfunction validatePolicyId(id: string, label: string): void {\n if (typeof id !== \"string\" || !id || id.trim() !== id) {\n throw new Error(`authorization ${label}: policy ids must be non-empty and must not contain surrounding whitespace.`);\n }\n}\n\nfunction expandRoles(roles: Readonly<Record<string, IRoleDefinition>>): ReadonlyMap<string, ReadonlySet<string>> {\n const expanded = new Map<string, ReadonlySet<string>>();\n const visiting: string[] = [];\n\n for (const [name, role] of Object.entries(roles)) {\n validateName(name, \"role\");\n for (const key of Object.keys(role)) {\n if (key !== \"inherits\" && key !== \"capabilities\") {\n throw new Error(`authorization role \"${name}\": unsupported field \"${key}\"; roles contain capabilities, not resource paths.`);\n }\n }\n if (!Array.isArray(role.capabilities)) {\n throw new Error(`authorization role \"${name}\": capabilities must be an array.`);\n }\n if (role.inherits !== undefined && !Array.isArray(role.inherits)) {\n throw new Error(`authorization role \"${name}\": inherits must be an array.`);\n }\n for (const capability of role.capabilities) validateCapability(capability, `role \"${name}\" capability`);\n for (const inherited of role.inherits ?? []) {\n validateName(inherited, `role \"${name}\" inheritance`);\n if (!roles[inherited]) {\n throw new Error(`authorization role \"${name}\": inherited role \"${inherited}\" is not defined.`);\n }\n }\n }\n\n const visit = (name: string): ReadonlySet<string> => {\n const cached = expanded.get(name);\n if (cached) return cached;\n\n const cycleStart = visiting.indexOf(name);\n if (cycleStart >= 0) {\n const cycle = [...visiting.slice(cycleStart), name].join(\" -> \");\n throw new Error(`authorization roles: inheritance cycle detected: ${cycle}.`);\n }\n\n const role = roles[name];\n if (!role) throw new Error(`authorization roles: role \"${name}\" is not defined.`);\n visiting.push(name);\n const capabilities = new Set<string>();\n for (const inherited of role.inherits ?? []) {\n for (const capability of visit(inherited)) capabilities.add(capability);\n }\n for (const capability of role.capabilities) capabilities.add(capability);\n visiting.pop();\n const frozen = Object.freeze(capabilities);\n expanded.set(name, frozen);\n return frozen;\n };\n\n for (const name of Object.keys(roles)) visit(name);\n return expanded;\n}\n\nfunction indexBySubject<T extends { readonly subject: string }>(entries: readonly T[]): ReadonlyMap<string, readonly T[]> {\n const mutable = new Map<string, T[]>();\n for (const entry of entries) {\n const bucket = mutable.get(entry.subject);\n if (bucket) bucket.push(entry);\n else mutable.set(entry.subject, [entry]);\n }\n const result = new Map<string, readonly T[]>();\n for (const [subject, bucket] of mutable) result.set(subject, Object.freeze(bucket));\n return result;\n}\n\nfunction grants(capabilities: ReadonlySet<string>, requested: string): boolean {\n return capabilities.has(\"*\") || capabilities.has(requested);\n}\n\n/**\n * Immutable, indexed in-memory policy engine. Role inheritance and resource\n * expressions are fully compiled in the constructor.\n */\nexport class ConfigPolicyEngine implements IPolicyEngine {\n private readonly _assignmentsBySubject: ReadonlyMap<string, readonly ICompiledAssignment[]>;\n private readonly _deniesBySubject: ReadonlyMap<string, readonly ICompiledDeny[]>;\n\n constructor(roles: Readonly<Record<string, IRoleDefinition>>, assignments: readonly IPolicyAssignment[], denies: readonly IDenyPolicy[]) {\n const expandedRoles = expandRoles(roles);\n const policyIds = new Set<string>();\n\n const reserveId = (id: string, label: string): void => {\n validatePolicyId(id, label);\n if (policyIds.has(id)) throw new Error(`authorization policies: duplicate policy id \"${id}\".`);\n policyIds.add(id);\n };\n\n const compiledAssignments = assignments.map((assignment, index): ICompiledAssignment => {\n const id = assignment.id ?? `assignment:${index}`;\n reserveId(id, `assignment ${index}`);\n validateSubject(assignment.subject, `assignment \"${id}\"`);\n validateName(assignment.role, `assignment \"${id}\" role`);\n const capabilities = expandedRoles.get(assignment.role);\n if (!capabilities) {\n throw new Error(`authorization assignment \"${id}\": role \"${assignment.role}\" is not defined.`);\n }\n if (!assignment.resource) throw new Error(`authorization assignment \"${id}\": resource must not be empty.`);\n return {\n id,\n subject: assignment.subject,\n capabilities,\n resource: ResourcePathPattern.parse(assignment.resource),\n };\n });\n\n const compiledDenies = denies.map((deny, index): ICompiledDeny => {\n const id = deny.id ?? `deny:${index}`;\n reserveId(id, `deny ${index}`);\n validateSubject(deny.subject, `deny \"${id}\"`);\n if (deny.effect !== undefined && deny.effect !== \"deny\") {\n throw new Error(`authorization deny \"${id}\": effect must be \"deny\".`);\n }\n if (!Array.isArray(deny.capabilities) || deny.capabilities.length === 0) {\n throw new Error(`authorization deny \"${id}\": at least one capability is required.`);\n }\n const capabilities = new Set<string>();\n for (const capability of deny.capabilities) {\n validateCapability(capability, `deny \"${id}\" capability`);\n capabilities.add(capability);\n }\n if (!deny.resource) throw new Error(`authorization deny \"${id}\": resource must not be empty.`);\n return {\n id,\n subject: deny.subject,\n capabilities: Object.freeze(capabilities),\n resource: ResourcePathPattern.parse(deny.resource),\n };\n });\n\n this._assignmentsBySubject = indexBySubject(compiledAssignments);\n this._deniesBySubject = indexBySubject(compiledDenies);\n }\n\n authorize(request: IAuthorizationRequest): IAuthorizationDecision {\n if (!request.resource) return { allowed: false, reason: \"invalid-resource\" };\n try {\n validateCapability(request.capability, \"request capability\");\n } catch (error) {\n // Not a policy miss: the capability string itself is malformed, so no\n // grant could ever match it. Reporting this as \"no-matching-grant\"\n // pointed operators at their grants instead of at the mapping that\n // produced the bad value.\n const detail = error instanceof Error ? error.message : String(error);\n console.error(\n `[broker] authorization: capability \"${String(request.capability)}\" requested on resource \"${request.resource.value}\" is malformed, denying. ${detail} ` +\n `Capability names look like \"mcp.tools.call\" or \"broker.providers.read\": fix the authorization.toolCapabilities / providerToolCapabilities entry that produced this value, or the caller that passed it.`\n );\n return { allowed: false, reason: \"invalid-capability\" };\n }\n\n const matchingDenies = new Set<string>();\n for (const subject of request.subject.ids) {\n for (const deny of this._deniesBySubject.get(subject) ?? []) {\n if (deny.resource.matches(request.resource) && grants(deny.capabilities, request.capability)) {\n matchingDenies.add(deny.id);\n }\n }\n }\n if (matchingDenies.size > 0) {\n return {\n allowed: false,\n reason: \"explicit-deny\",\n matchedPolicies: Object.freeze([...matchingDenies].sort()),\n };\n }\n\n const matchingGrants = new Set<string>();\n for (const subject of request.subject.ids) {\n for (const assignment of this._assignmentsBySubject.get(subject) ?? []) {\n if (assignment.resource.matches(request.resource) && grants(assignment.capabilities, request.capability)) {\n matchingGrants.add(assignment.id);\n }\n }\n }\n if (matchingGrants.size > 0) {\n return {\n allowed: true,\n reason: \"role-grant\",\n matchedPolicies: Object.freeze([...matchingGrants].sort()),\n };\n }\n return { allowed: false, reason: \"no-matching-grant\" };\n }\n}\n","import type { IAuthorizationSubject, ISubjectMappingConfig } from \"./policy.types\";\n\nexport interface ISubjectMapper {\n map(claims: Readonly<Record<string, unknown>>): IAuthorizationSubject;\n}\n\nexport class SubjectMappingError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SubjectMappingError\";\n }\n}\n\ninterface IClaimRule {\n readonly prefix: string;\n readonly claim: string;\n}\n\nfunction claimAt(claims: Readonly<Record<string, unknown>>, claimName: string): unknown {\n const parts = claimName.split(\".\");\n let current: unknown = claims;\n for (const part of parts) {\n if (!part || typeof current !== \"object\" || current === null || Array.isArray(current)) return undefined;\n current = (current as Readonly<Record<string, unknown>>)[part];\n }\n return current;\n}\n\nfunction valuesOf(value: unknown, claimName: string): readonly string[] {\n if (value === undefined || value === null) return [];\n if (typeof value === \"string\") return value ? [value] : [];\n if (Array.isArray(value) && value.every((entry) => typeof entry === \"string\")) {\n return value.filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n }\n throw new SubjectMappingError(`JWT subject claim \"${claimName}\" must be a string or an array of strings.`);\n}\n\nfunction validateClaimName(value: string, label: string): void {\n if (!value || value.split(\".\").some((part) => !part)) {\n throw new Error(`authorization subject mapping: ${label} contains an invalid claim name.`);\n }\n}\n\n/** Maps validated JWT claims to canonical, deduplicated authorization subjects. */\nexport class JwtSubjectMapper implements ISubjectMapper {\n private readonly _rules: readonly IClaimRule[];\n\n constructor(config: ISubjectMappingConfig = {}) {\n const userClaim = config.userClaim ?? \"sub\";\n const groupClaims = config.groupClaims ?? [\"groups\", \"roles\"];\n const clientClaim = config.clientClaim ?? \"client_id\";\n const serviceClaims = config.serviceClaims ?? [];\n\n if (!Array.isArray(groupClaims)) throw new Error(\"authorization subject mapping: groupClaims must be an array.\");\n if (!Array.isArray(serviceClaims)) throw new Error(\"authorization subject mapping: serviceClaims must be an array.\");\n validateClaimName(userClaim, \"userClaim\");\n validateClaimName(clientClaim, \"clientClaim\");\n for (const claim of groupClaims) validateClaimName(claim, \"groupClaims\");\n for (const claim of serviceClaims) validateClaimName(claim, \"serviceClaims\");\n\n this._rules = Object.freeze([\n { prefix: \"user\", claim: userClaim },\n ...groupClaims.map((claim) => ({ prefix: \"group\", claim })),\n { prefix: \"client\", claim: clientClaim },\n ...serviceClaims.map((claim) => ({ prefix: \"service\", claim })),\n ]);\n }\n\n map(claims: Readonly<Record<string, unknown>>): IAuthorizationSubject {\n const ids = new Set<string>();\n for (const rule of this._rules) {\n for (const value of valuesOf(claimAt(claims, rule.claim), rule.claim)) {\n ids.add(`${rule.prefix}:${value}`);\n }\n }\n return { ids: Object.freeze([...ids]), claims };\n }\n}\n\n/** @deprecated Use {@link ISubjectMapper}. */\nexport type SubjectMapper = ISubjectMapper;\n","import { ResourcePath } from \"./resource.path\";\n\nexport interface ISlotResourceResolver {\n resolve(slot: string): ResourcePath | undefined;\n}\n\nconst RESERVED_RESOURCES: Readonly<Record<string, string>> = {\n _broker: \"/_system/broker\",\n _all: \"/_system/all\",\n};\n\nfunction isReservedNamespace(resource: ResourcePath): boolean {\n return resource.value === \"/_system\" || resource.value.startsWith(\"/_system/\");\n}\n\n/** Default resolver with optional explicit technical-slot mappings. */\nexport class DefaultSlotResourceResolver implements ISlotResourceResolver {\n private readonly _explicit = new Map<string, ResourcePath>();\n\n constructor(slotResources: Readonly<Record<string, string>> = {}) {\n for (const [slot, configuredPath] of Object.entries(slotResources)) {\n if (!slot) throw new Error(\"authorization slotResources: slot names must not be empty.\");\n const resource = ResourcePath.parse(configuredPath);\n const reserved = RESERVED_RESOURCES[slot];\n if (isReservedNamespace(resource) && reserved !== resource.value) {\n throw new Error(`authorization slotResources: slot \"${slot}\" may not use reserved resource \"${resource.value}\".`);\n }\n if (reserved && resource.value !== reserved) {\n throw new Error(`authorization slotResources: reserved slot \"${slot}\" must resolve to \"${reserved}\".`);\n }\n this._explicit.set(slot, resource);\n }\n }\n\n resolve(slot: string): ResourcePath | undefined {\n const explicit = this._explicit.get(slot);\n if (explicit) return explicit;\n\n const reserved = RESERVED_RESOURCES[slot];\n if (reserved) return ResourcePath.parse(reserved);\n if (!slot) return undefined;\n\n const candidate = slot.startsWith(\"/\") ? slot : `/${slot}`;\n const resource = ResourcePath.tryParse(candidate);\n return resource && !isReservedNamespace(resource) ? resource : undefined;\n }\n}\n\n/** @deprecated Use {@link ISlotResourceResolver}. */\nexport type SlotResourceResolver = ISlotResourceResolver;\n","import { ConfiguredCapabilityClassifier, type ICapabilityClassifier } from \"./capability.classifier\";\nimport { ConfigPolicyEngine } from \"./policy.engine\";\nimport type { IAuthorizationAuditConfig, IAuthorizationPolicyConfig, IPolicyEngine } from \"./policy.types\";\nimport { DefaultSlotResourceResolver, type ISlotResourceResolver } from \"./slot.resource\";\nimport { JwtSubjectMapper, type ISubjectMapper } from \"./subject.mapper\";\n\nexport interface IPolicyAuthorization {\n readonly engine: IPolicyEngine;\n readonly subjectMapper: ISubjectMapper;\n readonly slotResourceResolver: ISlotResourceResolver;\n readonly capabilityClassifier: ICapabilityClassifier;\n readonly audit: Readonly<Required<IAuthorizationAuditConfig>>;\n}\n\nexport function hasAuthorizationPolicies(config: IAuthorizationPolicyConfig): boolean {\n return Object.keys(config.roles ?? {}).length > 0 || (config.assignments?.length ?? 0) > 0 || (config.denies?.length ?? 0) > 0;\n}\n\n/** Compiles and validates the complete hierarchical authorization runtime. */\nexport function compileAuthorizationPolicy(config: IAuthorizationPolicyConfig): IPolicyAuthorization {\n if (config.audit?.logAllowed !== undefined && typeof config.audit.logAllowed !== \"boolean\") {\n throw new Error(\"authorization audit.logAllowed must be a boolean.\");\n }\n const engine = new ConfigPolicyEngine(config.roles ?? {}, config.assignments ?? [], config.denies ?? []);\n const subjectMapper = new JwtSubjectMapper(config.subjectMapping);\n const slotResourceResolver = new DefaultSlotResourceResolver(config.slotResources);\n const capabilityClassifier = new ConfiguredCapabilityClassifier(config.toolCapabilities, config.providerToolCapabilities);\n return {\n engine,\n subjectMapper,\n slotResourceResolver,\n capabilityClassifier,\n audit: Object.freeze({ logAllowed: config.audit?.logAllowed ?? false }),\n };\n}\n\nexport function authorizationWithEngine(\n engine: IPolicyEngine,\n overrides: {\n readonly subjectMapper?: ISubjectMapper;\n readonly slotResourceResolver?: ISlotResourceResolver;\n readonly capabilityClassifier?: ICapabilityClassifier;\n readonly audit?: IAuthorizationAuditConfig;\n } = {}\n): IPolicyAuthorization {\n return {\n engine,\n subjectMapper: overrides.subjectMapper ?? new JwtSubjectMapper(),\n slotResourceResolver: overrides.slotResourceResolver ?? new DefaultSlotResourceResolver(),\n capabilityClassifier: overrides.capabilityClassifier ?? new ConfiguredCapabilityClassifier(),\n audit: Object.freeze({ logAllowed: overrides.audit?.logAllowed ?? false }),\n };\n}\n\n/** @deprecated Use {@link IPolicyAuthorization}. */\nexport type PolicyAuthorization = IPolicyAuthorization;\n","import type { IAuthorizationAuditEvent, IAuthorizationDecision, IAuthorizationSubject } from \"./policy.types\";\nimport type { ResourcePath } from \"./resource.path\";\n\nexport interface IAuditContext {\n readonly subject: IAuthorizationSubject;\n readonly slot: string;\n readonly resource?: ResourcePath;\n readonly capability?: string;\n readonly provider?: string;\n readonly tool?: string;\n}\n\nexport function makeAuthorizationAuditEvent(context: IAuditContext, decision: IAuthorizationDecision): IAuthorizationAuditEvent {\n const clientId = context.subject.ids.find((id) => id.startsWith(\"client:\"))?.slice(\"client:\".length);\n return {\n timestamp: new Date().toISOString(),\n allowed: decision.allowed,\n subjectIds: context.subject.ids,\n clientId,\n slot: context.slot,\n resource: context.resource?.value,\n capability: context.capability,\n provider: context.provider,\n tool: context.tool,\n reason: decision.reason,\n matchedPolicies: decision.matchedPolicies,\n };\n}\n\nexport function writeAuthorizationAuditEvent(event: IAuthorizationAuditEvent): void {\n console.error(`[broker] authorization ${JSON.stringify(event)}`);\n}\n\n/** @deprecated Use {@link IAuditContext}. */\nexport type AuditContext = IAuditContext;\n","/**\n * AggregateCatalog, merges the tool and prompt catalogs of several providers\n * into a single namespaced view, and routes aggregated names back to their\n * origin provider.\n *\n * Aggregated names use the `<provider>-<original>` shape. Routing never parses\n * that string back: a forward lookup table is the single source of truth, so\n * the `-` separator stays safe even when provider or tool names contain dashes.\n */\n\n/** Minimal shape of an MCP tool entry. Extra fields are preserved as-is. */\nexport interface ICatalogTool {\n name: string;\n description?: string;\n [key: string]: unknown;\n}\n\n/** Minimal shape of an MCP prompt entry. Extra fields are preserved as-is. */\nexport interface ICatalogPrompt {\n name: string;\n title?: string;\n description?: string;\n [key: string]: unknown;\n}\n\n/** One provider's raw contribution to the aggregate. */\nexport interface IProviderEntry {\n tools: ICatalogTool[];\n prompts: ICatalogPrompt[];\n}\n\n/** Where an aggregated name routes back to. */\nexport interface IRoute {\n provider: string;\n original: string;\n}\n\n/** Separator between the provider prefix and the original name. */\nconst SEPARATOR = \"-\";\n\n/** Anthropic API tool-name limit; aggregated tool names must fit inside it. */\nconst MAX_TOOL_NAME_LENGTH = 64;\n\nexport class AggregateCatalog {\n private readonly _providers = new Map<string, IProviderEntry>();\n private _tools: ICatalogTool[] = [];\n private _prompts: ICatalogPrompt[] = [];\n private _toolRoutes = new Map<string, IRoute>();\n private _promptRoutes = new Map<string, IRoute>();\n\n /** Number of providers currently contributing to the aggregate. */\n get providerCount(): number {\n return this._providers.size;\n }\n\n /** The merged, namespaced tool list. */\n get tools(): ICatalogTool[] {\n return this._tools;\n }\n\n /** The merged, namespaced prompt list. */\n get prompts(): ICatalogPrompt[] {\n return this._prompts;\n }\n\n /** Adds or replaces a provider's contribution, then rebuilds the merged view. */\n setProvider(provider: string, entry: IProviderEntry): void {\n this._providers.set(provider, entry);\n this._rebuild();\n }\n\n /** Drops a provider from the aggregate, then rebuilds. */\n removeProvider(provider: string): void {\n if (this._providers.delete(provider)) this._rebuild();\n }\n\n /** The merged tool list restricted to providers `allow` returns `true` for. */\n toolsFor(allow: (provider: string) => boolean): ICatalogTool[] {\n return this._tools.filter((tool) => {\n const route = this._toolRoutes.get(tool.name);\n return route ? allow(route.provider) : false;\n });\n }\n\n /** The merged prompt list restricted to providers `allow` returns `true` for. */\n promptsFor(allow: (provider: string) => boolean): ICatalogPrompt[] {\n return this._prompts.filter((prompt) => {\n const route = this._promptRoutes.get(prompt.name);\n return route ? allow(route.provider) : false;\n });\n }\n\n /** Resolves an aggregated tool name to its origin, or `undefined` if unknown. */\n resolveTool(name: string): IRoute | undefined {\n return this._toolRoutes.get(name);\n }\n\n /** Resolves an aggregated prompt name to its origin, or `undefined` if unknown. */\n resolvePrompt(name: string): IRoute | undefined {\n return this._promptRoutes.get(name);\n }\n\n private _rebuild(): void {\n const tools: ICatalogTool[] = [];\n const prompts: ICatalogPrompt[] = [];\n const toolRoutes = new Map<string, IRoute>();\n const promptRoutes = new Map<string, IRoute>();\n\n for (const [provider, entry] of this._providers) {\n for (const tool of entry.tools) {\n const name = unique(capToolName(prefixed(provider, tool.name)), toolRoutes);\n toolRoutes.set(name, { provider, original: tool.name });\n tools.push({ ...tool, name, description: tag(provider, tool.description) });\n }\n for (const prompt of entry.prompts) {\n const name = unique(prefixed(provider, prompt.name), promptRoutes);\n promptRoutes.set(name, { provider, original: prompt.name });\n prompts.push({ ...prompt, name, description: tag(provider, prompt.description) });\n }\n }\n\n this._tools = tools;\n this._prompts = prompts;\n this._toolRoutes = toolRoutes;\n this._promptRoutes = promptRoutes;\n }\n}\n\n/** @deprecated Use {@link ICatalogTool}. */\nexport type CatalogTool = ICatalogTool;\n\n/** @deprecated Use {@link ICatalogPrompt}. */\nexport type CatalogPrompt = ICatalogPrompt;\n\n/** @deprecated Use {@link IProviderEntry}. */\nexport type ProviderEntry = IProviderEntry;\n\n/** @deprecated Use {@link IRoute}. */\nexport type Route = IRoute;\n\nfunction prefixed(provider: string, original: string): string {\n return `${provider}${SEPARATOR}${original}`;\n}\n\n/** Tags a description with the origin provider so the model and user see the source. */\nfunction tag(provider: string, description: string | undefined): string {\n const label = `[${provider}]`;\n return description ? `${label} ${description}` : label;\n}\n\n/** Caps a tool name to the API limit, replacing the overflow with a stable hash. */\nfunction capToolName(name: string): string {\n if (name.length <= MAX_TOOL_NAME_LENGTH) return name;\n const hash = djb2(name);\n return name.slice(0, MAX_TOOL_NAME_LENGTH - hash.length - 1) + SEPARATOR + hash;\n}\n\n/** Disambiguates a name already present in `taken` by appending `-2`, `-3`, ... */\nfunction unique(candidate: string, taken: ReadonlyMap<string, unknown>): string {\n if (!taken.has(candidate)) return candidate;\n let n = 2;\n while (taken.has(`${candidate}${SEPARATOR}${n}`)) n++;\n return `${candidate}${SEPARATOR}${n}`;\n}\n\n/** Small deterministic string hash rendered as 8 base-36 characters. */\nfunction djb2(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;\n }\n return h.toString(36).padStart(8, \"0\").slice(-8);\n}\n","import type { IInternalClient } from \"../../ws/ws.interfaces\";\nimport type { ICatalogTool, ICatalogPrompt } from \"./aggregate.catalog\";\n\n/** MCP protocol version the aggregate sessions negotiate with sub-providers. */\nconst PROTOCOL_VERSION = \"2024-11-05\";\n\n/** Per-request timeout for sub-provider calls. */\nconst REQUEST_TIMEOUT_MS = 30_000;\n\n/** Outcome of a JSON-RPC request: exactly one of `result` / `error` is set. */\ninterface IRpcOutcome {\n result?: unknown;\n error?: unknown;\n}\n\ninterface IPendingRequest {\n resolve: (outcome: IRpcOutcome) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * True for the JSON-RPC \"method not found\" error, the documented way a provider\n * says it does not implement a primitive. Expected, so it is never logged.\n */\nfunction isMethodNotFound(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && (error as Record<string, unknown>).code === -32601;\n}\n\n/** Renders a JSON-RPC error payload as a one-line message for a log or a throw. */\nfunction describeRpcError(error: unknown): string {\n if (error && typeof error === \"object\" && !Array.isArray(error)) {\n const record = error as Record<string, unknown>;\n const message = typeof record.message === \"string\" ? record.message : JSON.stringify(error);\n return record.code === undefined ? message : `${message} (JSON-RPC code ${String(record.code)})`;\n }\n return typeof error === \"string\" ? error : JSON.stringify(error);\n}\n\ninterface IIncomingMessage {\n id?: string | number | null;\n method?: string;\n result?: unknown;\n error?: unknown;\n}\n\n/**\n * A hand-rolled JSON-RPC client session to one aggregated provider, running\n * over an in-process {@link IInternalClient}.\n *\n * Performs the MCP `initialize` handshake, caches the provider's `tools/list`\n * and `prompts/list`, and re-fetches them when the provider emits a\n * `list_changed` notification. `tools/call` and `prompts/get` are forwarded and\n * their raw result or error relayed back unchanged.\n */\nexport class ProviderClientSession {\n readonly provider: string;\n\n private readonly _client: IInternalClient;\n private readonly _idPrefix: string;\n private readonly _pending = new Map<string, IPendingRequest>();\n private _nextId = 0;\n private _tools: ICatalogTool[] = [];\n private _prompts: ICatalogPrompt[] = [];\n private _closed = false;\n\n /** Fires after the cached catalog changes (initial load or `list_changed`). */\n onCatalogChanged: (() => void) | null = null;\n\n /** Fires when the underlying provider slot disconnects. */\n onClosed: (() => void) | null = null;\n\n constructor(provider: string, client: IInternalClient) {\n this.provider = provider;\n this._client = client;\n this._idPrefix = `agg-${provider}-`;\n client.onMessage = (data: string): void => this._handleMessage(data);\n client.onClose = (): void => {\n if (this._closed) return;\n this._rejectAll(\"provider disconnected\");\n this.onClosed?.();\n };\n }\n\n get tools(): ICatalogTool[] {\n return this._tools;\n }\n\n get prompts(): ICatalogPrompt[] {\n return this._prompts;\n }\n\n /**\n * Runs the `initialize` handshake and the first catalog fetch.\n *\n * Throws when the provider answers `initialize` with an error, times out, or\n * has already gone away. The outcome used to be discarded, which left a\n * provider that never completed the handshake registered in `_all` with an\n * empty catalog and produced no diagnostic anywhere.\n */\n async initialize(): Promise<void> {\n const outcome = await this._request(\"initialize\", {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: {},\n clientInfo: { name: \"mcp-broker-aggregate\", version: \"0\" },\n });\n if (outcome.error !== undefined) {\n throw new Error(`provider \"${this.provider}\" refused the aggregate handshake: initialize answered ${describeRpcError(outcome.error)}.`);\n }\n this._client.send(JSON.stringify({ jsonrpc: \"2.0\", method: \"notifications/initialized\" }));\n await this._refresh();\n }\n\n /** Forwards a `tools/call` to the provider, relaying the raw outcome. */\n callTool(name: string, args: Record<string, unknown>): Promise<IRpcOutcome> {\n return this._request(\"tools/call\", { name, arguments: args });\n }\n\n /** Forwards a `prompts/get` to the provider, relaying the raw outcome. */\n getPrompt(name: string, args: Record<string, unknown>): Promise<IRpcOutcome> {\n return this._request(\"prompts/get\", { name, arguments: args });\n }\n\n /** Detaches the session and its internal client. */\n close(): void {\n if (this._closed) return;\n this._closed = true;\n this._rejectAll(\"session closed\");\n this._client.close();\n }\n\n private async _refresh(): Promise<void> {\n this._tools = await this._listAll<ICatalogTool>(\"tools/list\", \"tools\");\n this._prompts = await this._listAll<ICatalogPrompt>(\"prompts/list\", \"prompts\");\n this.onCatalogChanged?.();\n }\n\n /**\n * Refreshes the catalog without letting a failure escape, for the\n * notification path where there is no caller to hand a rejection to.\n */\n private _refreshSafely(): void {\n void this._refresh().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[broker] aggregate: refreshing the catalog of provider \"${this.provider}\" after a list_changed notification failed: ${message}`);\n });\n }\n\n /**\n * Calls a list method, following `nextCursor` pagination.\n *\n * An empty list is returned on any failure, because a provider that does not\n * implement the primitive legitimately answers `-32601`. Every other failure\n * (a timeout, a refusal) also lands here and silently produced a provider\n * with no tools, so anything that is not \"method not found\" is logged.\n */\n private async _listAll<T>(method: string, key: string): Promise<T[]> {\n const items: T[] = [];\n let cursor: string | undefined;\n do {\n let outcome: IRpcOutcome;\n try {\n outcome = await this._request(method, cursor ? { cursor } : {});\n } catch (error) {\n console.error(\n `[broker] aggregate: provider \"${this.provider}\" did not answer \"${method}\", so it joins \"_all\" with no ${key}: ${error instanceof Error ? error.message : String(error)}`\n );\n return [];\n }\n if (outcome.error !== undefined) {\n // -32601 is the documented \"I do not implement this primitive\"\n // answer and is expected from most providers for prompts/list.\n if (!isMethodNotFound(outcome.error)) {\n console.error(\n `[broker] aggregate: provider \"${this.provider}\" answered \"${method}\" with an error, so it joins \"_all\" with no ${key}: ${describeRpcError(outcome.error)} ` +\n `Clients of the \"_all\" slot will simply not see this provider's ${key}.`\n );\n }\n return [];\n }\n const page = (outcome.result ?? {}) as Record<string, unknown>;\n const list = page[key];\n if (Array.isArray(list)) items.push(...(list as T[]));\n cursor = typeof page.nextCursor === \"string\" ? page.nextCursor : undefined;\n } while (cursor);\n return items;\n }\n\n /**\n * Sends one JSON-RPC request and settles on the provider's answer.\n *\n * **Rejects** on the request timeout. Resolving with a synthetic error there\n * made every caller treat a dead provider as a provider that answered, which\n * is how a hung `initialize` ended up registered in `_all` with no trace.\n */\n private _request(method: string, params: unknown): Promise<IRpcOutcome> {\n return new Promise<IRpcOutcome>((resolve, reject) => {\n if (this._closed) {\n resolve({ error: { code: -32000, message: \"session closed\" } });\n return;\n }\n const id = this._idPrefix + String(++this._nextId);\n const startedAt = Date.now();\n const timer = setTimeout(() => {\n this._pending.delete(id);\n reject(\n new Error(\n `provider \"${this.provider}\" did not answer \"${method}\" within ${Date.now() - startedAt}ms (request id \"${id}\"). ` +\n `The provider socket is connected but nothing replied: make sure the provider installs its MCP message handler before it registers the slot, ` +\n `and that it echoes back the exact JSON-RPC id it received.`\n )\n );\n }, REQUEST_TIMEOUT_MS);\n this._pending.set(id, { resolve, timer });\n this._client.send(JSON.stringify({ jsonrpc: \"2.0\", id, method, params }));\n });\n }\n\n private _handleMessage(data: string): void {\n let msg: IIncomingMessage;\n try {\n msg = JSON.parse(data) as IIncomingMessage;\n } catch {\n return;\n }\n if (typeof msg.id === \"string\") {\n const pending = this._pending.get(msg.id);\n if (pending) {\n this._pending.delete(msg.id);\n clearTimeout(pending.timer);\n pending.resolve({ result: msg.result, error: msg.error });\n }\n return;\n }\n if (msg.id == null && (msg.method === \"notifications/tools/list_changed\" || msg.method === \"notifications/prompts/list_changed\")) {\n this._refreshSafely();\n }\n }\n\n private _rejectAll(reason: string): void {\n for (const pending of this._pending.values()) {\n clearTimeout(pending.timer);\n pending.resolve({ error: { code: -32000, message: reason } });\n }\n this._pending.clear();\n }\n}\n","import type { IMessageTransport } from \"@cyanmycelium/mcp-core\";\nimport type { IInternalClient } from \"../../ws/ws.interfaces\";\nimport type { AggregateScopeFilter, IPrincipal } from \"../../auth/index\";\nimport {\n SubjectMappingError,\n makeAuthorizationAuditEvent,\n writeAuthorizationAuditEvent,\n type IAuthorizationDecision,\n type IAuthorizationSubject,\n type IMcpOperation,\n type IPolicyAuthorization,\n} from \"../../authorization/index\";\nimport { AggregateCatalog } from \"./aggregate.catalog\";\nimport { ProviderClientSession } from \"./provider.client.session\";\n\n/** MCP protocol version advertised by the aggregate server. */\nconst PROTOCOL_VERSION = \"2024-11-05\";\n\n/** Opens an in-process client to a named provider slot. Supplied by WsTunnel. */\nexport type InternalClientFactory = (providerName: string) => IInternalClient;\n\ninterface IClientMessage {\n id?: string | number | null;\n method?: string;\n params?: unknown;\n}\n\ninterface ICallParams {\n name?: string;\n arguments?: Record<string, unknown>;\n}\n\n/** Renders an unknown thrown value as a one-line message for a log. */\nfunction describeError(error: unknown): string {\n if (error instanceof Error) return error.message;\n return typeof error === \"string\" ? error : JSON.stringify(error);\n}\n\n/** Renders a subject for a log line, so an empty one is visibly empty. */\nfunction describeSubject(subject: IAuthorizationSubject): string {\n return subject.ids.length > 0 ? subject.ids.join(\", \") : \"(none)\";\n}\n\n/**\n * The `_all` aggregate MCP server. Presents the union of every opted-in\n * provider's tools and prompts as a single MCP server, reachable on the\n * reserved `_all` slot.\n *\n * It implements {@link IMessageTransport} so it can be registered on the\n * WsTunnel as a loopback provider: `send` receives client requests, `onMessage`\n * (assigned by the tunnel) carries responses and notifications back to clients.\n */\nexport class AggregateServer implements IMessageTransport {\n /** Reserved provider slot the aggregate is published on. */\n static readonly SLOT = \"_all\";\n\n private readonly _catalog = new AggregateCatalog();\n private readonly _sessions = new Map<string, ProviderClientSession>();\n private readonly _openClient: InternalClientFactory;\n private _running = false;\n /** Per-caller provider visibility filter; `null` ⇒ every caller sees all. */\n private _scopeFilter: AggregateScopeFilter | null = null;\n /** Provider-aware hierarchical authorization, absent in legacy mode. */\n private _authorization: IPolicyAuthorization | null = null;\n\n onMessage: ((data: string) => void) | null = null;\n onOpen: (() => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n constructor(openClient: InternalClientFactory) {\n this._openClient = openClient;\n }\n\n get isOpen(): boolean {\n return this._running;\n }\n\n /** Number of providers currently in the aggregate. */\n get providerCount(): number {\n return this._sessions.size;\n }\n\n /** Marks the aggregate transport open. Call before registering it. */\n start(): void {\n this._running = true;\n }\n\n /** Sets the per-caller provider visibility filter. `null` disables filtering. */\n setScopeFilter(filter: AggregateScopeFilter | null): void {\n this._scopeFilter = filter;\n }\n\n /** Sets the compiled hierarchical policy runtime. */\n setPolicyAuthorization(authorization: IPolicyAuthorization | null): void {\n this._authorization = authorization;\n }\n\n /** WsTunnel hands a client request for the `_all` slot here (no principal). */\n send(data: string): void {\n this._dispatch(data, null);\n }\n\n /**\n * Like {@link send}, but carries the authenticated caller so the aggregate\n * narrows the catalog and routing to the providers the caller may see.\n */\n sendAs(data: string, principal: IPrincipal | null): void {\n this._dispatch(data, principal);\n }\n\n /**\n * Runs one client message to completion. The handler is async and the tunnel\n * calls us synchronously, so an unexpected throw would otherwise surface as\n * an unhandled rejection with no slot attached and take the process down.\n */\n private _dispatch(data: string, principal: IPrincipal | null): void {\n void this._handleClientMessage(data, principal).catch((error: unknown) => {\n console.error(`[broker] aggregate: unhandled failure while serving a request on slot \"${AggregateServer.SLOT}\": ${describeError(error)}`);\n });\n }\n\n /** Closes every provider session and the aggregate transport. */\n close(): void {\n if (!this._running) return;\n this._running = false;\n for (const session of this._sessions.values()) session.close();\n this._sessions.clear();\n this.onClose?.();\n }\n\n /**\n * Adds a provider to the aggregate: opens an internal client, runs the\n * session handshake, and merges the provider's catalog. A no-op for an\n * already-aggregated provider or the reserved `_all` slot itself.\n */\n async addProvider(name: string): Promise<void> {\n if (name === AggregateServer.SLOT || this._sessions.has(name)) return;\n\n const session = new ProviderClientSession(name, this._openClient(name));\n this._sessions.set(name, session);\n\n session.onCatalogChanged = (): void => {\n this._catalog.setProvider(name, { tools: session.tools, prompts: session.prompts });\n this._emitListChanged();\n };\n session.onClosed = (): void => this.removeProvider(name);\n\n try {\n await session.initialize();\n } catch (error) {\n // Reachable only because ProviderClientSession now surfaces handshake\n // failures instead of resolving them away. Before that a provider\n // whose `initialize` failed stayed registered in `_all` with an empty\n // catalog and produced no output at all, which reads to a client as\n // \"the aggregate lost my tools\".\n console.error(\n `[broker] aggregate: provider \"${name}\" failed its handshake and was not added to \"${AggregateServer.SLOT}\": ${describeError(error)} ` +\n `Its tools and prompts will not appear in the aggregate. The provider must answer the MCP \"initialize\" request the broker sends as soon as it registers: ` +\n `install the message handler before announcing the slot, and reply with the same JSON-RPC id.`\n );\n this.removeProvider(name);\n }\n }\n\n /** Removes a provider from the aggregate. */\n removeProvider(name: string): void {\n const session = this._sessions.get(name);\n if (!session) return;\n this._sessions.delete(name);\n session.close();\n this._catalog.removeProvider(name);\n this._emitListChanged();\n }\n\n private _subjectFor(principal: IPrincipal | null): IAuthorizationSubject {\n if (principal?.subject) return principal.subject;\n if (!principal) return { ids: [] };\n try {\n return (\n this._authorization?.subjectMapper.map(principal.claims) ?? {\n ids: [],\n claims: principal.claims,\n }\n );\n } catch (error) {\n // A SubjectMappingError used to be the one case that produced no\n // output, on the theory that a bad token is attacker noise. It is not:\n // the mapper only throws when a claim it was *configured* to read has\n // the wrong shape, and the empty subject returned below makes the\n // policy engine deny every request from this caller. The most likely\n // misconfiguration must not be the silent one.\n const kind = error instanceof SubjectMappingError ? \"malformed JWT subject claim\" : \"subject mapping error\";\n console.error(\n `[broker] aggregate authorization: ${kind} on slot \"${AggregateServer.SLOT}\": ${describeError(error)} ` +\n `This caller is now treated as having no subject, so every provider in the aggregate will be denied with \"no-matching-grant\". ` +\n `Fix authorization.subjectMapping (userClaim, groupClaims, clientClaim, serviceClaims) so it names claims this token actually carries as a string or an array of strings.`\n );\n return { ids: [], claims: principal.claims };\n }\n }\n\n private _scopeAllows(principal: IPrincipal | null, provider: string): boolean {\n const filter = this._scopeFilter;\n return !filter || !principal || filter(principal, provider);\n }\n\n private _policyAllows(principal: IPrincipal | null, provider: string, operation: IMcpOperation): boolean {\n const authorization = this._authorization;\n if (!authorization) return true;\n\n const subject = this._subjectFor(principal);\n const resource = authorization.slotResourceResolver.resolve(provider);\n if (!resource) {\n const decision: IAuthorizationDecision = { allowed: false, reason: \"unknown-resource\" };\n writeAuthorizationAuditEvent(makeAuthorizationAuditEvent({ subject, slot: AggregateServer.SLOT, provider }, decision));\n return false;\n }\n\n // Hoisted out of the try so the catch can name what was being evaluated.\n // Without them the failure log said nothing at all and the audit event\n // carried neither capability nor tool.\n let capability: string | undefined;\n let tool: string | undefined;\n try {\n const classified = authorization.capabilityClassifier.classify(operation, resource, provider);\n if (!classified) return true;\n capability = classified.capability;\n tool = classified.tool;\n const decision = authorization.engine.authorize({\n subject,\n capability,\n resource,\n provider,\n tool,\n });\n if (!decision.allowed || authorization.audit.logAllowed) {\n writeAuthorizationAuditEvent(\n makeAuthorizationAuditEvent(\n {\n subject,\n slot: AggregateServer.SLOT,\n resource,\n capability,\n provider,\n tool,\n },\n decision\n )\n );\n }\n return decision.allowed;\n } catch (error) {\n // The request is denied, but nothing was actually decided. Auditing\n // this as \"no-matching-grant\" named a cause that did not occur and\n // sent operators off writing grants that could never help, so it gets\n // its own reason and a log line carrying the full context.\n console.error(\n `[broker] aggregate authorization: policy evaluation threw on slot \"${AggregateServer.SLOT}\" for provider \"${provider}\", ` +\n `subject [${describeSubject(subject)}], resource \"${resource.value}\", capability \"${capability ?? \"(unclassified)\"}\"` +\n `${tool ? `, tool \"${tool}\"` : \"\"}: ${describeError(error)} ` +\n `The request is denied. This is a broker or policy-configuration fault, not a missing grant: adding grants will not change the outcome until the error above is fixed.`\n );\n const decision: IAuthorizationDecision = { allowed: false, reason: \"evaluation-error\" };\n writeAuthorizationAuditEvent(\n makeAuthorizationAuditEvent(\n {\n subject,\n slot: AggregateServer.SLOT,\n resource,\n capability,\n provider,\n tool,\n },\n decision\n )\n );\n return false;\n }\n }\n\n private _allows(principal: IPrincipal | null, provider: string, operation: IMcpOperation): boolean {\n return this._scopeAllows(principal, provider) && this._policyAllows(principal, provider, operation);\n }\n\n private async _handleClientMessage(data: string, principal: IPrincipal | null): Promise<void> {\n let msg: IClientMessage;\n try {\n msg = JSON.parse(data) as IClientMessage;\n } catch {\n return;\n }\n const id = msg.id;\n if (id == null) return; // client notification: nothing to answer\n\n switch (msg.method) {\n case \"initialize\":\n this._reply(id, {\n result: {\n protocolVersion: PROTOCOL_VERSION,\n serverInfo: { name: AggregateServer.SLOT, version: \"0\" },\n capabilities: { tools: { listChanged: true }, prompts: { listChanged: true } },\n },\n });\n break;\n case \"ping\":\n this._reply(id, { result: {} });\n break;\n case \"tools/list\":\n this._reply(id, {\n result: {\n tools: this._catalog.toolsFor((provider) => this._allows(principal, provider, { method: \"tools/list\" })),\n },\n });\n break;\n case \"prompts/list\":\n this._reply(id, {\n result: {\n prompts: this._catalog.promptsFor((provider) => this._allows(principal, provider, { method: \"prompts/list\" })),\n },\n });\n break;\n case \"tools/call\":\n await this._route(id, msg.params, \"tool\", principal);\n break;\n case \"prompts/get\":\n await this._route(id, msg.params, \"prompt\", principal);\n break;\n default:\n this._reply(id, { error: { code: -32601, message: `Method not found: ${msg.method ?? \"(none)\"}` } });\n }\n }\n\n private async _route(id: string | number, params: unknown, kind: \"tool\" | \"prompt\", principal: IPrincipal | null): Promise<void> {\n const p = (params ?? {}) as ICallParams;\n const route = p.name ? (kind === \"tool\" ? this._catalog.resolveTool(p.name) : this._catalog.resolvePrompt(p.name)) : undefined;\n // Treat a provider the caller may not see as if it did not exist, do not\n // leak its presence through a distinct \"forbidden\" error.\n const operation: IMcpOperation | undefined = route\n ? kind === \"tool\"\n ? { method: \"tools/call\", params: { name: route.original } }\n : { method: \"prompts/get\", params: { name: route.original } }\n : undefined;\n if (!route || !operation || !this._allows(principal, route.provider, operation)) {\n this._reply(id, { error: { code: -32602, message: `Unknown aggregated ${kind}: ${p.name ?? \"(none)\"}` } });\n return;\n }\n const session = this._sessions.get(route.provider);\n if (!session) {\n this._reply(id, { error: { code: -32000, message: `Provider \"${route.provider}\" is no longer connected` } });\n return;\n }\n const args = p.arguments ?? {};\n try {\n const outcome = kind === \"tool\" ? await session.callTool(route.original, args) : await session.getPrompt(route.original, args);\n this._reply(id, outcome.error !== undefined ? { error: outcome.error } : { result: outcome.result });\n } catch (error) {\n // The session rejects rather than resolves on a timeout, so the caller\n // gets a named error instead of an open request that never settles.\n const message = describeError(error);\n console.error(`[broker] aggregate: routing ${kind} \"${p.name ?? \"(none)\"}\" to provider \"${route.provider}\" failed: ${message}`);\n this._reply(id, { error: { code: -32000, message } });\n }\n }\n\n private _reply(id: string | number, body: { result?: unknown; error?: unknown }): void {\n this.onMessage?.(JSON.stringify({ jsonrpc: \"2.0\", id, ...body }));\n }\n\n private _emitListChanged(): void {\n if (!this._running) return;\n this.onMessage?.(JSON.stringify({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" }));\n this.onMessage?.(JSON.stringify({ jsonrpc: \"2.0\", method: \"notifications/prompts/list_changed\" }));\n }\n}\n","/**\n * Core contracts for the broker's OAuth 2.1 **resource server** layer.\n *\n * The broker never acts as an authorization server: it only validates the\n * access tokens minted by an external AS and advertises that AS through\n * Protected Resource Metadata (RFC 9728). These types are the seam every other\n * auth module builds on, so a host can drop in a custom {@link ITokenValidator}\n * (e.g. RFC 7662 introspection) without touching the enforcement code.\n *\n * Everything the MCP specification itself defines comes from `mcp-core` and is\n * re-exported here under the broker's historical names: the claim shape, the\n * validator seam, the error carrying a challenge. What stays broker-owned is\n * what the spec does not define, namely a multi-slot resource server whose\n * principals feed a hierarchical policy engine.\n */\nimport { McpAuthError, scopesOf as mcpScopesOf, type IAccessTokenClaims, type IMcpPrincipal, type ITokenValidator } from \"@cyanmycelium/mcp-core\";\nimport type { IAuthorizationSubject, IPolicyAuthorization, ISlotResourceResolver } from \"../authorization/index\";\n\nexport type { IAccessTokenClaims, ITokenValidator } from \"@cyanmycelium/mcp-core\";\n\n/** OAuth 2.1 error codes the broker emits in `WWW-Authenticate` challenges. */\nexport type AuthErrorCode = import(\"@cyanmycelium/mcp-core\").McpAuthErrorCode;\n\n/**\n * A thrown authorization failure carrying the HTTP status and OAuth error code\n * the enforcement point should surface. `scope` is set for `insufficient_scope`\n * challenges to advertise the scope(s) the resource requires.\n *\n * The broker's own name for `mcp-core`'s `McpAuthError`, kept so `instanceof`\n * checks and the published API survive the consolidation. There is one class at\n * runtime, so an error thrown by `mcp-core` is caught by the broker and the\n * other way round.\n */\nexport const AuthError = McpAuthError;\nexport type AuthError = McpAuthError;\n\n/**\n * The authenticated caller, produced once a token passes validation and the\n * required scopes are satisfied. Threaded through the request so downstream\n * components (e.g. the `_all` aggregate) can make scope-aware decisions.\n *\n * Extends `mcp-core`'s principal with the subject the policy engine reasons\n * about, which the specification says nothing about and which therefore stays\n * here.\n */\nexport interface IPrincipal extends IMcpPrincipal {\n readonly claims: IAccessTokenClaims;\n readonly scopes: ReadonlySet<string>;\n /** Subjects derived exclusively from validated token claims. */\n readonly subject?: IAuthorizationSubject;\n}\n\n/**\n * Decides, per authenticated caller, whether a given provider is visible in the\n * `_all` aggregate. This is the content-confidentiality enforcement point: a\n * client only sees (and can call) tools/prompts from providers it is authorized\n * for. Return `true` to include the provider for this principal.\n */\nexport type AggregateScopeFilter = (principal: IPrincipal, providerName: string) => boolean;\n\n/**\n * A fully resolved authorization configuration, ready for the enforcement\n * layer. Built either from JSON config (via `buildJwtAuth`) or supplied\n * directly by an embedder with a custom {@link ITokenValidator}.\n */\nexport interface IResolvedAuth {\n /**\n * Public origin the broker is reached at, used to build canonical resource\n * URIs and metadata URLs. No trailing slash (e.g. `https://mcp.example.com`).\n */\n publicBaseUrl: string;\n /** One or more authorization server issuer URLs, advertised in the PRM. */\n authorizationServers: string[];\n /** Optional list of scopes advertised in the PRM `scopes_supported`. */\n scopesSupported?: string[];\n /** The token validator (JWKS-backed by default). */\n validator: ITokenValidator;\n /** Baseline scope(s) required to reach any slot. Empty ⇒ any valid token. */\n requiredScopes?: string[];\n /** Per-slot required-scope overrides (e.g. an admin scope for `_broker`). */\n perSlotScopes?: Record<string, string[]>;\n /**\n * Per-caller filter for the `_all` aggregate. When set, a client's view of\n * `_all` is narrowed to the providers this returns `true` for. When absent,\n * every authenticated caller sees the full aggregate.\n */\n aggregateScopeFilter?: AggregateScopeFilter;\n /** Compiled hierarchical policy runtime, absent for legacy OAuth behavior. */\n authorization?: IPolicyAuthorization;\n /** Optional resolver usable for provider namespace checks without policies. */\n slotResourceResolver?: ISlotResourceResolver;\n}\n\n/**\n * Extracts the effective set of granted scopes from token claims.\n *\n * A deliberate superset of `mcp-core`'s: OAuth 2.1 only defines the\n * space-delimited `scope` string, which is what the spec-level helper reads,\n * but several authorization servers emit an array-form `scopes` claim instead.\n * Dropping that here would silently strip every scope for those deployments, so\n * the two are unioned. The `scope` half is parsed by `mcp-core` rather than\n * re-implemented.\n */\nexport function scopesOf(claims: IAccessTokenClaims): Set<string> {\n const set = new Set<string>(mcpScopesOf(claims));\n const arrayForm: unknown = claims[\"scopes\"];\n if (Array.isArray(arrayForm)) {\n for (const scope of arrayForm) if (typeof scope === \"string\" && scope) set.add(scope);\n }\n return set;\n}\n\n/** @deprecated Use {@link IAccessTokenClaims}. */\nexport type AccessTokenClaims = IAccessTokenClaims;\n/** @deprecated Use {@link ITokenValidator}. */\nexport type TokenValidator = ITokenValidator;\n/** @deprecated Use {@link IPrincipal}. */\nexport type Principal = IPrincipal;\n/** @deprecated Use {@link IResolvedAuth}. */\nexport type ResolvedAuth = IResolvedAuth;\n","import { createRemoteJWKSet, jwtVerify, errors, type JWTVerifyGetKey } from \"jose\";\nimport { AuthError, type IAccessTokenClaims, type ITokenValidator } from \"./auth.types\";\n\n/**\n * Options for {@link JwtTokenValidator}. `jwksUri` points at the authorization\n * server's JWKS endpoint; `issuer` (when set) is checked against the token `iss`.\n */\nexport interface IJwtValidatorOptions {\n /** URL of the authorization server's JWKS document. */\n jwksUri: string;\n /** Expected token issuer(s). When omitted, the `iss` claim is not checked. */\n issuer?: string | string[];\n /** Leeway in seconds for `exp`/`nbf` checks. Defaults to jose's `0`. */\n clockToleranceSec?: number;\n}\n\n/**\n * An {@link ITokenValidator} that verifies JWT access tokens **statelessly** by\n * checking the signature against the authorization server's JWKS and validating\n * the standard claims. This is the default validator for a public deployment:\n * no per-request round-trip to the AS, no shared introspection secret.\n *\n * Audience binding (RFC 8707) is enforced by passing the per-request canonical\n * resource URI as the required `audience`, so a token minted for another slot ,\n * or another service, is rejected.\n *\n * The JWKS is fetched lazily and cached (with rotation/cooldown) by\n * `jose.createRemoteJWKSet`.\n */\nexport class JwtTokenValidator implements ITokenValidator {\n private readonly _jwks: JWTVerifyGetKey;\n private readonly _issuer?: string | string[];\n private readonly _clockTolerance: number;\n\n constructor(options: IJwtValidatorOptions) {\n this._jwks = createRemoteJWKSet(new URL(options.jwksUri));\n this._issuer = options.issuer;\n this._clockTolerance = options.clockToleranceSec ?? 0;\n }\n\n async validate(token: string, resource: string): Promise<IAccessTokenClaims> {\n try {\n const { payload } = await jwtVerify(token, this._jwks, {\n audience: resource,\n issuer: this._issuer,\n clockTolerance: this._clockTolerance,\n });\n return payload as IAccessTokenClaims;\n } catch (err) {\n // Token-level failures (bad signature, wrong audience/issuer, expired,\n // no matching key) are JOSEError subclasses ⇒ a genuine 401. Anything\n // else (JWKS endpoint unreachable, malformed config) is infrastructure:\n // rethrow so the caller surfaces a 500 instead of a misleading 401.\n if (err instanceof errors.JOSEError) {\n throw new AuthError(401, \"invalid_token\", err.message);\n }\n throw err;\n }\n }\n}\n\n/** @deprecated Use {@link IJwtValidatorOptions}. */\nexport type JwtValidatorOptions = IJwtValidatorOptions;\n","/**\n * OAuth 2.0 Protected Resource Metadata (RFC 9728).\n *\n * Each slot exposed over HTTP is an independent resource server; its metadata\n * document tells an MCP client which authorization server(s) issue tokens for\n * that slot and which bearer methods it accepts. Served (unauthenticated, it is\n * public discovery data) at\n * `<publicBaseUrl>/.well-known/oauth-protected-resource/<slot>/<mcp>`.\n */\n\nimport { buildProtectedResourceMetadata, type IProtectedResourceMetadata } from \"@cyanmycelium/mcp-core\";\n\n/** The RFC 9728 metadata document for a single protected resource. */\nexport type { IProtectedResourceMetadata } from \"@cyanmycelium/mcp-core\";\n\n/**\n * Builds the RFC 9728 metadata document for one slot.\n *\n * The document itself is shaped by `mcp-core`: it is defined by the MCP\n * specification, identically for every server. What is broker-specific is only\n * which resource a slot maps to, and that is decided by the caller.\n * `bearer_methods_supported` comes out fixed to `[\"header\"]`, matching the\n * broker's refusal to read a token from anywhere but the header (OAuth 2.1 §5).\n */\nexport function buildResourceMetadata(params: { resource: string; authorizationServers: string[]; scopesSupported?: string[] }): IProtectedResourceMetadata {\n return buildProtectedResourceMetadata({\n resource: params.resource,\n authorizationServers: params.authorizationServers,\n scopesSupported: params.scopesSupported,\n });\n}\n\n/** @deprecated Use {@link IProtectedResourceMetadata}. */\nexport type ProtectedResourceMetadata = IProtectedResourceMetadata;\n","import type { IncomingMessage, ServerResponse } from \"http\";\nimport { bearerToken, buildChallengeHeader, PROTECTED_RESOURCE_METADATA_PREFIX } from \"@cyanmycelium/mcp-core\";\nimport { AuthError, scopesOf, type IPrincipal, type IResolvedAuth } from \"./auth.types\";\nimport { buildResourceMetadata, type IProtectedResourceMetadata } from \"./resource.metadata\";\nimport { SubjectMappingError } from \"../authorization/index\";\n\n/**\n * Well-known prefix under which per-slot Protected Resource Metadata is served.\n *\n * Carries a trailing slash because every use here splits a slot off it, while\n * `mcp-core` exports the bare RFC 9728 prefix.\n */\nconst PRM_PREFIX = `${PROTECTED_RESOURCE_METADATA_PREFIX}/`;\n\n/**\n * The HTTP enforcement point for the resource-server layer. Wraps a\n * {@link IResolvedAuth} plus the configured `/mcp` path suffix and turns it into\n * the three operations the transport needs: serve Protected Resource Metadata,\n * authorize a request, and write an RFC 9728 `401`/`403` challenge.\n *\n * A slot's **canonical resource URI** is `<publicBaseUrl>/<slot>/<mcp>` and is\n * used uniformly across all of that slot's HTTP endpoints (`/mcp`, `/sse`,\n * `/messages`) so a single token audience covers the whole slot.\n */\nexport class HttpAuthGuard {\n private readonly _auth: IResolvedAuth;\n /** The `/mcp` suffix without a leading slash, e.g. `\"mcp\"`. */\n private readonly _mcpSuffix: string;\n\n constructor(auth: IResolvedAuth, mcpSuffix: string) {\n this._auth = auth;\n this._mcpSuffix = mcpSuffix.replace(/^\\//, \"\");\n }\n\n /** Canonical resource identifier for a slot (RFC 8707 §2). */\n resourceFor(slot: string): string {\n return `${this._auth.publicBaseUrl}/${encodeURIComponent(slot)}/${this._mcpSuffix}`;\n }\n\n /** RFC 9728 metadata URL for a slot, advertised in the `401` challenge. */\n metadataUrlFor(slot: string): string {\n return `${this._auth.publicBaseUrl}${PRM_PREFIX}${encodeURIComponent(slot)}/${this._mcpSuffix}`;\n }\n\n /** Required scope(s) for a slot: per-slot override, else the baseline. */\n requiredScopesFor(slot: string): string[] {\n return this._auth.perSlotScopes?.[slot] ?? this._auth.requiredScopes ?? [];\n }\n\n /** The RFC 9728 metadata document for a slot. */\n metadataFor(slot: string): IProtectedResourceMetadata {\n return buildResourceMetadata({\n resource: this.resourceFor(slot),\n authorizationServers: this._auth.authorizationServers,\n scopesSupported: this._auth.scopesSupported,\n });\n }\n\n /**\n * If `rawUrl` is a Protected Resource Metadata request\n * (`/.well-known/oauth-protected-resource/<slot>/<mcp>`), returns the slot;\n * otherwise `null`.\n */\n matchMetadataRequest(rawUrl: string): string | null {\n if (!rawUrl.startsWith(PRM_PREFIX)) return null;\n const parts = rawUrl.slice(PRM_PREFIX.length).split(\"/\").filter(Boolean);\n if (parts.length !== 2 || parts[1] !== this._mcpSuffix) return null;\n return decodeURIComponent(parts[0]);\n }\n\n /**\n * Validates the request's bearer token against the slot's canonical resource\n * and enforces the slot's required scopes. Resolves to the {@link IPrincipal}\n * on success; rejects with an {@link AuthError} (`401` missing/invalid token,\n * `403` insufficient scope) otherwise.\n */\n async authorize(req: IncomingMessage, slot: string): Promise<IPrincipal> {\n const token = bearerToken(req.headers[\"authorization\"]);\n if (!token) {\n throw new AuthError(401, \"invalid_token\", \"Missing bearer token\");\n }\n\n const claims = await this._auth.validator.validate(token, this.resourceFor(slot));\n const scopes = scopesOf(claims);\n\n const required = this.requiredScopesFor(slot);\n const missing = required.filter((s) => !scopes.has(s));\n if (missing.length > 0) {\n throw new AuthError(403, \"insufficient_scope\", `Missing required scope(s): ${missing.join(\" \")}`, required.join(\" \"));\n }\n\n let subject: IPrincipal[\"subject\"];\n try {\n subject = this._auth.authorization?.subjectMapper.map(claims);\n } catch (error) {\n if (error instanceof SubjectMappingError) {\n throw new AuthError(403, \"insufficient_scope\", \"Malformed configured JWT subject claim\");\n }\n throw error;\n }\n\n return subject ? { claims, scopes, subject } : { claims, scopes };\n }\n\n /**\n * Builds the RFC 9728 §5.1 `WWW-Authenticate` header value for a challenge.\n * Always points the client at the slot's metadata URL so it can discover the\n * authorization server and retry. Shared by the HTTP and WebSocket paths.\n */\n challengeHeader(slot: string, err: AuthError): string {\n return buildChallengeHeader({\n resourceMetadata: this.metadataUrlFor(slot),\n error: err.code,\n errorDescription: err.description,\n scope: err.scope,\n });\n }\n\n /**\n * Writes an RFC 9728 §5.1 `WWW-Authenticate` challenge and the matching\n * status to an HTTP response.\n */\n writeChallenge(res: ServerResponse, slot: string, err: AuthError): void {\n res.setHeader(\"WWW-Authenticate\", this.challengeHeader(slot, err));\n res.writeHead(err.status, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify({ error: err.code, error_description: err.description }));\n }\n}\n","import { JwtTokenValidator } from \"./jwt.validator\";\nimport type { AggregateScopeFilter, IResolvedAuth } from \"./auth.types\";\nimport { compileAuthorizationPolicy, DefaultSlotResourceResolver, hasAuthorizationPolicies, type IAuthorizationPolicyConfig } from \"../authorization/index\";\n\n/**\n * High-level options for the default JWT/JWKS resource-server setup. Mirrors the\n * `auth` block of the broker JSON config and is turned into a fully\n * {@link IResolvedAuth} (with a {@link JwtTokenValidator}) by {@link buildJwtAuth}.\n */\nexport interface IJwtAuthOptions extends IAuthorizationPolicyConfig {\n /** Public origin the broker is reached at (e.g. `https://mcp.example.com`). */\n publicBaseUrl: string;\n /** Authorization server issuer URL(s) advertised in the PRM. At least one. */\n authorizationServers: string[];\n /** URL of the authorization server's JWKS document. */\n jwksUri: string;\n /** Expected token issuer(s). Defaults to the sole authorization server. */\n issuer?: string | string[];\n /** Scopes advertised in the PRM `scopes_supported`. */\n scopesSupported?: string[];\n /** Baseline scope(s) required to reach any slot. */\n requiredScopes?: string[];\n /** Per-slot required-scope overrides (e.g. an admin scope for `_broker`). */\n perSlotScopes?: Record<string, string[]>;\n /**\n * Per-provider scope requirements for the `_all` aggregate. A caller sees a\n * provider in `_all` only if it holds at least one of the listed scopes.\n * Providers not listed here stay visible to every authenticated caller.\n * Turned into an {@link AggregateScopeFilter} automatically.\n */\n providerScopes?: Record<string, string[]>;\n /** Leeway in seconds for token `exp`/`nbf` checks. */\n clockToleranceSec?: number;\n}\n\n/** Builds the default aggregate filter from a per-provider scope map. */\nfunction makeProviderScopeFilter(providerScopes: Record<string, string[]>): AggregateScopeFilter {\n return (principal, providerName) => {\n const required = providerScopes[providerName];\n if (!required || required.length === 0) return true; // unlisted ⇒ visible to all\n return required.some((scope) => principal.scopes.has(scope));\n };\n}\n\n/** Removes a single trailing slash so resource URIs concatenate cleanly. */\nfunction stripTrailingSlash(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\n/**\n * Builds an {@link IResolvedAuth} backed by a {@link JwtTokenValidator}. Validates\n * the required inputs up front and throws a descriptive error on misconfig, so\n * an operator sees the problem at boot rather than as opaque `401`s later.\n */\nexport function buildJwtAuth(options: IJwtAuthOptions): IResolvedAuth {\n if (!options.publicBaseUrl) {\n throw new Error(\"auth: publicBaseUrl is required.\");\n }\n if (!options.authorizationServers || options.authorizationServers.length === 0) {\n throw new Error(\"auth: at least one authorizationServers entry is required.\");\n }\n if (!options.jwksUri) {\n throw new Error(\"auth: jwksUri is required.\");\n }\n\n const publicBaseUrl = stripTrailingSlash(options.publicBaseUrl);\n const issuer = options.issuer ?? (options.authorizationServers.length === 1 ? options.authorizationServers[0] : undefined);\n\n const validator = new JwtTokenValidator({\n jwksUri: options.jwksUri,\n issuer,\n clockToleranceSec: options.clockToleranceSec,\n });\n\n const resolved: IResolvedAuth = {\n publicBaseUrl,\n authorizationServers: options.authorizationServers,\n validator,\n };\n if (options.scopesSupported) resolved.scopesSupported = options.scopesSupported;\n if (options.requiredScopes) resolved.requiredScopes = options.requiredScopes;\n if (options.perSlotScopes) resolved.perSlotScopes = options.perSlotScopes;\n if (options.providerScopes && Object.keys(options.providerScopes).length > 0) {\n console.warn(\"[mcp-broker] auth.providerScopes is deprecated; migrate to roles and hierarchical assignments.\");\n resolved.aggregateScopeFilter = makeProviderScopeFilter(options.providerScopes);\n }\n if (options.slotResources && Object.keys(options.slotResources).length > 0) {\n resolved.slotResourceResolver = new DefaultSlotResourceResolver(options.slotResources);\n }\n if (hasAuthorizationPolicies(options)) {\n resolved.authorization = compileAuthorizationPolicy(options);\n resolved.slotResourceResolver = resolved.authorization.slotResourceResolver;\n }\n return resolved;\n}\n\n/** @deprecated Use {@link IJwtAuthOptions}. */\nexport type JwtAuthOptions = IJwtAuthOptions;\n","import { timingSafeEqual } from \"crypto\";\nimport type { IncomingMessage } from \"http\";\nimport { ResourcePath, ResourcePathPattern } from \"../authorization/index\";\n\nexport interface IProviderPrincipal {\n readonly id: string;\n readonly subjects?: readonly string[];\n readonly allowedResources?: readonly string[];\n readonly metadata?: Readonly<Record<string, unknown>>;\n}\n\nexport type ProviderAuthenticationResult = { readonly authenticated: true; readonly principal: IProviderPrincipal } | { readonly authenticated: false; readonly reason?: string };\n\nexport type ProviderAuthenticatorReturn = boolean | ProviderAuthenticationResult;\n\n/**\n * Authenticates a **provider** (the engine that connects _into_ the broker to\n * serve a slot) at the WebSocket upgrade handshake. This is a distinct concern\n * from the OAuth 2.1 resource-server layer that guards *clients*: a provider is\n * not an OAuth client acting for a resource owner, it is the backend claiming a\n * slot. Authenticating it is what stops a stranger from occupying a free slot\n * (`ws://host/provider/<slot>`) and impersonating the real engine.\n */\nexport interface IProviderAuthenticator {\n /**\n * Returns a structured result, or a legacy boolean for backward\n * compatibility. `slot` is the dedicated slot name for\n * `/provider/<slot>`, or `undefined` for the multiplexed `/providers`\n * socket, which is authenticated before any provider name is known.\n */\n authenticate(req: IncomingMessage, slot: string | undefined): ProviderAuthenticatorReturn | Promise<ProviderAuthenticatorReturn>;\n}\n\nexport function normalizeProviderAuthentication(result: ProviderAuthenticatorReturn, fallbackId = \"legacy-provider\"): ProviderAuthenticationResult {\n if (typeof result === \"boolean\") {\n return result ? { authenticated: true, principal: { id: fallbackId, allowedResources: [\"**\"] } } : { authenticated: false };\n }\n if (!result.authenticated) return result;\n if (!result.principal.id) return { authenticated: false, reason: \"provider principal id is empty\" };\n return result;\n}\n\n/** Wording shared by every \"this pattern is not valid\" diagnostic. */\nconst PATTERN_SYNTAX_HINT = 'Resource patterns are absolute and segment-based: \"/enterprise/**\", \"/enterprise/*/line-3\", \"/enterprise/site-a/asset\", or \"**\" for everything.';\n\n/**\n * Compiled `allowedResources` patterns, keyed by the exact pattern string, with\n * the compile failure cached alongside the successes.\n *\n * {@link providerMayPublish} runs on every provider WebSocket upgrade, and the\n * previous per-call `ResourcePathPattern.parse` inside a `try` meant a single\n * typo re-threw on every registration and was mapped to a bare `false`. Caching\n * the outcome makes the parse happen once per distinct pattern and gives the\n * failure a stable identity we can report exactly once.\n */\nconst compiledPatterns = new Map<string, ResourcePathPattern | Error>();\n\n/** Malformed-pattern reports already emitted, so a wedged config logs once. */\nconst reportedMalformedPatterns = new Set<string>();\n\n/** Parses one pattern, memoizing both the success and the failure. */\nfunction compilePattern(pattern: string): ResourcePathPattern | Error {\n const cached = compiledPatterns.get(pattern);\n if (cached !== undefined) return cached;\n let compiled: ResourcePathPattern | Error;\n try {\n compiled = ResourcePathPattern.parse(pattern);\n } catch (error) {\n compiled = error instanceof Error ? error : new Error(String(error));\n }\n compiledPatterns.set(pattern, compiled);\n return compiled;\n}\n\n/** Why a provider was refused a slot. `undefined` when it was allowed. */\nexport type ProviderPublishDenialReason = \"no-allowed-resources\" | \"out-of-namespace\" | \"malformed-pattern\";\n\n/** The outcome of a provider namespace check, with the cause when it denies. */\nexport interface IProviderPublishDecision {\n readonly allowed: boolean;\n /** Machine-readable cause, present only when `allowed` is `false`. */\n readonly reason?: ProviderPublishDenialReason;\n /** Operator-facing explanation that already names the fix. */\n readonly detail?: string;\n}\n\n/**\n * Compiles a principal's `allowedResources`, throwing on the first malformed\n * pattern with the offending pattern quoted in the message.\n *\n * Call this wherever a provider principal is *built* (config load, a custom\n * authenticator's constructor) so a typo fails the broker at startup instead of\n * silently 403-ing every provider on that principal forever.\n * {@link providerPublishDecision} deliberately does not throw: it runs inside the\n * WebSocket upgrade, where the only safe answer to \"is this pattern valid?\" is\n * to deny loudly.\n */\nexport function compileProviderAllowedResources(allowed: readonly string[], label = \"provider allowedResources\"): readonly ResourcePathPattern[] {\n return allowed.map((pattern) => {\n const compiled = compilePattern(pattern);\n if (compiled instanceof Error) {\n throw new Error(`${label}: \"${pattern}\" is not a valid resource pattern: ${compiled.message} ${PATTERN_SYNTAX_HINT}`);\n }\n return compiled;\n });\n}\n\n/**\n * Decides whether a provider principal may claim `resource`, and says why when\n * it may not.\n *\n * Every denial here surfaces to the provider as a bare 403 at the WebSocket\n * handshake, which a browser reports as a contentless error event. The reason is\n * therefore the only thing an operator (or an agent wiring this up) has to work\n * from, so it is returned to the caller for the registration log and, for the\n * configuration-fault case, logged here as well.\n */\nexport function providerPublishDecision(principal: IProviderPrincipal, resource: ResourcePath): IProviderPublishDecision {\n const allowed = principal.allowedResources;\n if (allowed === undefined) return { allowed: true };\n if (allowed.length === 0) {\n return {\n allowed: false,\n reason: \"no-allowed-resources\",\n detail:\n `Provider principal \"${principal.id}\" has an empty allowedResources list, which forbids every slot. ` +\n `Remove the key entirely to allow all slots, or list the namespaces this principal may publish, for example [\"/enterprise/**\"].`,\n };\n }\n\n const patterns: ResourcePathPattern[] = [];\n const malformed: string[] = [];\n for (const pattern of allowed) {\n const compiled = compilePattern(pattern);\n if (compiled instanceof Error) malformed.push(`\"${pattern}\" (${compiled.message})`);\n else patterns.push(compiled);\n }\n\n if (malformed.length > 0) {\n const detail =\n `Provider principal \"${principal.id}\" carries ${malformed.length} malformed allowedResources pattern(s): ${malformed.join(\"; \")} ` +\n `Every provider registration on this principal is refused with 403 until they are fixed, whatever slot it asks for. ${PATTERN_SYNTAX_HINT}`;\n // Loud, but once per (principal, bad pattern set): this is a\n // startup-class configuration fault the broker can never honor, and its\n // request-time symptom is a 403 that names nothing.\n const key = `${principal.id}|${malformed.join(\"|\")}`;\n if (!reportedMalformedPatterns.has(key)) {\n reportedMalformedPatterns.add(key);\n console.error(`[broker] provider auth: ${detail}`);\n }\n return { allowed: false, reason: \"malformed-pattern\", detail };\n }\n\n if (patterns.some((pattern) => pattern.matches(resource))) return { allowed: true };\n return {\n allowed: false,\n reason: \"out-of-namespace\",\n detail:\n `Provider principal \"${principal.id}\" may not publish resource \"${resource.value}\": it is outside allowedResources [${allowed.join(\", \")}]. ` +\n `Either connect the provider to a slot inside one of those namespaces, or widen allowedResources for this principal.`,\n };\n}\n\n/**\n * Boolean form of {@link providerPublishDecision}, kept for callers that only\n * need the verdict. Prefer the decision form so the refusal can be logged with\n * its cause.\n */\nexport function providerMayPublish(principal: IProviderPrincipal, resource: ResourcePath): boolean {\n return providerPublishDecision(principal, resource).allowed;\n}\n\n/** Constant-time string comparison; `false` on any length mismatch. */\nfunction safeEqual(a: string, b: string): boolean {\n const ab = Buffer.from(a);\n const bb = Buffer.from(b);\n if (ab.length !== bb.length) return false;\n return timingSafeEqual(ab, bb);\n}\n\n/**\n * Reads the secret a provider presents, from either the `X-Provider-Token`\n * header or an `Authorization: Bearer <secret>` header.\n */\nfunction presentedSecret(req: IncomingMessage): string | null {\n const xheader = req.headers[\"x-provider-token\"];\n if (typeof xheader === \"string\" && xheader.trim()) return xheader.trim();\n\n const auth = req.headers[\"authorization\"];\n if (typeof auth === \"string\") {\n const match = /^Bearer\\s+(.+)$/i.exec(auth.trim());\n if (match) return match[1].trim();\n }\n return null;\n}\n\n/**\n * The default {@link IProviderAuthenticator}: every provider connection must\n * present a single shared secret (via `X-Provider-Token` or `Authorization:\n * Bearer`). Compared in constant time. Suitable when the broker and its\n * providers are operated by the same party; swap in a custom authenticator for\n * per-slot secrets, mTLS, or a signed handshake.\n */\nexport class SharedSecretProviderAuthenticator implements IProviderAuthenticator {\n private readonly _secret: string;\n\n constructor(secret: string) {\n if (!secret) {\n throw new Error(\"provider auth: a non-empty shared secret is required.\");\n }\n this._secret = secret;\n }\n\n authenticate(req: IncomingMessage): ProviderAuthenticationResult {\n const presented = presentedSecret(req);\n if (!presented || !safeEqual(presented, this._secret)) {\n return { authenticated: false };\n }\n return {\n authenticated: true,\n principal: {\n id: \"shared-secret\",\n allowedResources: [\"**\"],\n },\n };\n }\n}\n\n/** @deprecated Use {@link IProviderPrincipal}. */\nexport type ProviderPrincipal = IProviderPrincipal;\n/** @deprecated Use {@link IProviderAuthenticator}. */\nexport type ProviderAuthenticator = IProviderAuthenticator;\n","import { createRequire } from \"module\";\n\n// Resolves the package's own version from package.json without bundler help.\n// Works both for the compiled dist/version.js (one level below package.json)\n// and for tsc's source-level resolution from src/version.ts.\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string; name: string };\n\nexport const VERSION: string = pkg.version;\nexport const PACKAGE_NAME: string = pkg.name;\n","import * as fs from \"fs\";\nimport * as http from \"http\";\nimport * as https from \"https\";\nimport * as nodePath from \"path\";\nimport { randomUUID } from \"crypto\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { WebSocket, WebSocketServer, type VerifyClientCallbackAsync } from \"ws\";\nimport type { IMessageTransport, IMcpServer } from \"@cyanmycelium/mcp-core\";\nimport { StdioTransport, StreamableHttpEndpoint } from \"@cyanmycelium/mcp-core/node\";\n// The broker is itself a provider: it publishes its own `_broker` and `_all`\n// slots: so sharing the provider package's wire contract is the natural way to\n// keep one definition of the envelope rather than two that drift.\nimport { decodeEnvelope, encodeEnvelope, encodeErrorEnvelope, envelopeFrame, TUNNEL_REGISTER_METHOD, TunnelErrorCodes } from \"@cyanmycelium/mcp-broker-provider/protocol\";\nimport { StdioUpstream } from \"../stdio.upstream\";\nimport { RemoteUpstream } from \"../remote.upstream\";\nimport type { IUpstream } from \"../upstream\";\nimport { startBrokerServer, BROKER_PROVIDER_NAME } from \"../broker/index\";\nimport type { IBrokerContext, IBrokerProviderInfo, BrokerProviderTransport } from \"../broker/index\";\n// Imported from the defining module rather than the barrel: these two are the\n// optional `IBrokerContext` extensions `broker_diagnose` reads, and the barrel\n// does not re-export them yet.\nimport type { IBrokerSecurityInfo } from \"../broker/broker.context\";\nimport { AggregateServer } from \"../broker/aggregate/aggregate.server\";\nimport {\n HttpAuthGuard,\n AuthError,\n normalizeProviderAuthentication,\n providerMayPublish,\n type IProviderAuthenticator,\n type IPrincipal,\n type IProviderPrincipal,\n} from \"../auth/index\";\nimport {\n DefaultSlotResourceResolver,\n SubjectMappingError,\n makeAuthorizationAuditEvent,\n writeAuthorizationAuditEvent,\n type IAuthorizationDecision,\n type IAuthorizationSubject,\n type IPolicyAuthorization,\n type ResourcePath,\n type ISlotResourceResolver,\n} from \"../authorization/index\";\nimport { VERSION, PACKAGE_NAME } from \"../version\";\nimport type {\n AllowedOrigins,\n IHttpSession,\n IInternalClient,\n IProviderState,\n IWsTunnelOptions,\n McpEndpointKind,\n ProviderTakeoverMode,\n ResponseSink,\n WsConnectRole,\n WsRouteClassification,\n} from \"./ws.interfaces\";\n\n// ---------------------------------------------------------------------------\n// Static-file helpers\n// ---------------------------------------------------------------------------\n\n/** Maps file extensions to their HTTP Content-Type values. */\nconst MIME: Readonly<Record<string, string>> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".map\": \"application/json; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff2\": \"font/woff2\",\n \".woff\": \"font/woff\",\n};\n\n// ---------------------------------------------------------------------------\n// JSON-RPC helpers\n// ---------------------------------------------------------------------------\n\n/**\n * The JSON-RPC id a frame is waiting on, or `undefined` when nothing will come\n * back for it: a notification, or something that did not parse.\n *\n * `null` is a legal id in an error response, so absence cannot be signalled\n * with it, hence `undefined`.\n */\nfunction requestIdOf(frame: string): string | number | undefined {\n try {\n const parsed = JSON.parse(frame) as { id?: unknown };\n if (typeof parsed?.id === \"string\" || typeof parsed?.id === \"number\") return parsed.id;\n } catch {\n /* not JSON: nothing to route by */\n }\n return undefined;\n}\n\n/**\n * Prefix of every broker-assigned JSON-RPC id.\n *\n * Requests are re-numbered on their way to a provider so two clients on one\n * slot cannot collide (see {@link WsTunnel._trackRequest}). The prefix is\n * cosmetic but deliberate: it makes a stray id recognizable as the broker's in\n * a provider's own logs, instead of looking like a client's.\n */\nconst BROKER_REQUEST_ID_PREFIX = \"brk-\";\n\n/** Default heartbeat period, in ms, for `providerHeartbeatIntervalMs`. */\nconst DEFAULT_PROVIDER_HEARTBEAT_MS = 30_000;\n\n/** Default per-request deadline, in ms, for `providerRequestTimeoutMs`. */\nconst DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 60_000;\n\n/**\n * RFC 6455 caps a close reason at 123 bytes and `ws` throws a `RangeError`\n * rather than truncating, which would turn a diagnostic into a crash inside a\n * connection handler. Every close reason goes through {@link truncateReason}.\n */\nconst MAX_CLOSE_REASON_BYTES = 123;\n\n/** Shortens a close reason to what RFC 6455 allows, without splitting a character. */\nfunction truncateReason(reason: string): string {\n if (Buffer.byteLength(reason, \"utf8\") <= MAX_CLOSE_REASON_BYTES) return reason;\n let cut = reason;\n while (Buffer.byteLength(cut + \"...\", \"utf8\") > MAX_CLOSE_REASON_BYTES) {\n cut = cut.slice(0, -1);\n }\n return cut + \"...\";\n}\n\n/**\n * `decodeURIComponent` that returns its input instead of throwing.\n *\n * A slot name arrives from a URL, so it is attacker-controlled: `%zz` throws a\n * `URIError`, and both call sites here run inside a WebSocket connection\n * handler, where an exception is an uncaught one.\n */\nfunction safeDecode(raw: string): string {\n try {\n return decodeURIComponent(raw);\n } catch {\n return raw;\n }\n}\n\n/** Parses a frame into a plain JSON object, or `undefined` for anything else. */\nfunction parseObjectFrame(text: string): Record<string, unknown> | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return undefined;\n return parsed as Record<string, unknown>;\n}\n\n/**\n * `true` when the frame is the tunnel registration notification asking to join\n * the `_all` aggregate slot, in either of the two shapes the broker accepts.\n *\n * Both are notifications a peer that does not know them ignores, which is why\n * the opt-in could be added without a protocol version: the JSON-RPC form\n * `{\"jsonrpc\":\"2.0\",\"method\":\"notifications/register\",\"params\":{\"aggregate\":true}}`\n * is what the provider SDK sends on both paths, and the legacy control frame\n * `{\"type\":\"register\",\"aggregate\":true}` is what hand-written providers send on\n * the slot-scoped path.\n */\nfunction registrationAsksForAggregate(payload: unknown): boolean {\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) return false;\n const frame = payload as { jsonrpc?: unknown; method?: unknown; params?: unknown; type?: unknown; aggregate?: unknown };\n if (frame.jsonrpc !== undefined) {\n if (frame.method !== TUNNEL_REGISTER_METHOD) return false;\n const params = frame.params;\n if (typeof params !== \"object\" || params === null) return false;\n return (params as { aggregate?: unknown }).aggregate === true;\n }\n return frame.type === \"register\" && frame.aggregate === true;\n}\n\n/**\n * Turns the three shapes an operator may configure into the single predicate\n * the Streamable HTTP endpoint expects.\n *\n * Absent means closed, not open: a browser origin is refused unless it was\n * named. A `RegExp` is reset before each test, because one carrying the `g`\n * flag keeps `lastIndex` between calls and would otherwise accept and refuse\n * the same origin in turn.\n */\nfunction originPredicate(allowed: AllowedOrigins | undefined): (origin: string) => boolean {\n if (!allowed) return () => false;\n if (typeof allowed === \"function\") return allowed;\n if (allowed instanceof RegExp) {\n return (origin) => {\n allowed.lastIndex = 0;\n return allowed.test(origin);\n };\n }\n const exact = new Set(allowed);\n return (origin) => exact.has(origin);\n}\n\n/**\n * Opens a transport that was handed over closed.\n *\n * `connect` is not part of `IMessageTransport`, because some transports arrive\n * already open, so it is probed for rather than required. This is the same\n * check `McpServer` makes on the transport it is given, and for the same\n * reason: testing for a concrete class would tie the caller to one\n * implementation.\n */\nfunction openTransport(transport: IMessageTransport): void {\n if (\"connect\" in transport && typeof (transport as { connect: unknown }).connect === \"function\") {\n (transport as { connect(): void }).connect();\n }\n}\n\n// ---------------------------------------------------------------------------\n// WsTunnel\n// ---------------------------------------------------------------------------\n\n/**\n * A multi-provider relay that bridges any number of MCP server instances\n * (the **providers**) with their respective MCP clients.\n *\n * ## Transport overview\n * ```\n * Provider \"<name>\"\n * ws://host/provider/<name> ← WebSocket registration\n *\n * MCP Inspector (Streamable HTTP, 2025-03-26)\n * GET http://host/<name>/mcp ← persistent SSE notification stream\n * POST http://host/<name>/mcp → JSON-RPC requests\n *\n * Claude (legacy SSE transport)\n * GET http://host/<name>/sse ← SSE notification stream\n * POST http://host/<name>/messages → JSON-RPC requests\n * ```\n *\n * Each provider gets its own isolated set of sessions, pending requests, and\n * notification streams. Multiple providers can be connected simultaneously.\n */\nexport class WsTunnel implements IBrokerContext {\n private readonly _options: IWsTunnelOptions;\n private _httpServer: http.Server | https.Server | null = null;\n private _wss: WebSocketServer | null = null;\n\n /**\n * Per-provider state, keyed by provider name.\n * Created lazily: a slot is allocated the first time any client references\n * a provider name, even before the provider WebSocket connects.\n */\n private readonly _providers = new Map<string, IProviderState>();\n\n /** Maps a multiplexed WebSocket to the set of provider names it feeds. */\n private readonly _multiplexSockets = new Map<WebSocket, Set<string>>();\n\n /**\n * Every inbound provider socket the heartbeat watches, dedicated and\n * multiplexed alike.\n *\n * An explicit collection is needed because there was none: `_providers`\n * holds only the socket that currently owns a slot (so it misses a\n * multiplex socket that has not announced a name yet), and\n * `_providerPrincipals` only has entries when provider auth is configured.\n */\n private readonly _providerSockets = new Set<WebSocket>();\n\n /**\n * Liveness of each provider socket: `true` when it answered the last ping,\n * `false` while a ping is outstanding.\n *\n * A `WeakMap` so a terminated socket needs no cleanup here, and so a socket\n * the heartbeat never saw (heartbeat disabled) reads back `undefined`,\n * which the admission check treats as \"no evidence either way\" and refuses\n * the takeover.\n */\n private readonly _alive = new WeakMap<WebSocket, boolean>();\n\n /** Heartbeat sweep timer; `null` while stopped or disabled. */\n private _heartbeatTimer: NodeJS.Timeout | null = null;\n\n /** Pending-request deadline sweep timer; `null` while stopped or disabled. */\n private _requestTimeoutTimer: NodeJS.Timeout | null = null;\n\n /**\n * Counter behind every broker-assigned request id. Monotonic per process,\n * which is all the uniqueness the pending maps need.\n */\n private _nextRequestId = 1;\n\n /**\n * Slots already warned about for answering with an id the broker never\n * issued, so a provider that does this on every frame warns once.\n */\n private readonly _unmatchedIdWarnedProviders = new Set<string>();\n\n /**\n * Slots already warned about for emitting a frame that is not JSON-RPC.\n * A provider that speaks a non-JSON dialect emits one on every message, so\n * the warning fires once per slot instead of flooding the log.\n */\n private readonly _nonJsonWarnedProviders = new Set<string>();\n\n /** Upstream providers (stdio child processes and remote URL servers), keyed by name. */\n private readonly _upstreams = new Map<string, IUpstream>();\n\n /**\n * In-process loopback transports registered as provider slots.\n * Used by the embedded broker server (`_broker`) and any other component\n * that wants to expose itself as a provider without going through a network.\n */\n private readonly _loopbackProviders = new Map<string, IMessageTransport>();\n\n /** The embedded broker MCP server, when {@link IWsTunnelOptions.enableBrokerProvider} is on. */\n private _brokerServer: IMcpServer | null = null;\n\n /** The aggregate MCP server (`_all` slot), when {@link IWsTunnelOptions.enableAggregateProvider} is on. */\n private _aggregateServer: AggregateServer | null = null;\n\n /** Provider name that the stdio client transport is bridged to, or null when disabled. */\n private _stdioClientProvider: string | null = null;\n\n /** mcp-core transport connected to the broker process stdin/stdout. */\n private _stdioClientTransport: StdioTransport | null = null;\n\n /** Timestamp of the most recent successful `start()`. */\n private _startedAt: Date | null = null;\n\n /** HTTP resource-server enforcement point, or `null` when auth is disabled. */\n private readonly _authGuard: HttpAuthGuard | null;\n\n /** Provider (engine) authenticator, or `null` when provider auth is disabled. */\n private readonly _providerAuth: IProviderAuthenticator | null;\n\n /** Compiled hierarchical authorization, or `null` for legacy behavior. */\n private readonly _authorization: IPolicyAuthorization | null;\n\n /** Stable technical-slot to hierarchical-resource mapping. */\n private readonly _slotResourceResolver: ISlotResourceResolver;\n\n /** Origin check applied by every slot's Streamable HTTP endpoint. */\n private readonly _allowedOrigins: (origin: string) => boolean;\n\n /** Principal captured at a client's WS upgrade, keyed by the upgrade request. */\n private readonly _pendingClientPrincipals = new WeakMap<IncomingMessage, IPrincipal>();\n\n /** Authenticated principal per raw WS client socket, for `_all` scope filtering. */\n private readonly _clientPrincipals = new WeakMap<WebSocket, IPrincipal>();\n\n /** Authenticated principal attached to long-lived HTTP/SSE streams. */\n private readonly _streamPrincipals = new WeakMap<ServerResponse, IPrincipal>();\n\n /** Provider principals captured during successful WebSocket upgrades. */\n private readonly _pendingProviderPrincipals = new WeakMap<IncomingMessage, IProviderPrincipal>();\n private readonly _providerPrincipals = new WeakMap<WebSocket, IProviderPrincipal>();\n\n constructor(options: IWsTunnelOptions) {\n this._options = options;\n this._authGuard = options.auth ? new HttpAuthGuard(options.auth, options.mcpPath ?? \"/mcp\") : null;\n this._providerAuth = options.providerAuth ?? null;\n this._allowedOrigins = originPredicate(options.allowedOrigins);\n this._authorization = options.authorization ?? options.auth?.authorization ?? null;\n this._slotResourceResolver =\n options.slotResourceResolver ?? this._authorization?.slotResourceResolver ?? options.auth?.slotResourceResolver ?? new DefaultSlotResourceResolver();\n }\n\n // -------------------------------------------------------------------------\n // IBrokerContext implementation\n // -------------------------------------------------------------------------\n\n get version(): string {\n return VERSION;\n }\n\n get name(): string {\n return this._options.brokerName ?? PACKAGE_NAME;\n }\n\n get startedAt(): Date | null {\n return this._startedAt;\n }\n\n get uptimeSeconds(): number {\n if (!this._startedAt) return 0;\n return Math.floor((Date.now() - this._startedAt.getTime()) / 1000);\n }\n\n get host(): string | undefined {\n return this._options.host;\n }\n\n get port(): number {\n return this._options.port;\n }\n\n get tls(): boolean {\n return !!this._options.tls;\n }\n\n get paths(): IBrokerContext[\"paths\"] {\n const o = this._options;\n return {\n provider: o.providerPath ?? \"/provider\",\n providers: o.providersPath ?? \"/providers\",\n client: o.clientPath ?? \"/\",\n mcp: o.mcpPath ?? \"/mcp\",\n sse: o.ssePath ?? \"/sse\",\n messages: o.messagesPath ?? \"/messages\",\n };\n }\n\n /**\n * What the broker enforces on its listening surface right now, for\n * `broker_diagnose`.\n *\n * The rule it feeds is the one that catches a page the broker serves itself\n * being refused by its own origin check: static files mounted, no browser\n * origin allowed. That combination now costs more than it did, because the\n * check reaches the legacy SSE endpoints too.\n */\n public getSecurityInfo(): IBrokerSecurityInfo {\n return {\n allowedOriginsConfigured: this._options.allowedOrigins !== undefined,\n clientAuthEnabled: this._authGuard !== null,\n providerAuthEnabled: this._providerAuth !== null,\n staticMountPrefixes: (this._options.staticMounts ?? []).map((m) => m.urlPrefix),\n };\n }\n\n /** Slot the stdio bridge is pinned to, or `null` when there is no bridge. */\n public getStdioBridgeTarget(): string | null {\n return this._options.stdioClient?.providerName ?? null;\n }\n\n public getProvidersInfo(): IBrokerProviderInfo[] {\n const out: IBrokerProviderInfo[] = [];\n for (const [name, state] of this._providers) {\n out.push(this._buildProviderInfo(name, state));\n }\n return out;\n }\n\n public getProviderInfo(name: string): IBrokerProviderInfo | undefined {\n const state = this._providers.get(name);\n if (!state) return undefined;\n return this._buildProviderInfo(name, state);\n }\n\n private _buildProviderInfo(name: string, state: IProviderState): IBrokerProviderInfo {\n let transport: BrokerProviderTransport;\n let connected: boolean;\n\n if (this._loopbackProviders.get(name)?.isOpen) {\n transport = \"loopback\";\n connected = true;\n } else if (this._upstreams.get(name)?.isOpen) {\n transport = \"stdio\";\n connected = true;\n } else if (state.ws?.readyState === WebSocket.OPEN) {\n transport = this._multiplexSockets.has(state.ws) ? \"ws-multiplex\" : \"ws\";\n connected = true;\n } else {\n transport = \"none\";\n connected = false;\n }\n\n return {\n name,\n transport,\n connected,\n clientCount: state.wsClients.size,\n sessionCount: state.sseSessions.size + state.httpSessions.size,\n pendingCount: state.pending.size,\n };\n }\n\n // -------------------------------------------------------------------------\n // Loopback provider registration (in-process transports)\n // -------------------------------------------------------------------------\n\n /**\n * Registers an in-process transport as a provider slot. Used by the embedded\n * broker server and may be used by application code that wants to host an\n * MCP server inside the same process without opening a real WebSocket.\n *\n * @throws if the name is already used by a stdio upstream or another loopback.\n */\n public registerLoopbackProvider(name: string, transport: IMessageTransport): void {\n if (this._loopbackProviders.has(name)) {\n throw new Error(`Loopback provider \"${name}\" is already registered.`);\n }\n if (this._upstreams.has(name)) {\n throw new Error(`Cannot register loopback \"${name}\": a stdio upstream with the same name already exists.`);\n }\n\n const state = this._getOrCreateProviderState(name);\n this._loopbackProviders.set(name, transport);\n\n transport.onMessage = (data: string) => this._routeFromProvider(state, name, data);\n transport.onClose = () => {\n this._loopbackProviders.delete(name);\n this._failProviderDisconnected(state, name);\n };\n }\n\n /**\n * Opens an in-process client to a provider slot. The returned handle can\n * issue MCP requests and receives both the responses and the provider's\n * broadcast notifications. Used by the aggregate server to fan a single\n * in-process client out to every aggregated provider.\n *\n * The slot does not need a provider attached yet, `send` returns a\n * JSON-RPC error while the provider is disconnected.\n */\n public openInternalClient(providerName: string): IInternalClient {\n const state = this._getOrCreateProviderState(providerName);\n let closed = false;\n\n const client: IInternalClient = {\n onMessage: null,\n onClose: null,\n send: (message: string): void => {\n if (closed) return;\n if (this._isProviderConnected(providerName, state)) {\n this._sendToProvider(state, providerName, this._trackRequest(state, message, { type: \"internal\", client }));\n } else if (requestIdOf(message) !== undefined) {\n client.onMessage?.(this._notConnectedPayload(providerName, message));\n }\n },\n close: (): void => {\n if (closed) return;\n closed = true;\n state.internalClients.delete(client);\n for (const [brokerId, entry] of state.pending) {\n if (entry.sink.type === \"internal\" && entry.sink.client === client) state.pending.delete(brokerId);\n }\n },\n };\n\n state.internalClients.add(client);\n return client;\n }\n\n // -------------------------------------------------------------------------\n // Public state\n // -------------------------------------------------------------------------\n\n get isListening(): boolean {\n return this._httpServer?.listening ?? false;\n }\n\n /** Total number of connected MCP clients across all providers. */\n get clientCount(): number {\n let n = 0;\n for (const s of this._providers.values()) {\n n += s.wsClients.size + s.sseSessions.size + s.httpSessions.size;\n }\n return n;\n }\n\n /** Names of all providers that currently have an active connection. */\n get providerNames(): readonly string[] {\n return [...this._providers.entries()].filter(([name, s]) => this._isProviderConnected(name, s)).map(([name]) => name);\n }\n\n /** @deprecated Check `providerNames.length > 0` instead. */\n get hasProvider(): boolean {\n return this.providerNames.length > 0;\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n /**\n * Starts the broker. Resolves once the HTTP server is listening, and\n * **rejects** when the listen fails.\n *\n * The rejection is the point: until the port is bound, a listen failure has\n * nowhere else to go. `ws` mirrors the HTTP server's `'error'` onto the\n * `WebSocketServer` from a listener it installs inside its own constructor,\n * so an unhandled one is rethrown by Node as an uncaught exception, outside\n * any caller's `await` and outside any `catch` the caller wrote.\n */\n start(): Promise<void> {\n return new Promise((resolve, reject) => {\n const handler = (req: IncomingMessage, res: ServerResponse) => this._handleHttp(req, res);\n this._httpServer = this._options.tls ? https.createServer({ cert: this._options.tls.cert, key: this._options.tls.key }, handler) : http.createServer(handler);\n // Disable perMessageDeflate: payloads may be large base64-encoded blobs\n // (snapshots, images) that are already compressed. Deflating them wastes\n // CPU without reducing size, and caused multi-second stalls in practice.\n this._wss = new WebSocketServer({ server: this._httpServer, perMessageDeflate: false, verifyClient: this._makeVerifyClient() });\n\n // Server-level errors, of which the one that actually happens is\n // `EADDRINUSE` on the very first bind.\n //\n // `settled` guards the reject: once the server is listening the\n // promise is spoken for, and a later error (a socket reset during an\n // upgrade, say) must be logged instead, or it lands as a rejection on\n // an already-resolved promise, which Node reports as unhandled.\n //\n // The same handler goes on BOTH emitters deliberately. `ws` forwards\n // the HTTP server's `'error'` to the `WebSocketServer` from a listener\n // registered inside `new WebSocketServer({ server })`; being first, it\n // rethrows an unhandled event before any listener added here to\n // `_httpServer` could run. The `_httpServer` listener is still needed\n // for the errors `ws` does not forward. `lastError` is what stops the\n // doubly delivered listen failure from being reported twice.\n let settled = false;\n let lastError: unknown = null;\n const onServerError = (err: Error): void => {\n if (err === lastError) return;\n lastError = err;\n if (settled) {\n console.error(`[broker] http/websocket server error: ${err.message}`);\n return;\n }\n settled = true;\n reject(this._listenError(err));\n };\n this._wss.on(\"error\", onServerError);\n this._httpServer.on(\"error\", onServerError);\n\n this._wss.on(\"connection\", (ws: WebSocket, req: IncomingMessage) => {\n const url = req.url ?? \"/\";\n const route = this._classifyWsRoute(url);\n\n switch (route.role) {\n case \"reject\":\n // Defence in depth. `verifyClient` refuses these before the\n // handshake completes, with the full diagnosis in the HTTP\n // body, so this branch should be unreachable: it exists so\n // the invariant \"a rejected path never reaches a handler\"\n // holds even if the hook is ever changed.\n console.warn(`[broker] ws connect path=\"${url}\" REFUSED after handshake: ${route.detail}`);\n this._closeWs(ws, 1008, route.closeReason);\n return;\n case \"multiplex-provider\":\n // Multiplexed provider: one WebSocket carries N providers via envelopes.\n this._logWsConnection(url, \"multiplex-provider\", \"(announced per envelope)\");\n this._onMultiplexProviderConnect(ws, req);\n return;\n case \"dedicated-provider\":\n this._logWsConnection(url, \"dedicated-provider\", route.slot);\n this._onProviderConnect(ws, route.slot, req);\n return;\n case \"client\":\n this._logWsConnection(url, \"client\", route.slot);\n this._onClientConnect(ws, route.slot, req);\n return;\n }\n });\n\n this._httpServer.listen(this._options.port, this._options.host ?? \"0.0.0.0\", () => {\n // Listening: from here on `onServerError` logs instead of rejecting.\n settled = true;\n\n // Both sweeps run on `unref`'d timers cleared by `stop()`, so an\n // embedder (or a test file) that starts a tunnel is never held\n // alive by them.\n this._startHeartbeat();\n this._startRequestTimeoutSweep();\n\n // Bring the aggregate `_all` slot up before any upstream connects\n // (a Streamable HTTP upstream opens synchronously on connect()).\n this._maybeStartAggregateServer();\n\n // Attach configured upstreams (stdio child processes + remote URL\n // servers). Both implement the Upstream contract, so the wiring\n // into a provider slot is identical.\n const wireUpstream = (cfg: { name: string; aggregate?: boolean }, upstream: IUpstream): void => {\n upstream.onMessage = (data) => {\n const state = this._getOrCreateProviderState(cfg.name);\n this._routeFromProvider(state, cfg.name, data);\n };\n upstream.onError = (err) => {\n console.error(`[broker] ${err.message}`);\n };\n upstream.onClose = () => {\n const state = this._providers.get(cfg.name);\n if (state) this._failProviderDisconnected(state, cfg.name);\n };\n if (cfg.aggregate) {\n upstream.onOpen = () => void this._aggregateServer?.addProvider(cfg.name);\n }\n this._upstreams.set(cfg.name, upstream);\n upstream.connect();\n };\n for (const cfg of this._options.stdioUpstreams ?? []) wireUpstream(cfg, new StdioUpstream(cfg));\n for (const cfg of this._options.remoteUpstreams ?? []) wireUpstream(cfg, new RemoteUpstream(cfg));\n\n // Attach stdio client transport if configured.\n // stdin carries Claude Desktop's JSON-RPC requests; stdout carries responses.\n if (this._options.stdioClient) {\n this._stdioClientProvider = this._options.stdioClient.providerName;\n const transport = new StdioTransport();\n this._stdioClientTransport = transport;\n transport.onMessage = (data: string): void => {\n const state = this._getOrCreateProviderState(this._stdioClientProvider!);\n this._routeFromStdioClient(state, data);\n };\n transport.onError = (err: Error): void => {\n console.error(`[broker] stdio client transport: ${err.message}`);\n };\n transport.onClose = (): void => {\n // Client disconnected: nothing to clean up; pending sinks will time out.\n };\n transport.connect();\n }\n\n this._startedAt = new Date();\n\n // Spawn the embedded broker server last so it can already report\n // accurate state in its first `broker_info` call.\n void this._maybeStartBrokerServer().then(\n () => resolve(),\n (err: unknown) => {\n console.error(\"[broker] embedded broker server failed to start:\", err);\n // Keep the tunnel up even if the introspection server fails.\n resolve();\n }\n );\n });\n });\n }\n\n /**\n * Turns a listen failure into an error whose message says what to do next.\n *\n * `EADDRINUSE` is the one that happens in practice, and the reflex it\n * triggers is usually the wrong one: another broker gets spawned on another\n * port. Two brokers do not share anything, a slot is held by exactly one\n * process, so the second instance's providers are invisible to the first\n * instance's clients. Hence the message points at attaching to the running\n * broker first, and only then at changing the port.\n */\n private _listenError(err: Error): Error {\n const host = this._options.host ?? \"0.0.0.0\";\n const port = this._options.port;\n const code = (err as NodeJS.ErrnoException).code;\n\n if (code === \"EADDRINUSE\") {\n const scheme = this._options.tls ? \"https\" : \"http\";\n // A wildcard bind is not a reachable authority; name one that is.\n const reachable = host === \"0.0.0.0\" || host === \"::\" ? \"localhost\" : host;\n return new Error(\n `Cannot listen on ${host}:${port}: the address is already in use. Another broker (or another process) already holds that port. ` +\n `If it is a broker, use it: attach clients to ${scheme}://${reachable}:${port}/<slot>/mcp and inspect it at ${scheme}://${reachable}:${port}/_broker/mcp, ` +\n `rather than starting a second instance, which would share no provider slot with the first. ` +\n `To run a second one anyway, give it a free port (MCP_BROKER_PORT, or the \\`port\\` option).`,\n { cause: err }\n );\n }\n\n if (code === \"EACCES\") {\n return new Error(\n `Cannot listen on ${host}:${port}: permission denied. Ports below 1024 require elevated privileges; ` +\n `pick a port above 1024 (MCP_BROKER_PORT, or the \\`port\\` option), or put a reverse proxy in front.`,\n { cause: err }\n );\n }\n\n if (code === \"EADDRNOTAVAIL\") {\n return new Error(\n `Cannot listen on ${host}:${port}: the host address is not available on this machine. ` +\n `Bind to \"0.0.0.0\" (every interface) or \"127.0.0.1\" (local only) via MCP_BROKER_HOST, or the \\`host\\` option.`,\n { cause: err }\n );\n }\n\n return new Error(`Cannot listen on ${host}:${port}: ${err.message}`, { cause: err });\n }\n\n /**\n * Starts the in-process MCP server that exposes the broker's own behaviors\n * (`broker_info`, `providers_list`, `provider_status`, `broker_guide`,\n * `broker_diagnose`) under the reserved provider slot `_broker`. No-op when\n * {@link IWsTunnelOptions.enableBrokerProvider} is `false`.\n */\n private async _maybeStartBrokerServer(): Promise<void> {\n if (this._options.enableBrokerProvider === false) return;\n const { server, clientTransport } = await startBrokerServer(this, {\n grammarResolverOptions: this._options.brokerGrammarResolverOptions,\n localGrammarsDir: this._options.brokerLocalGrammarsDir,\n });\n this._brokerServer = server;\n this.registerLoopbackProvider(BROKER_PROVIDER_NAME, clientTransport);\n\n // Aggregate the broker's own introspection tools into `_all`, so a stdio\n // host pinned to `_all` still reaches broker_info / providers_list /\n // provider_status alongside the other aggregated providers.\n void this._aggregateServer?.addProvider(BROKER_PROVIDER_NAME);\n }\n\n /**\n * Starts the aggregate MCP server and registers it on the reserved `_all`\n * slot. No-op when {@link IWsTunnelOptions.enableAggregateProvider} is `false`.\n */\n private _maybeStartAggregateServer(): void {\n if (this._options.enableAggregateProvider === false) return;\n try {\n const server = new AggregateServer((providerName) => this.openInternalClient(providerName));\n server.setScopeFilter(this._options.auth?.aggregateScopeFilter ?? null);\n server.setPolicyAuthorization(this._authorization);\n server.start();\n this.registerLoopbackProvider(AggregateServer.SLOT, server);\n this._aggregateServer = server;\n } catch (err) {\n console.error(`[broker] aggregate server failed to start: ${(err as Error).message}`);\n }\n }\n\n /**\n * Gracefully closes all connections and stops the HTTP server.\n */\n async stop(): Promise<void> {\n // First thing, before any `await`: a live interval keeps the event loop\n // busy, and both of these fire on sockets that are about to be torn\n // down. They are `unref`'d, so they cannot by themselves hold a process\n // open, but a test runner that checks for leaked handles counts them.\n this._stopHeartbeat();\n this._stopRequestTimeoutSweep();\n this._providerSockets.clear();\n\n // Stop the embedded broker first so it does not see its loopback close\n // as an unexpected disconnect (and to flush any pending broker responses).\n const brokerServer = this._brokerServer;\n this._brokerServer = null;\n if (brokerServer) {\n try {\n await brokerServer.stop();\n } catch {\n /* best-effort; continue tearing down */\n }\n }\n\n // Close the aggregate server so its provider sessions and internal\n // clients detach before the provider slots are torn down.\n const aggregateServer = this._aggregateServer;\n this._aggregateServer = null;\n if (aggregateServer) {\n try {\n aggregateServer.close();\n } catch {\n /* best-effort; continue tearing down */\n }\n }\n\n this._stdioClientTransport?.close();\n this._stdioClientTransport = null;\n this._stdioClientProvider = null;\n\n // Streamable HTTP sessions are torn down by the endpoint that owns them,\n // not by ending their responses here: `closeAll` runs each session's\n // `stop`, which is what empties `httpSessions`.\n await Promise.all([...this._providers.values()].map((state) => state.httpEndpoint?.closeAll() ?? Promise.resolve()));\n\n return new Promise((resolve, reject) => {\n for (const state of this._providers.values()) {\n for (const res of state.sseSessions.values()) res.end();\n state.sseSessions.clear();\n state.httpSessions.clear();\n state.httpEndpoint = null;\n for (const client of state.wsClients) client.close();\n state.wsClients.clear();\n state.ws?.close();\n }\n this._providers.clear();\n this._multiplexSockets.clear();\n for (const upstream of this._upstreams.values()) upstream.close();\n this._upstreams.clear();\n for (const loopback of this._loopbackProviders.values()) loopback.close();\n this._loopbackProviders.clear();\n this._startedAt = null;\n this._wss?.close();\n\n const httpServer = this._httpServer;\n if (!httpServer) {\n // Never started: there is no close callback coming, and waiting\n // for one would hang the caller's teardown.\n resolve();\n return;\n }\n httpServer.close((err) => {\n // A tunnel whose `start()` rejected (the port was already taken)\n // has a server object that never listened, and closing that one\n // answers `ERR_SERVER_NOT_RUNNING`. Failing the teardown on it\n // would replace the real diagnosis with a meaningless one, in the\n // `finally` where the caller is trying to clean up after the first.\n if (err && (err as NodeJS.ErrnoException).code !== \"ERR_SERVER_NOT_RUNNING\") reject(err);\n else resolve();\n });\n });\n }\n\n // -------------------------------------------------------------------------\n // Provider liveness (heartbeat) and slot takeover\n // -------------------------------------------------------------------------\n\n /** Effective heartbeat period in ms; `0` means the heartbeat is off. */\n private _heartbeatIntervalMs(): number {\n const configured = this._options.providerHeartbeatIntervalMs;\n return Math.max(0, configured ?? DEFAULT_PROVIDER_HEARTBEAT_MS);\n }\n\n /** Effective per-request deadline in ms; `0` means requests never expire. */\n private _requestTimeoutMs(): number {\n const configured = this._options.providerRequestTimeoutMs;\n return Math.max(0, configured ?? DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS);\n }\n\n /**\n * Starts watching every provider socket for a missed pong.\n *\n * `unref()` is not cosmetic: without it this interval alone keeps the Node\n * event loop alive, so every test file that starts a tunnel would hang on\n * teardown, and an embedder's process would refuse to exit.\n */\n private _startHeartbeat(): void {\n const interval = this._heartbeatIntervalMs();\n if (interval === 0) return;\n this._heartbeatTimer = setInterval(() => this._sweepHeartbeats(), interval);\n this._heartbeatTimer.unref?.();\n }\n\n private _stopHeartbeat(): void {\n if (!this._heartbeatTimer) return;\n clearInterval(this._heartbeatTimer);\n this._heartbeatTimer = null;\n }\n\n /**\n * One heartbeat round: terminate whoever did not answer the previous ping,\n * then ping everybody still standing.\n *\n * The two-phase shape is what gives a provider a full interval to reply,\n * and it is why {@link _alive} means \"answered since the last sweep\" rather\n * than \"is connected\".\n */\n private _sweepHeartbeats(): void {\n const interval = this._heartbeatIntervalMs();\n for (const ws of [...this._providerSockets]) {\n if (ws.readyState !== WebSocket.OPEN) {\n this._providerSockets.delete(ws);\n continue;\n }\n if (this._alive.get(ws) === false) {\n const slots = this._slotsOfSocket(ws);\n console.warn(\n `[broker] provider socket for ${slots} did not answer a WebSocket ping within ${interval}ms; terminating it and freeing the slot. ` +\n `The provider process, tab or network path is gone. It may reconnect immediately. ` +\n `If this provider is alive but slow, raise providerHeartbeatIntervalMs (or set it to 0 to disable the heartbeat).`\n );\n this._providerSockets.delete(ws);\n ws.terminate();\n continue;\n }\n this._alive.set(ws, false);\n try {\n ws.ping();\n } catch (err) {\n // A socket that died between the readyState check and the ping.\n // Nothing to diagnose: the close handler is already on its way.\n this._providerSockets.delete(ws);\n void err;\n }\n }\n }\n\n /**\n * Puts one accepted provider socket under the heartbeat.\n *\n * No-op when the heartbeat is disabled, which is what keeps\n * {@link _alive} empty and makes the admission check fall back to refusing\n * every takeover: with no liveness evidence, evicting the incumbent would\n * be a guess.\n */\n private _watchProviderSocket(ws: WebSocket): void {\n if (this._heartbeatIntervalMs() === 0) return;\n this._alive.set(ws, true);\n this._providerSockets.add(ws);\n ws.on(\"pong\", () => this._alive.set(ws, true));\n ws.on(\"close\", () => this._providerSockets.delete(ws));\n }\n\n /** Human-readable list of the slots one provider socket currently serves. */\n private _slotsOfSocket(ws: WebSocket): string {\n const announced = this._multiplexSockets.get(ws);\n if (announced) return announced.size > 0 ? `multiplexed slots [${[...announced].join(\", \")}]` : \"a multiplexed socket that announced no slot\";\n const owned = [...this._providers.entries()].filter(([, state]) => state.ws === ws).map(([name]) => name);\n return owned.length > 0 ? `slot \"${owned.join('\", \"')}\"` : \"a slot it no longer owns\";\n }\n\n /**\n * Decides whether a newly connected provider socket may take the slot\n * `name`, evicting the incumbent when it is allowed to.\n *\n * Returns `null` when the newcomer is admitted, or the refusal otherwise:\n * `detail` is the full diagnosis for the log and for the envelope the\n * multiplexed path can carry, `closeReason` the same thing squeezed into the\n * 123 bytes RFC 6455 allows on a close frame, with the actionable part\n * first so truncation eats the slot name (which the peer already knows)\n * rather than the instruction.\n *\n * See {@link ProviderTakeoverMode} for what each mode means and why\n * `\"always\"` is gated on provider authentication.\n */\n private _claimSlot(name: string, ws: WebSocket): { detail: string; closeReason: string } | null {\n const incumbent = this._providers.get(name)?.ws ?? null;\n if (!incumbent || incumbent === ws || incumbent.readyState !== WebSocket.OPEN) return null;\n\n const mode: ProviderTakeoverMode = this._options.providerTakeover ?? \"liveness\";\n\n if (mode === \"always\") {\n if (this._sameProviderPrincipal(incumbent, ws)) {\n console.warn(`[broker] provider \"${name}\": takeover mode \"always\", the incumbent socket is being terminated in favor of the new one from the same principal.`);\n incumbent.terminate();\n return null;\n }\n // Not a refusal on its own: fall through to the liveness rule. Saying\n // so out loud matters, because the operator asked for \"always\" and is\n // entitled to know why they did not get it.\n console.warn(\n `[broker] provider \"${name}\": takeover mode \"always\" is not honored here and the broker fell back to \"liveness\". ` +\n `Unconditional takeover is only safe when providerAuth is configured AND the new socket authenticated as the same principal as the incumbent; ` +\n `otherwise anyone able to reach the provider URL could evict the real provider at will. Configure providerAuth (withProviderSecret) to enable it.`\n );\n }\n\n if (mode !== \"reject\" && this._alive.get(incumbent) === false) {\n console.warn(`[broker] provider \"${name}\": the incumbent socket missed its last heartbeat, so it is terminated and the new connection takes the slot.`);\n incumbent.terminate();\n return null;\n }\n\n const heartbeat = this._heartbeatIntervalMs();\n const why =\n mode === \"reject\"\n ? `providerTakeover is \"reject\", so a live slot is never handed over.`\n : heartbeat === 0\n ? `The heartbeat is disabled (providerHeartbeatIntervalMs: 0), so the broker has no evidence the incumbent is dead and will not evict it.`\n : `The incumbent answered the last heartbeat, so it is treated as alive.`;\n const recovery =\n heartbeat === 0\n ? `Enable the heartbeat (providerHeartbeatIntervalMs) so a dead socket frees its slot on its own`\n : `wait up to ${heartbeat}ms for the heartbeat to notice a dead socket and reconnect`;\n return {\n detail:\n `Provider \"${name}\" is already connected. ${why} ` +\n `If the previous instance really is gone, ${recovery}, close the old socket cleanly from the provider side, or publish on a different slot name. ` +\n `Call provider_status on the _broker slot to see which socket holds it.`,\n closeReason: `Slot already held by a live provider; call provider_status on _broker. Slot: \"${name}\"`,\n };\n }\n\n /**\n * `true` when two provider sockets authenticated as the same principal.\n *\n * Deliberately `false` when provider auth is off: with no authenticator\n * there are no principals to compare, and treating \"both anonymous\" as\n * \"the same provider\" is exactly the spoofing primitive the gate exists to\n * prevent.\n */\n private _sameProviderPrincipal(a: WebSocket, b: WebSocket): boolean {\n if (!this._providerAuth) return false;\n const left = this._providerPrincipals.get(a);\n const right = this._providerPrincipals.get(b);\n return left !== undefined && right !== undefined && left.id === right.id;\n }\n\n /** Closes a socket with a reason RFC 6455 actually allows on the wire. */\n private _closeWs(ws: WebSocket, code: number, reason: string): void {\n ws.close(code, truncateReason(reason));\n }\n\n // -------------------------------------------------------------------------\n // Pending requests: correlation and deadlines\n // -------------------------------------------------------------------------\n\n /**\n * Registers one outbound request against a slot and returns the frame to\n * put on the wire, with the client's JSON-RPC id replaced by a\n * broker-assigned one.\n *\n * The rewrite is the fix for a cross-client response leak. `state.pending`\n * is one map per **slot**, written from five different ingresses (raw WS,\n * legacy SSE, Streamable HTTP, the stdio bridge, in-process clients), and\n * it used to be keyed by the id the client chose. Two clients on one slot\n * that both start numbering at 1 (MCP Inspector plus Claude, the pairing\n * the architecture doc explicitly advertises) therefore shared one entry:\n * the second write replaced the first, one client received the other's\n * result, and the overwritten request hung forever with no error. Rewriting\n * also stops the provider from seeing two concurrent requests with the same\n * id, which it has no way to answer correctly either.\n *\n * Invisible to conforming clients: {@link _routeFromProvider} restores the\n * original id before the answer is delivered.\n *\n * Frames with no usable id (notifications) and JSON-RPC batches (an array,\n * which has no top-level id) are returned untouched and untracked, exactly\n * as before.\n */\n private _trackRequest(state: IProviderState, frame: string, sink: ResponseSink): string {\n const message = parseObjectFrame(frame);\n if (!message) return frame;\n const clientId = message.id;\n if (typeof clientId !== \"string\" && typeof clientId !== \"number\") return frame;\n\n const brokerId = `${BROKER_REQUEST_ID_PREFIX}${this._nextRequestId++}`;\n const timeout = this._requestTimeoutMs();\n state.pending.set(brokerId, { sink, clientId, expiresAt: timeout > 0 ? Date.now() + timeout : 0 });\n message.id = brokerId;\n return JSON.stringify(message);\n }\n\n /** Delivers one already-addressed frame to the sink that is waiting for it. */\n private _deliverToSink(state: IProviderState, sink: ResponseSink, data: string): void {\n switch (sink.type) {\n case \"ws\":\n if (sink.socket.readyState === WebSocket.OPEN) sink.socket.send(data);\n return;\n case \"sse\": {\n const sseRes = state.sseSessions.get(sink.sessionId);\n if (sseRes) this._sendSseEvent(sseRes, data);\n return;\n }\n case \"http-session\":\n // The session transport decides whether this answers a held-open\n // POST or travels on the GET stream: it correlates by id.\n state.httpSessions.get(sink.sessionId)?.transport.send(data);\n return;\n case \"stdio\":\n this._stdioClientTransport?.send(data);\n return;\n case \"internal\":\n sink.client.onMessage?.(data);\n return;\n }\n }\n\n /**\n * Starts the sweep that fails requests a provider never answered.\n *\n * Same `unref()` requirement as the heartbeat. The period is derived from\n * the deadline rather than fixed, so a short timeout (a test, or a\n * latency-sensitive deployment) is still honored roughly on time instead of\n * being rounded up to the next sweep minutes later.\n */\n private _startRequestTimeoutSweep(): void {\n const timeout = this._requestTimeoutMs();\n if (timeout === 0) return;\n const period = Math.max(250, Math.min(5_000, Math.floor(timeout / 2)));\n this._requestTimeoutTimer = setInterval(() => this._sweepPendingTimeouts(), period);\n this._requestTimeoutTimer.unref?.();\n }\n\n private _stopRequestTimeoutSweep(): void {\n if (!this._requestTimeoutTimer) return;\n clearInterval(this._requestTimeoutTimer);\n this._requestTimeoutTimer = null;\n }\n\n /**\n * Fails every request whose deadline has passed.\n *\n * Until this existed a pending entry was released only by a matching\n * response, a provider disconnect, or the client's own close, so a provider\n * that stayed connected and simply never answered (a browser tab throttled\n * in the background is the ordinary case) left the caller waiting with\n * nothing to release it and no trace anywhere. A named error is strictly\n * better than a hang.\n */\n private _sweepPendingTimeouts(): void {\n const timeout = this._requestTimeoutMs();\n if (timeout === 0) return;\n const now = Date.now();\n\n for (const [name, state] of this._providers) {\n for (const [brokerId, entry] of state.pending) {\n if (entry.expiresAt === 0 || entry.expiresAt > now) continue;\n state.pending.delete(brokerId);\n console.warn(\n `[broker] provider \"${name}\" did not answer a request within ${timeout}ms; the caller was sent a timeout error. ` +\n `The socket is still connected, so this is the provider not replying rather than a disconnect: check that its MCP message handler was installed BEFORE the transport connected, ` +\n `that it echoes the JSON-RPC id it was given, and that the page hosting it is not throttled in a background tab. ` +\n `Raise providerRequestTimeoutMs for genuinely long-running tools.`\n );\n this._deliverToSink(\n state,\n entry.sink,\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: entry.clientId,\n error: {\n code: -32000,\n message:\n `Provider \"${name}\" did not respond within ${timeout}ms. The provider socket is still connected but sent no answer for this request. ` +\n `Call broker_diagnose on the _broker slot for the live state of this slot.`,\n },\n })\n );\n }\n }\n }\n\n private _authorizationSubject(principal: IPrincipal | null): IAuthorizationSubject {\n if (principal?.subject) return principal.subject;\n if (!principal) return { ids: [] };\n try {\n return (\n this._authorization?.subjectMapper.map(principal.claims) ?? {\n ids: [],\n claims: principal.claims,\n }\n );\n } catch (error) {\n // Both branches are logged, deliberately. A `SubjectMappingError` used\n // to be swallowed here, which made the single most likely\n // misconfiguration the one case that produced no output at all, while\n // the empty subject returned below makes the policy engine deny every\n // request from this caller. It is a configuration fault, not attacker\n // noise, and the HTTP path already diagnoses it out loud (a 403 saying\n // \"Malformed configured JWT subject claim\", see `auth/http.auth.ts`).\n const kind = error instanceof SubjectMappingError ? \"malformed configured JWT subject claim\" : \"subject mapping failed\";\n console.error(\n `[broker] authorization ${kind}: ${(error as Error).message}` +\n ` -- every request from this caller is denied while this stands. Check authorization.subjectMapping against the claims the token actually carries.`\n );\n return { ids: [], claims: principal.claims };\n }\n }\n\n private _auditDecision(\n subject: IAuthorizationSubject,\n slot: string,\n resource: ResourcePath | undefined,\n capability: string | undefined,\n tool: string | undefined,\n decision: IAuthorizationDecision\n ): void {\n const authorization = this._authorization;\n if (!authorization || (decision.allowed && !authorization.audit.logAllowed)) return;\n writeAuthorizationAuditEvent(\n makeAuthorizationAuditEvent(\n {\n subject,\n slot,\n resource,\n capability,\n provider: slot,\n tool,\n },\n decision\n )\n );\n }\n\n /**\n * Applies hierarchical policy to the MCP operations carried in one\n * JSON-RPC frame. `_all` performs provider-specific checks internally.\n */\n private _authorizeMcpFrame(providerName: string, data: string, principal: IPrincipal | null): boolean {\n const authorization = this._authorization;\n if (!authorization || providerName === AggregateServer.SLOT) return true;\n\n const subject = this._authorizationSubject(principal);\n const resource = this._slotResourceResolver.resolve(providerName);\n if (!resource) {\n const decision: IAuthorizationDecision = { allowed: false, reason: \"unknown-resource\" };\n this._auditDecision(subject, providerName, undefined, undefined, undefined, decision);\n return false;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data) as unknown;\n } catch {\n return true;\n }\n const operations = Array.isArray(parsed) ? parsed : [parsed];\n for (const value of operations) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) continue;\n const operation = value as Readonly<{ method?: string; params?: unknown }>;\n // Hoisted out of the `try` so the failure path can still name the\n // capability when the throw came from the engine rather than from the\n // classifier.\n let capability: string | undefined;\n try {\n const classified = authorization.capabilityClassifier.classify(operation, resource, providerName);\n if (!classified) continue;\n capability = classified.capability;\n const decision = authorization.engine.authorize({\n subject,\n capability: classified.capability,\n resource,\n provider: providerName,\n tool: classified.tool,\n });\n this._auditDecision(subject, providerName, resource, classified.capability, classified.tool, decision);\n if (!decision.allowed) return false;\n } catch (error) {\n // The evaluation itself threw: a classifier or engine fault, not a\n // policy miss. The two call for opposite fixes, and the audit event\n // used to claim \"no-matching-grant\", which sends the operator off\n // to write grants that can never help. So say what actually\n // happened, with everything needed to reproduce it.\n console.error(\n `[broker] policy evaluation error on slot \"${providerName}\": ${(error as Error).message}` +\n ` -- subject=[${subject.ids.join(\", \") || \"(none)\"}] resource=\"${resource.value}\" capability=\"${capability ?? \"(unclassified)\"}\" method=\"${operation.method ?? \"(none)\"}\".` +\n ` The request is denied. This is a fault in the authorization configuration or in the frame, not a missing grant.`\n );\n // \"evaluation-error\", not \"no-matching-grant\": nothing was\n // decided here, the request is denied because that is the safe\n // answer to a fault.\n const decision: IAuthorizationDecision = { allowed: false, reason: \"evaluation-error\" };\n this._auditDecision(subject, providerName, resource, capability, undefined, decision);\n return false;\n }\n }\n return true;\n }\n\n private _policyDeniedPayload(data: string): string {\n let id: string | number | null = null;\n try {\n const parsed = JSON.parse(data) as { id?: unknown };\n if (typeof parsed.id === \"string\" || typeof parsed.id === \"number\" || parsed.id === null) {\n id = parsed.id;\n }\n } catch {\n // A malformed frame has no usable request id.\n }\n return JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32001, message: \"Forbidden\" },\n });\n }\n\n /** The JSON-RPC error returned when the slot has nobody behind it. */\n private _notConnectedPayload(providerName: string, frame: string): string {\n return JSON.stringify({\n jsonrpc: \"2.0\",\n id: requestIdOf(frame) ?? null,\n error: { code: -32000, message: `Provider \"${providerName}\" not connected` },\n });\n }\n\n // -------------------------------------------------------------------------\n // HTTP dispatcher\n // -------------------------------------------------------------------------\n\n private _handleHttp(req: IncomingMessage, res: ServerResponse): void {\n const method = req.method ?? \"GET\";\n const rawUrl = (req.url ?? \"/\").split(\"?\")[0];\n\n // CORS\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", req.headers[\"access-control-request-headers\"] ?? \"Content-Type, Accept, Mcp-Session-Id\");\n res.setHeader(\"Access-Control-Expose-Headers\", \"Mcp-Session-Id\");\n\n if (method === \"OPTIONS\") {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // Samples index (no provider prefix)\n const samplesIndexPath = this._options.samplesIndexPath ?? \"/__samples_index__\";\n if (method === \"GET\" && rawUrl === samplesIndexPath) {\n this._handleSamplesIndex(res);\n return;\n }\n\n // Protected Resource Metadata (RFC 9728), public discovery data, served\n // unauthenticated so a client can find the authorization server after a 401.\n if (this._authGuard && method === \"GET\") {\n const metaSlot = this._authGuard.matchMetadataRequest(rawUrl);\n if (metaSlot) {\n res.writeHead(200, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify(this._authGuard.metadataFor(metaSlot)));\n return;\n }\n }\n\n // Route /<providerName>/<endpoint>\n const route = this._parseProviderRoute(rawUrl);\n if (route) {\n const { providerName, endpoint } = route;\n const kind = this._mcpEndpointKind(endpoint, method);\n if (kind) {\n // The `mcp` kind is left out on purpose: `StreamableHttpEndpoint`\n // already runs the identical check, with the same predicate.\n if ((kind === \"sse-connect\" || kind === \"sse-message\") && !this._sseOriginAllowed(req, res, providerName, kind)) return;\n\n if (this._authGuard) {\n // Gate on a valid bearer token issued for this slot before touching\n // the provider. On failure, emit an RFC 9728 challenge / 500.\n const guard = this._authGuard;\n void guard.authorize(req, providerName).then(\n (principal) => this._dispatchMcpEndpoint(kind, req, res, providerName, principal),\n (err: unknown) => this._handleAuthFailure(guard, res, providerName, err)\n );\n } else {\n this._dispatchMcpEndpoint(kind, req, res, providerName, null);\n }\n return;\n }\n }\n\n // Static files\n if (this._options.staticMounts?.length) {\n this._serveStatic(req, res);\n } else {\n res.writeHead(404);\n res.end();\n }\n }\n\n /**\n * Applies the browser-origin check to the legacy SSE pair, answering `403`\n * and returning `false` when the origin is refused.\n *\n * This closes a hole, and it is the one behavior change in this release a\n * browser page can notice. `allowedOrigins` reached exactly one place, the\n * Streamable HTTP endpoint, so `/<slot>/sse` and `/<slot>/messages` were\n * open to every page on the machine: `Access-Control-Allow-Origin: *` is\n * set unconditionally a few lines above, and a POST of JSON to\n * `/<slot>/messages` is a CORS *simple* request, so any page could open an\n * `EventSource`, read the session id off the `endpoint` event, and drive the\n * broker. That is verbatim the attack the origin check exists to stop.\n *\n * The contract of the check is preserved exactly: a request carrying **no**\n * `Origin` always passes, which is every non-browser client (Claude Desktop,\n * Inspector, the server-side SDKs), and an `Origin` passes only if\n * `allowedOrigins` names it. The same predicate object is used as for\n * `/<slot>/mcp`, so the two endpoints cannot drift apart.\n */\n private _sseOriginAllowed(req: IncomingMessage, res: ServerResponse, providerName: string, kind: McpEndpointKind): boolean {\n const origin = req.headers.origin;\n // A request with no Origin cannot come from a browser, so it is not this\n // check's business and passes straight through.\n if (typeof origin !== \"string\" || origin.length === 0) return true;\n if (this._allowedOrigins(origin)) return true;\n\n const endpoint = kind === \"sse-connect\" ? `/${providerName}${this._options.ssePath ?? \"/sse\"}` : `/${providerName}${this._options.messagesPath ?? \"/messages\"}`;\n const configured = this._options.allowedOrigins !== undefined;\n const description = configured\n ? `Origin \"${origin}\" is not allowed to reach \"${endpoint}\". It is compared verbatim against the configured allowedOrigins, so a different scheme, port or a trailing slash does not match. ` +\n `Add the exact origin the browser sends (MCP_BROKER_ALLOWED_ORIGINS, the \\`allowedOrigins\\` config key, or WsTunnelBuilder.withAllowedOrigins).`\n : `Origin \"${origin}\" is refused because no browser origin is allowed: \\`allowedOrigins\\` is unset, and the default is closed. ` +\n `A page served by this broker is not exempt, its origin has to be listed too. ` +\n `Set MCP_BROKER_ALLOWED_ORIGINS (the \\`allowedOrigins\\` config key, or WsTunnelBuilder.withAllowedOrigins) to \"${origin}\" to open it, and only then.`;\n\n console.warn(`[broker] refused SSE request on \"${endpoint}\": ${description}`);\n res.writeHead(403, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify({ error: \"invalid_origin\", error_description: description }));\n return false;\n }\n\n /**\n * Parses `/<providerName>/<endpoint>` from a URL path.\n * Returns `null` if the URL does not match this two-segment pattern.\n */\n private _parseProviderRoute(rawUrl: string): { providerName: string; endpoint: string } | null {\n const parts = rawUrl.split(\"/\").filter(Boolean);\n if (parts.length !== 2) return null;\n const providerName = decodeURIComponent(parts[0]);\n const endpoint = decodeURIComponent(parts[1]);\n if (!providerName || !endpoint) return null;\n return { providerName, endpoint };\n }\n\n /**\n * Classifies a `(endpoint, method)` pair as one of the four MCP/SSE client\n * handlers, or `null` when it is not a client transport request (the caller\n * then falls through to static-file serving, preserving prior behavior).\n */\n private _mcpEndpointKind(endpoint: string, method: string): McpEndpointKind | null {\n const mcpSuffix = (this._options.mcpPath ?? \"/mcp\").replace(/^\\//, \"\");\n const sseSuffix = (this._options.ssePath ?? \"/sse\").replace(/^\\//, \"\");\n const messagesSuffix = (this._options.messagesPath ?? \"/messages\").replace(/^\\//, \"\");\n // GET, POST and DELETE all belong to the Streamable HTTP state machine.\n if (endpoint === mcpSuffix) return \"mcp\";\n if (endpoint === sseSuffix && method === \"GET\") return \"sse-connect\";\n if (endpoint === messagesSuffix && method === \"POST\") return \"sse-message\";\n return null;\n }\n\n /** Routes an already-authorized (or auth-disabled) request to its handler. */\n private _dispatchMcpEndpoint(kind: McpEndpointKind, req: IncomingMessage, res: ServerResponse, providerName: string, principal: IPrincipal | null): void {\n switch (kind) {\n case \"mcp\":\n this._handleStreamableHttp(req, res, providerName, principal);\n return;\n case \"sse-connect\":\n this._handleSseConnect(req, res, providerName, principal);\n return;\n case \"sse-message\":\n this._handleSseMessage(req, res, providerName, principal);\n return;\n }\n }\n\n /** Turns a rejected {@link HttpAuthGuard.authorize} into an HTTP response. */\n private _handleAuthFailure(guard: HttpAuthGuard, res: ServerResponse, providerName: string, err: unknown): void {\n if (err instanceof AuthError) {\n guard.writeChallenge(res, providerName, err);\n return;\n }\n // Not a token failure (e.g. the JWKS endpoint is unreachable), surface a\n // 500 rather than a misleading 401.\n console.error(`[broker] token validation error for \"${providerName}\":`, err);\n res.writeHead(500, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify({ error: \"server_error\" }));\n }\n\n /**\n * Decides, from the URL alone, what one WebSocket upgrade is asking for.\n *\n * One function rather than the two `startsWith` chains this used to be, one\n * in the connection handler and one in `verifyClient`. They agreed by\n * coincidence, and a disagreement would mean a socket authenticated as one\n * role and then served as another.\n *\n * The three refusals are paths that cannot work whatever is behind them:\n * a provider URL with no slot name (which used to mint a slot literally\n * named `(unnamed)` that nothing could ever address) and a slot-scoped\n * provider URL with more than one segment (`/provider/a/b`, which aliases\n * the `%2F`-encoded spelling of the same slot, so refusing it removes\n * nothing and forces one spelling).\n *\n * What is deliberately **not** refused: a slot name that matches nothing\n * configured. Claiming a free slot by connecting to it is how a provider\n * registers, so an unknown name is the normal case, not an error.\n */\n private _classifyWsRoute(url: string): WsRouteClassification {\n const providerPath = this._options.providerPath ?? \"/provider\";\n const providersPath = this._options.providersPath ?? \"/providers\";\n\n // Exact match plus query string: the multiplex endpoint takes its slot\n // names from the envelopes, never from the path.\n if (url === providersPath || url.startsWith(providersPath + \"?\")) return { role: \"multiplex-provider\" };\n\n // `${providerPath}?x=1` is deliberately absent from this test: it has\n // always been served as a client on a slot named after the path, and\n // narrowing that is not this change's business.\n if (url === providerPath) {\n return {\n role: \"reject\",\n detail:\n `\"${providerPath}\" is the provider path PREFIX, not an endpoint. A slot-scoped provider appends its slot name: \"${providerPath}/<name>\". ` +\n `If you meant the shared multiplexed socket, that is \"${providersPath}\" (exact path, one socket for many slots, envelope framing). ` +\n `Connecting here used to occupy a slot literally named \"(unnamed)\", which no client could address.`,\n closeReason: `Missing slot name: connect to ${providerPath}/<name>, or to ${providersPath}`,\n };\n }\n\n if (url.startsWith(providerPath + \"/\")) {\n const raw = url.slice(providerPath.length + 1).split(\"?\")[0];\n if (raw.length === 0) {\n return {\n role: \"reject\",\n detail: `\"${url}\" has an empty slot name. Append the slot the provider publishes: \"${providerPath}/<name>\".`,\n closeReason: `Empty slot name: connect to ${providerPath}/<name>`,\n };\n }\n // Tested on the RAW segment, before decoding: hierarchical slot names\n // are legitimate and travel percent-encoded (`%2Fsite-a%2Fline-3`),\n // so decoding first would refuse exactly the shape the authorization\n // layer is built around.\n if (raw.includes(\"/\")) {\n return {\n role: \"reject\",\n detail:\n `\"${url}\" has more than one path segment after \"${providerPath}/\". A slot-scoped provider URL carries exactly one segment. ` +\n `A slot name containing \"/\" must be percent-encoded: \"${providerPath}/${encodeURIComponent(safeDecode(raw))}\". ` +\n `Both spellings resolve to the same slot, so only the encoded one is accepted.`,\n closeReason: `Too many path segments: percent-encode the slot name after ${providerPath}/`,\n };\n }\n return { role: \"dedicated-provider\", slot: safeDecode(raw) };\n }\n\n // Raw WS MCP client: URL is \"/<slot>\" or \"/\".\n return { role: \"client\", slot: safeDecode(url.replace(/^\\//, \"\").split(\"?\")[0]) };\n }\n\n /**\n * Builds the `ws` verifyClient hook, which decides every WebSocket upgrade\n * before the connection is accepted, returning a real HTTP status during\n * the handshake rather than a post-handshake close:\n *\n * - Paths that cannot work are refused with `400` and the full reason as the\n * response body (see {@link _classifyWsRoute}).\n * - **Raw MCP clients** (`/<slot>`) are gated by the OAuth 2.1 resource\n * server ({@link _authGuard}) with the RFC 9728 `WWW-Authenticate` challenge.\n * - **Providers** (`/provider/<slot>`, `/providers`) are gated by the\n * {@link _providerAuth} shared-secret / custom authenticator.\n *\n * Each authentication side is independent: a branch with no authenticator\n * configured is let through unchanged. The hook is always installed now,\n * because the path check applies whether or not anything is authenticated.\n */\n private _makeVerifyClient(): VerifyClientCallbackAsync {\n const guard = this._authGuard;\n const providerAuth = this._providerAuth;\n\n return (info, cb) => {\n const url = info.req.url ?? \"/\";\n const route = this._classifyWsRoute(url);\n\n if (route.role === \"reject\") {\n // `ws` writes this string as the body of the refused upgrade, so\n // a Node client reads it off `unexpected-response`. A browser\n // gets no status from script, which is why the connect log line\n // carries the same diagnosis on the server side.\n console.warn(`[broker] ws upgrade REFUSED path=\"${url}\": ${route.detail}`);\n cb(false, 400, route.detail);\n return;\n }\n\n if (route.role === \"multiplex-provider\" || route.role === \"dedicated-provider\") {\n // Provider (engine) upgrade, shared-secret / custom authenticator.\n if (!providerAuth) {\n cb(true);\n return;\n }\n const slot = route.role === \"dedicated-provider\" ? route.slot : undefined;\n Promise.resolve(providerAuth.authenticate(info.req, slot)).then(\n (rawResult) => {\n const result = normalizeProviderAuthentication(rawResult);\n if (!result.authenticated) {\n cb(false, 401, \"Unauthorized\", { \"WWW-Authenticate\": 'Bearer realm=\"provider\"' });\n return;\n }\n if (slot !== undefined) {\n const resource = this._slotResourceResolver.resolve(slot);\n if (!resource || !providerMayPublish(result.principal, resource)) {\n this._logProviderRegistration(result.principal, slot, resource, false);\n cb(false, 403, \"Forbidden\");\n return;\n }\n }\n this._pendingProviderPrincipals.set(info.req, result.principal);\n cb(true);\n },\n () => {\n console.error(`[broker] provider authentication error for \"${slot ?? \"(multiplex)\"}\".`);\n cb(false, 500, \"server_error\");\n }\n );\n return;\n }\n\n // Raw WS MCP client upgrade, OAuth 2.1 resource server.\n if (!guard) {\n cb(true);\n return;\n }\n const slot = decodeURIComponent(url.replace(/^\\//, \"\").split(\"?\")[0]);\n void guard.authorize(info.req, slot).then(\n (principal) => {\n // Stash the principal so _onClientConnect can bind it to the socket.\n this._pendingClientPrincipals.set(info.req, principal);\n cb(true);\n },\n (err: unknown) => {\n if (err instanceof AuthError) {\n cb(false, err.status, err.code, { \"WWW-Authenticate\": guard.challengeHeader(slot, err) });\n } else {\n console.error(`[broker] token validation error for WS client \"${slot}\":`, err);\n cb(false, 500, \"server_error\");\n }\n }\n );\n };\n }\n\n // -------------------------------------------------------------------------\n // MCP / SSE transport (per provider)\n // -------------------------------------------------------------------------\n\n /**\n * Handles `GET /<providerName>/sse`, opens a long-lived SSE stream for Claude.\n * Sends an `endpoint` event so Claude knows where to POST its requests.\n */\n private _handleSseConnect(req: IncomingMessage, res: ServerResponse, providerName: string, principal: IPrincipal | null): void {\n const sessionId = randomUUID();\n const messagesSuffix = (this._options.messagesPath ?? \"/messages\").replace(/^\\//, \"\");\n const messagesUrl = `/${encodeURIComponent(providerName)}/${messagesSuffix}`;\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n });\n res.write(`event: endpoint\\ndata: ${messagesUrl}?sessionId=${sessionId}\\n\\n`);\n\n const state = this._getOrCreateProviderState(providerName);\n state.sseSessions.set(sessionId, res);\n if (principal) this._streamPrincipals.set(res, principal);\n\n req.on(\"close\", () => {\n state.sseSessions.delete(sessionId);\n for (const [brokerId, entry] of state.pending) {\n if (entry.sink.type === \"sse\" && entry.sink.sessionId === sessionId) state.pending.delete(brokerId);\n }\n });\n }\n\n /**\n * Handles `POST /<providerName>/messages?sessionId=…`, receives a JSON-RPC\n * request from Claude and forwards it to the provider.\n * Always responds 202 Accepted; the real response arrives over SSE.\n */\n private _handleSseMessage(req: IncomingMessage, res: ServerResponse, providerName: string, principal: IPrincipal | null): void {\n const params = new URL(req.url ?? \"\", \"http://localhost\").searchParams;\n const sessionId = params.get(\"sessionId\") ?? \"\";\n const state = this._getOrCreateProviderState(providerName);\n\n if (!state.sseSessions.has(sessionId)) {\n res.writeHead(400, { \"Content-Type\": \"text/plain\" });\n res.end(\"Unknown or expired session\");\n return;\n }\n\n let body = \"\";\n req.on(\"data\", (chunk: Buffer) => {\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n if (!this._authorizeMcpFrame(providerName, body, principal)) {\n res.writeHead(403, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(this._policyDeniedPayload(body));\n return;\n }\n if (this._isProviderConnected(providerName, state)) {\n // Tracked only once the frame is actually on its way out: an\n // entry added before the connectivity check has nothing to\n // answer it and would pin that id until the slot next\n // disconnects (the raw-WS path had the same ordering bug).\n this._sendToProvider(state, providerName, this._trackRequest(state, body, { type: \"sse\", sessionId }), principal);\n } else {\n const sseRes = state.sseSessions.get(sessionId);\n if (sseRes) this._sendSseEvent(sseRes, this._notConnectedPayload(providerName, body));\n }\n\n res.writeHead(202);\n res.end();\n });\n }\n\n /**\n * Serves `/<providerName>/mcp` by handing the request to the slot's\n * Streamable HTTP endpoint.\n *\n * Everything protocol-shaped, sessions, `Mcp-Session-Id`, `DELETE`, the\n * `404` on a terminated session, `Origin` and `MCP-Protocol-Version`\n * validation, `202` on a notification, belongs to `mcp-core` and is no\n * longer reimplemented here. What stays is the broker's own business:\n * deciding who may speak (already done upstream by the auth guard) and\n * relaying frames to a provider that lives somewhere else entirely.\n */\n private _handleStreamableHttp(req: IncomingMessage, res: ServerResponse, providerName: string, principal: IPrincipal | null): void {\n const state = this._getOrCreateProviderState(providerName);\n\n // The endpoint authenticates nothing: this broker has its own guard,\n // richer than the spec's (per-slot scopes, subject mapping into the\n // policy engine). So the principal is attached to the session here,\n // refreshed on every request, and read back when a frame is checked.\n const sessionId = req.headers[\"mcp-session-id\"];\n if (typeof sessionId === \"string\") {\n const session = state.httpSessions.get(sessionId);\n if (session) session.principal = principal;\n }\n\n void this._endpointFor(providerName, state).handleRequest(req, res);\n }\n\n /**\n * The slot's Streamable HTTP endpoint, built on first use.\n *\n * Its factory does not create an MCP server: the server is the provider,\n * reachable only through the tunnel. It creates a bridge instead: frames the\n * client sends go out to the provider, and frames coming back are addressed\n * to this session by id.\n */\n private _endpointFor(providerName: string, state: IProviderState): StreamableHttpEndpoint {\n if (state.httpEndpoint) return state.httpEndpoint;\n\n state.httpEndpoint = new StreamableHttpEndpoint({\n allowedOrigins: this._allowedOrigins,\n\n createServer: (transport, sessionId, _principal) => {\n const session: IHttpSession = { transport, principal: null };\n state.httpSessions.set(sessionId, session);\n\n transport.onMessage = (frame: string) => this._fromHttpSession(state, providerName, sessionId, session, frame);\n\n return {\n // No server to launch: the one serving this session is the\n // provider, at the far end of the tunnel. What `start` still\n // owes is opening the transport, since a closed one drops\n // every frame it is handed.\n start: () => openTransport(transport),\n stop: () => {\n state.httpSessions.delete(sessionId);\n // Nothing can answer the requests this session had in\n // flight; leaving them would pin the ids forever.\n for (const [brokerId, entry] of state.pending) {\n if (entry.sink.type === \"http-session\" && entry.sink.sessionId === sessionId) state.pending.delete(brokerId);\n }\n },\n };\n },\n });\n\n return state.httpEndpoint;\n }\n\n /** Relays one frame from an HTTP session to the provider behind the slot. */\n private _fromHttpSession(state: IProviderState, providerName: string, sessionId: string, session: IHttpSession, frame: string): void {\n if (!this._authorizeMcpFrame(providerName, frame, session.principal)) {\n session.transport.send(this._policyDeniedPayload(frame));\n return;\n }\n\n if (!this._isProviderConnected(providerName, state)) {\n session.transport.send(this._notConnectedPayload(providerName, frame));\n return;\n }\n\n this._sendToProvider(state, providerName, this._trackRequest(state, frame, { type: \"http-session\", sessionId }), session.principal);\n }\n\n /** Writes one JSON-RPC message as an SSE `message` event. */\n private _sendSseEvent(res: ServerResponse, data: string): void {\n // data is already a compact JSON string: no need to parse+re-serialize.\n res.write(`event: message\\ndata: ${data}\\n\\n`);\n }\n\n // -------------------------------------------------------------------------\n // WebSocket connection handlers\n // -------------------------------------------------------------------------\n\n /**\n * Prints one line for every accepted WebSocket upgrade: the path asked for,\n * the role the router gave it, and the slot it landed on.\n *\n * Without it a successful connect produces no output whatsoever, so a\n * mistyped provider URL looks exactly like a working one until nothing ever\n * answers. The last router branch accepts **any** unmatched path as a client\n * slot, so `/providers/foo` (neither the multiplex endpoint `/providers` nor\n * a dedicated `/provider/foo`) becomes a client on a slot literally named\n * `providers/foo`; that case gets the fix spelled out in the same line.\n *\n * `console.log` is safe here: in stdio mode `bin.ts` rebinds the console to\n * stderr before the tunnel starts, so this never reaches the JSON-RPC stream.\n */\n private _logWsConnection(path: string, role: WsConnectRole, slot: string): void {\n let hint = \"\";\n if (role === \"client\") {\n const providerPath = this._options.providerPath ?? \"/provider\";\n const providersPath = this._options.providersPath ?? \"/providers\";\n const providerSlot = providerPath.replace(/^\\//, \"\");\n const providersSlot = providersPath.replace(/^\\//, \"\");\n // `/provider?x=1` matches neither provider branch (they test the bare\n // path and the `<path>/` prefix), and `/providers/foo` matches neither\n // the exact multiplex path nor the dedicated prefix.\n if (slot === providerSlot || slot === providersSlot || slot.startsWith(providersSlot + \"/\")) {\n hint =\n ` -- this looks like a provider URL but matched no provider route, so it was accepted as a CLIENT slot and nothing will ever answer it. ` +\n `Connect a MultiplexTransport to \"${providersPath}\" (exact path, slots announced per envelope), or a DirectTransport to \"${providerPath}/<name>\".`;\n }\n }\n console.log(`[broker] ws connect path=\"${path}\" role=${role} slot=\"${slot}\"${hint}`);\n }\n\n private _logProviderRegistration(principal: IProviderPrincipal, slot: string, resource: ResourcePath | undefined, allowed: boolean): void {\n const event = {\n timestamp: new Date().toISOString(),\n providerId: principal.id,\n slot,\n resource: resource?.value,\n allowed,\n };\n const line = `[broker] provider-registration ${JSON.stringify(event)}`;\n if (allowed) console.info(line);\n else console.warn(line);\n }\n\n private _onProviderConnect(ws: WebSocket, name: string, req: IncomingMessage): void {\n const providerPrincipal = this._pendingProviderPrincipals.get(req);\n if (providerPrincipal) {\n this._pendingProviderPrincipals.delete(req);\n this._providerPrincipals.set(ws, providerPrincipal);\n }\n if (this._upstreams.has(name)) {\n console.warn(\n `[broker] WARNING: WebSocket provider \"${name}\" rejected: a stdio upstream with the same name is already configured. ` + `Rename one of them to avoid the conflict.`\n );\n this._closeWs(ws, 1008, `Provider \"${name}\" is managed by a stdio upstream`);\n return;\n }\n\n if (this._loopbackProviders.has(name)) {\n console.warn(`[broker] WARNING: WebSocket provider \"${name}\" rejected: the slot is held by an in-process loopback (reserved system slot).`);\n this._closeWs(ws, 1008, `Provider \"${name}\" is reserved by the broker`);\n return;\n }\n\n const refusal = this._claimSlot(name, ws);\n if (refusal) {\n console.warn(`[broker] WARNING: WebSocket provider \"${name}\" rejected. ${refusal.detail}`);\n this._closeWs(ws, 1008, refusal.closeReason);\n return;\n }\n\n const state = this._getOrCreateProviderState(name);\n state.ws = ws;\n this._watchProviderSocket(ws);\n if (providerPrincipal) {\n this._logProviderRegistration(providerPrincipal, name, this._slotResourceResolver.resolve(name), true);\n }\n\n // A provider MAY send a registration control frame as its very first\n // message (see _tryHandleRegistration). Any other first message ,\n // including a normal MCP frame, is routed and leaves the provider\n // non-aggregated, so every pre-existing provider keeps working.\n let registrationChecked = false;\n ws.on(\"message\", (data: Buffer) => {\n const text = data.toString();\n if (!registrationChecked) {\n registrationChecked = true;\n if (this._refuseEnvelopeOnSlotPath(ws, name, text)) return;\n if (this._tryHandleRegistration(name, text)) return;\n }\n this._routeFromProvider(state, name, text);\n });\n\n ws.on(\"close\", () => {\n // Only the socket that currently holds the slot may release it.\n //\n // A provider that reconnects while its predecessor is still CLOSING\n // is admitted (the incumbent is no longer OPEN), takes `state.ws`,\n // and would then have its own registration nulled out by the\n // predecessor's deferred close. The slot stays wedged: the socket is\n // open and answering, `provider_status` reports `connected: false`,\n // and `_failProviderDisconnected` has already evicted the slot from\n // `_all`, which the aggregate opt-in cannot restore because it is\n // checked once per socket, on the first frame. The multiplexed path\n // has always guarded this way.\n if (state.ws !== ws) return;\n state.ws = null;\n this._failProviderDisconnected(state, name);\n });\n\n // `ws` emits 'error' for receive-side protocol faults, an invalid UTF-8\n // text frame or a bad opcode among them, and Node rethrows an unhandled\n // 'error' event as an uncaught exception. Without this listener one\n // malformed frame from one provider takes the whole broker down and every\n // other provider with it. Log and let the socket close on its own: `ws`\n // closes it right after emitting.\n ws.on(\"error\", (err: Error) => {\n console.error(`[broker] provider \"${name}\" socket error: ${err.message}. The socket is being closed; the provider should reconnect.`);\n });\n }\n\n /**\n * Inspects a provider's first WebSocket message for a registration frame,\n * and consumes it when that is what it is. Returns `true` when the message\n * was a registration, and thus must not be routed as MCP traffic.\n *\n * Two shapes are accepted, both notifications a peer that does not know them\n * ignores:\n *\n * - `{\"jsonrpc\":\"2.0\",\"method\":\"notifications/register\",\"params\":{\"aggregate\":true}}`,\n * what `@cyanmycelium/mcp-broker-provider` sends on **both** paths. This\n * is the shape to write new providers against: the multiplexed socket has\n * always used it (wrapped in an envelope), so there is now one\n * registration to learn instead of one per path.\n * - `{\"type\":\"register\",\"aggregate\":true}`, the legacy control frame, kept\n * working indefinitely for hand-written providers already sending it.\n *\n * `aggregate` is opt-in and stays that way. Joining `_all` publishes a\n * provider's tools and prompts to every client of the aggregate slot, which\n * is a confidentiality boundary: a provider that never asks is reachable\n * only on its own slot.\n *\n * A normal MCP frame carries `jsonrpc` with some other `method`, so it\n * returns `false` and the provider stays non-aggregated.\n */\n private _tryHandleRegistration(name: string, text: string): boolean {\n const frame = parseObjectFrame(text);\n if (!frame) return false;\n\n const isJsonRpcRegister = frame.jsonrpc !== undefined && frame.method === TUNNEL_REGISTER_METHOD;\n const isLegacyRegister = frame.jsonrpc === undefined && frame.type === \"register\";\n if (!isJsonRpcRegister && !isLegacyRegister) return false;\n\n if (registrationAsksForAggregate(frame)) {\n void this._aggregateServer?.addProvider(name);\n }\n return true;\n }\n\n /**\n * Detects a `MultiplexTransport` connected to a slot-scoped provider URL,\n * the single most reported way to wire this broker up wrong, and refuses it\n * instead of letting it look like it worked.\n *\n * What the mistake looks like without this check: the socket connects, the\n * broker registers the slot from the URL before any frame exists, so\n * `provider_status` reports the provider connected; then every frame the\n * broker sends is a plain JSON-RPC one that the peer's envelope decoder\n * drops on the floor, and every frame the peer sends is an envelope with no\n * top-level `id`, so it matches no pending request. Both sides believe they\n * are connected and no request is ever answered. Nothing is logged anywhere.\n *\n * Only an **unambiguous** envelope closes the socket: a JSON object with no\n * `jsonrpc` member that decodes as `{provider, payload}`. A malformed frame\n * is left alone and routed as before, since a provider is entitled to speak\n * a dialect the broker does not recognize. The legacy\n * `{\"type\":\"register\",\"aggregate\":true}` frame has no `provider`/`payload`\n * pair and so is never mistaken for one.\n *\n * The diagnosis goes out three ways because each reaches a different reader:\n * the broker log, an error **envelope** (the only framing this particular\n * peer can decode), and the close reason, which the provider SDK surfaces\n * through `onError` and prints to the browser console.\n */\n private _refuseEnvelopeOnSlotPath(ws: WebSocket, name: string, text: string): boolean {\n const frame = parseObjectFrame(text);\n if (!frame || frame.jsonrpc !== undefined) return false;\n const envelope = decodeEnvelope(text);\n if (!envelope) return false;\n\n const providerPath = this._options.providerPath ?? \"/provider\";\n const providersPath = this._options.providersPath ?? \"/providers\";\n const detail =\n `Provider \"${name}\" is registered on the slot-scoped path \"${providerPath}/${name}\", which carries plain JSON-RPC frames, but its first frame is a multiplex envelope ` +\n `(it announced slot \"${envelope.provider}\"). This is a MultiplexTransport pointed at a DirectTransport URL. Two corrections, either works: ` +\n `use DirectTransport for \"${providerPath}/${name}\" (plain frames, one slot fixed by the URL), or keep MultiplexTransport and connect it to \"${providersPath}\" ` +\n `(exact path, envelope framing, slots announced per frame). The connection is being closed; it would otherwise look connected and answer nothing.`;\n\n console.warn(`[broker] ${detail}`);\n try {\n // Addressed to the slot the peer announced, not to the URL's: that is\n // the name its own decoder will match the envelope against.\n ws.send(encodeErrorEnvelope(envelope.provider, TunnelErrorCodes.ProviderUnavailable, detail));\n } catch {\n /* the socket may already be gone; the log and the close reason stand */\n }\n this._closeWs(ws, 1008, `Envelope frame on slot-scoped path ${providerPath}/${name}: use DirectTransport here, or connect to ${providersPath}`);\n return true;\n }\n\n /**\n * The mirror image: a `DirectTransport` connected to the shared multiplexed\n * base. Refuses it instead of dropping its frames one by one in silence.\n *\n * Signature of the mistake: the socket opens, the broker never learns a slot\n * name (they only arrive inside envelopes), so no slot is ever claimed and\n * every client is told the provider is not connected, while the provider\n * believes it published successfully.\n *\n * Only a frame that is unambiguously plain JSON-RPC (a JSON object carrying\n * `jsonrpc`, that did not decode as an envelope) closes the socket. Anything\n * else keeps the old behavior of dropping the frame, now with one warning.\n */\n private _refusePlainFrameOnMultiplexPath(ws: WebSocket, text: string): boolean {\n const frame = parseObjectFrame(text);\n if (!frame || frame.jsonrpc === undefined) return false;\n\n const providerPath = this._options.providerPath ?? \"/provider\";\n const providersPath = this._options.providersPath ?? \"/providers\";\n const detail =\n `A provider connected to the multiplexed path \"${providersPath}\", which carries envelope frames {\"provider\":\"<slot>\",\"payload\":{...}}, but sent a plain JSON-RPC frame ` +\n `(method \"${String(frame.method ?? \"(none)\")}\"). This is a DirectTransport pointed at a MultiplexTransport URL. Two corrections, either works: ` +\n `use MultiplexTransport for \"${providersPath}\" (it wraps every frame and announces its slots), or keep DirectTransport and connect it to \"${providerPath}/<name>\" ` +\n `(the slot comes from the URL there). The connection is being closed; on this path the broker never learns a slot name, so every client would be told the provider is not connected.`;\n\n console.warn(`[broker] ${detail}`);\n try {\n // A bare JSON-RPC error, matching what this peer speaks: an envelope\n // would be dropped by a DirectTransport exactly the way its own\n // frames are being dropped here.\n ws.send(JSON.stringify({ jsonrpc: \"2.0\", id: null, error: { code: TunnelErrorCodes.ProviderUnavailable, message: detail } }));\n } catch {\n /* the socket may already be gone; the log and the close reason stand */\n }\n this._closeWs(ws, 1008, `Plain JSON-RPC on multiplex path ${providersPath}: use MultiplexTransport here, or connect to ${providerPath}/<name>`);\n return true;\n }\n\n private _onClientConnect(ws: WebSocket, providerName: string, req: IncomingMessage): void {\n const state = this._getOrCreateProviderState(providerName);\n state.wsClients.add(ws);\n\n // Carry the principal captured at the upgrade onto the socket, so requests\n // this client makes to `_all` can be scope-filtered.\n const principal = this._pendingClientPrincipals.get(req);\n if (principal) {\n this._clientPrincipals.set(ws, principal);\n this._pendingClientPrincipals.delete(req);\n }\n\n ws.on(\"message\", (data: Buffer) => this._routeFromClient(ws, state, providerName, data.toString()));\n\n ws.on(\"close\", () => {\n state.wsClients.delete(ws);\n for (const [brokerId, entry] of state.pending) {\n if (entry.sink.type === \"ws\" && entry.sink.socket === ws) state.pending.delete(brokerId);\n }\n });\n\n // Same reason as on the provider sockets: an unhandled 'error' event is\n // rethrown by Node, so a single client sending a malformed frame would\n // otherwise kill the broker for everybody.\n ws.on(\"error\", (err: Error) => {\n console.error(`[broker] client socket error on slot \"${providerName}\": ${err.message}. The socket is being closed; the client should reconnect.`);\n });\n }\n\n /**\n * Handles a multiplexed provider WebSocket (`/providers`).\n * A single socket carries traffic for multiple providers using the\n * envelope format `{ provider: string, payload: object }`.\n * Provider names are registered lazily on first message.\n */\n private _onMultiplexProviderConnect(ws: WebSocket, req: IncomingMessage): void {\n const providerNames = new Set<string>();\n this._multiplexSockets.set(ws, providerNames);\n this._watchProviderSocket(ws);\n const providerPrincipal = this._pendingProviderPrincipals.get(req);\n if (providerPrincipal) {\n this._pendingProviderPrincipals.delete(req);\n this._providerPrincipals.set(ws, providerPrincipal);\n }\n\n // Undecodable frames used to be dropped without a word. The first one is\n // where a DirectTransport on the wrong URL is caught; later ones warn\n // once, because a peer that speaks the wrong dialect speaks it on every\n // frame and must not be allowed to flood the log.\n let firstFrame = true;\n let undecodableWarned = false;\n\n ws.on(\"message\", (data: Buffer) => {\n const text = data.toString();\n const envelope = decodeEnvelope(text);\n const wasFirstFrame = firstFrame;\n firstFrame = false;\n\n if (!envelope) {\n if (wasFirstFrame && this._refusePlainFrameOnMultiplexPath(ws, text)) return;\n if (!undecodableWarned) {\n undecodableWarned = true;\n const preview = text.length > 200 ? `${text.slice(0, 200)}...` : text;\n console.warn(\n `[broker] multiplexed provider socket sent a frame that is not a tunnel envelope; it was dropped. ` +\n `This path expects {\"provider\":\"<slot>\",\"payload\":{ ...JSON-RPC... }} on every frame. First 200 chars: ${JSON.stringify(preview)}. ` +\n `Further undecodable frames from this socket are not logged.`\n );\n }\n return;\n }\n\n const name = envelope.provider;\n\n // Register provider name lazily on first encounter.\n if (!providerNames.has(name)) {\n if (providerPrincipal) {\n const resource = this._slotResourceResolver.resolve(name);\n if (!resource || !providerMayPublish(providerPrincipal, resource)) {\n this._logProviderRegistration(providerPrincipal, name, resource, false);\n ws.send(encodeErrorEnvelope(name, TunnelErrorCodes.RegistrationForbidden, \"Provider registration forbidden\"));\n return;\n }\n }\n if (this._upstreams.has(name)) {\n console.warn(\n `[broker] WARNING: Multiplexed WebSocket provider \"${name}\" rejected: a stdio upstream with the same name is already configured. ` +\n `Rename one of them to avoid the conflict.`\n );\n ws.send(encodeErrorEnvelope(name, TunnelErrorCodes.ProviderUnavailable, `Provider \"${name}\" is managed by a stdio upstream`));\n return;\n }\n\n if (this._loopbackProviders.has(name)) {\n ws.send(encodeErrorEnvelope(name, TunnelErrorCodes.ProviderUnavailable, `Provider \"${name}\" is reserved by the broker`));\n return;\n }\n\n const refusal = this._claimSlot(name, ws);\n if (refusal) {\n // Provider already connected via another socket, reject this\n // name. The socket itself stays open on purpose: it may be\n // carrying other slots it is legitimately serving.\n console.warn(`[broker] WARNING: multiplexed WebSocket provider \"${name}\" rejected. ${refusal.detail}`);\n // An envelope has no length limit, so the peer gets the full\n // diagnosis here, not the close-frame abbreviation.\n ws.send(encodeErrorEnvelope(name, TunnelErrorCodes.ProviderUnavailable, refusal.detail));\n return;\n }\n providerNames.add(name);\n const state = this._getOrCreateProviderState(name);\n state.ws = ws;\n if (providerPrincipal) {\n this._logProviderRegistration(providerPrincipal, name, this._slotResourceResolver.resolve(name), true);\n }\n\n // The multiplexed path could not aggregate at all before this:\n // it had no `addProvider` call anywhere, so the one transport the\n // provider README demonstrates was the one that could never join\n // `_all`. The opt-in rides on the `notifications/register`\n // notification the transport already sends on every open, as\n // `params.aggregate`.\n if (registrationAsksForAggregate(envelope.payload)) {\n void this._aggregateServer?.addProvider(name);\n }\n }\n\n const state = this._providers.get(name)!;\n this._routeFromProvider(state, name, envelopeFrame(envelope));\n });\n\n ws.on(\"close\", () => {\n for (const name of providerNames) {\n const state = this._providers.get(name);\n if (state && state.ws === ws) {\n state.ws = null;\n this._failProviderDisconnected(state, name);\n }\n }\n this._multiplexSockets.delete(ws);\n });\n\n // An unhandled 'error' event is rethrown by Node. One multiplex socket\n // carries every slot it announced, so losing the process over a single\n // malformed frame is the worst of the three cases: name the slots this\n // socket was serving, since they are all about to go with it.\n ws.on(\"error\", (err: Error) => {\n const slots = providerNames.size > 0 ? [...providerNames].join(\", \") : \"(none announced yet)\";\n console.error(\n `[broker] multiplex provider socket error: ${err.message}. Slots carried by this socket: ${slots}. The socket is being closed; the provider should reconnect.`\n );\n });\n }\n\n // -------------------------------------------------------------------------\n // Message routing\n // -------------------------------------------------------------------------\n\n /**\n * Sends a raw JSON-RPC message to a provider, wrapping it in a multiplex\n * envelope when the provider's WebSocket is a multiplexed connection.\n */\n private _sendToProvider(state: IProviderState, providerName: string, data: string, principal: IPrincipal | null = null): void {\n // The `_all` aggregate is a loopback, but it needs the caller's principal\n // to scope its catalog/routing, hand it off directly rather than through\n // the generic transport, which would drop the context.\n if (providerName === AggregateServer.SLOT && this._aggregateServer) {\n this._aggregateServer.sendAs(data, principal);\n return;\n }\n\n // Upstreams (stdio child processes and remote URL servers) take priority.\n const upstream = this._upstreams.get(providerName);\n if (upstream?.isOpen) {\n upstream.send(data);\n return;\n }\n\n // In-process loopback (e.g. the embedded `_broker`) takes the same priority.\n const loopback = this._loopbackProviders.get(providerName);\n if (loopback?.isOpen) {\n loopback.send(data);\n return;\n }\n\n if (!state.ws || state.ws.readyState !== WebSocket.OPEN) return;\n\n if (this._multiplexSockets.has(state.ws)) {\n // Wrap in envelope for the multiplexed socket.\n state.ws.send(encodeEnvelope(providerName, data));\n } else {\n state.ws.send(data);\n }\n }\n\n private _routeFromStdioClient(state: IProviderState, data: string): void {\n if (this._isProviderConnected(this._stdioClientProvider!, state)) {\n this._sendToProvider(state, this._stdioClientProvider!, this._trackRequest(state, data, { type: \"stdio\" }));\n } else {\n let errId: string | number | null = null;\n try {\n errId = (JSON.parse(data) as { id?: string | number }).id ?? null;\n } catch {\n /* */\n }\n if (errId != null) {\n // A stdio host (Claude Desktop) starts the broker and sends\n // `initialize` immediately, long before a browser or engine\n // provider has had a chance to connect, and it treats the failure\n // as a dead server with no retry. So the error names the two slots\n // that exist from the first millisecond instead of just reporting\n // the miss.\n this._stdioClientTransport?.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: errId,\n error: {\n code: -32000,\n message:\n `Provider \"${this._stdioClientProvider}\" not connected. A stdio host cannot wait for a provider to appear: pin ` +\n `MCP_BROKER_STDIO_PROVIDER to \"_all\" (the aggregate slot, present at startup, and it announces tools as providers join) ` +\n `or to \"_broker\" (introspection only: broker_info, providers_list, provider_status).`,\n },\n })\n );\n }\n }\n }\n\n private _routeFromClient(client: WebSocket, state: IProviderState, providerName: string, data: string): void {\n const principal = this._clientPrincipals.get(client) ?? null;\n if (!this._authorizeMcpFrame(providerName, data, principal)) {\n client.send(this._policyDeniedPayload(data));\n return;\n }\n\n if (!this._isProviderConnected(providerName, state)) {\n // Echo the request id and name the slot. With `id: null` a client that\n // correlates by id (every SDK does) drops the frame and then waits for\n // an answer that is never coming, so the symptom of an absent provider\n // was an indefinite hang rather than an error. The pointer to\n // `providers_list` is what turns it into something actionable: the\n // usual cause is a slot name that does not match the one the provider\n // registered.\n client.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: requestIdOf(data) ?? null,\n error: {\n code: -32000,\n message: `Provider \"${providerName}\" is not connected. Call providers_list on the _broker slot to see which slots are live.`,\n },\n })\n );\n return;\n }\n\n // Registered only once the frame is actually on its way out: an entry\n // added before the connectivity check has nothing to answer it and would\n // pin that id until the slot next disconnects.\n this._sendToProvider(state, providerName, this._trackRequest(state, data, { type: \"ws\", socket: client }), principal);\n }\n\n private _routeFromProvider(state: IProviderState, providerName: string, data: string): void {\n try {\n const msg = JSON.parse(data) as { id?: string | number };\n\n if (msg.id != null) {\n // Response: route to the specific sink that made the request, and\n // put the client's own id back in place of the broker's before it\n // is delivered (see `_trackRequest`).\n const entry = state.pending.get(msg.id);\n if (entry) {\n state.pending.delete(msg.id);\n (msg as { id: unknown }).id = entry.clientId;\n this._deliverToSink(state, entry.sink, JSON.stringify(msg));\n } else {\n this._warnUnmatchedResponseId(providerName, msg.id);\n }\n } else {\n // Notification (no id): broadcast to all clients of this provider.\n this._broadcast(state, providerName, data);\n }\n } catch {\n // The frame could not be parsed and routed as JSON-RPC. It is still\n // broadcast, because some providers legitimately put non-JSON-RPC text\n // on this socket and silently dropping it would be a behavior change,\n // but it no longer travels unannounced: the usual source is a reverse\n // proxy answering with an HTML error page under a 200, which then\n // surfaces in every client as an \"unexpected token <\" with nothing\n // naming the provider it came from.\n if (!this._nonJsonWarnedProviders.has(providerName)) {\n this._nonJsonWarnedProviders.add(providerName);\n const preview = data.length > 200 ? `${data.slice(0, 200)}...` : data;\n console.warn(\n `[broker] provider \"${providerName}\" sent a frame the broker could not route as JSON-RPC; it is being broadcast to that slot's clients verbatim. ` +\n `First 200 chars: ${JSON.stringify(preview)}. If this is HTML, something between the broker and the provider (a proxy, a login page) is answering instead of the provider. ` +\n `Further such frames from this slot are not logged.`\n );\n }\n this._broadcast(state, providerName, data);\n }\n }\n\n /**\n * Reports a frame carrying an id nothing is waiting for.\n *\n * Two very different causes, so the message names both. Either the provider\n * did not echo the id it was given (the frame is then unroutable and the\n * real client hangs until the request deadline), or the provider is opening\n * a **server-to-client** request of its own (`sampling/createMessage`,\n * `roots/list`, `elicitation/create`), which this broker does not relay: the\n * frame is dropped and the provider waits for an answer that never comes.\n * Both used to be silent, which is what made the second one impossible to\n * diagnose from either end.\n *\n * Once per slot: a provider doing this does it on every frame.\n */\n private _warnUnmatchedResponseId(providerName: string, id: string | number): void {\n if (this._unmatchedIdWarnedProviders.has(providerName)) return;\n this._unmatchedIdWarnedProviders.add(providerName);\n console.warn(\n `[broker] provider \"${providerName}\" sent a frame with id ${JSON.stringify(id)}, which matches no request the broker is waiting on; it was dropped. ` +\n `Either the provider answered with a different id than the one it received (JSON-RPC requires echoing it verbatim, including its type: 1 and \"1\" are not the same id), ` +\n `or it is initiating a request of its own (sampling/createMessage, roots/list, elicitation/create), which the broker does not relay to clients. ` +\n `Further unmatched ids from this slot are not logged.`\n );\n }\n\n /** Sends a message to all clients connected to one provider. */\n private _broadcast(state: IProviderState, providerName: string, data: string): void {\n for (const client of state.wsClients) {\n const principal = this._clientPrincipals.get(client) ?? null;\n if (client.readyState === WebSocket.OPEN && this._authorizeMcpFrame(providerName, data, principal)) {\n client.send(data);\n }\n }\n for (const sseRes of state.sseSessions.values()) {\n const principal = this._streamPrincipals.get(sseRes) ?? null;\n if (this._authorizeMcpFrame(providerName, data, principal)) {\n this._sendSseEvent(sseRes, data);\n }\n }\n for (const session of state.httpSessions.values()) {\n // The principal rides on the session here rather than in a WeakMap\n // keyed by the response: a Streamable HTTP session spans many HTTP\n // exchanges, so there is no single response to hang it on.\n if (this._authorizeMcpFrame(providerName, data, session.principal)) {\n session.transport.send(data);\n }\n }\n for (const ic of state.internalClients) {\n ic.onMessage?.(data);\n }\n // Forward notifications to the stdio client if it is watching this provider.\n if (this._stdioClientProvider && this._providers.get(this._stdioClientProvider) === state) {\n this._stdioClientTransport?.send(data);\n }\n }\n\n /**\n * Notifies every pending sink and internal client that the provider slot\n * has disconnected, then clears the pending map. Shared by all provider\n * close handlers (dedicated WS, multiplexed WS, loopback).\n */\n private _failProviderDisconnected(state: IProviderState, name: string): void {\n // Echoing the **client's** id rather than `null` or the broker's: a\n // Streamable HTTP session matches the answer to its held-open POST by\n // the id it chose, so an unaddressed error would leave that request\n // hanging until it times out.\n for (const entry of state.pending.values()) {\n const error = JSON.stringify({\n jsonrpc: \"2.0\",\n id: entry.clientId,\n error: { code: -32000, message: `Provider \"${name}\" disconnected` },\n });\n this._deliverToSink(state, entry.sink, error);\n }\n state.pending.clear();\n for (const ic of state.internalClients) ic.onClose?.();\n }\n\n // -------------------------------------------------------------------------\n // Provider state helpers\n // -------------------------------------------------------------------------\n\n /**\n * Returns `true` if the provider is reachable, via a WebSocket connection,\n * a stdio upstream, or an in-process loopback transport.\n */\n private _isProviderConnected(providerName: string, state: IProviderState): boolean {\n if (this._upstreams.get(providerName)?.isOpen) return true;\n if (this._loopbackProviders.get(providerName)?.isOpen) return true;\n if (state.ws?.readyState === WebSocket.OPEN) return true;\n return false;\n }\n\n /** Returns the state for `name`, creating it lazily if it doesn't exist yet. */\n private _getOrCreateProviderState(name: string): IProviderState {\n let state = this._providers.get(name);\n if (!state) {\n state = {\n ws: null,\n pending: new Map(),\n sseSessions: new Map(),\n httpSessions: new Map(),\n wsClients: new Set(),\n internalClients: new Set(),\n httpEndpoint: null,\n };\n this._providers.set(name, state);\n }\n return state;\n }\n\n // -------------------------------------------------------------------------\n // Samples index\n // -------------------------------------------------------------------------\n\n private _handleSamplesIndex(res: ServerResponse): void {\n const rootMount = (this._options.staticMounts ?? []).find((m) => m.urlPrefix === \"/\");\n\n let files: string[] = [];\n if (rootMount) {\n const samplesDir = nodePath.join(rootMount.dir, \"samples\");\n try {\n if (fs.existsSync(samplesDir) && fs.statSync(samplesDir).isDirectory()) {\n files = fs.readdirSync(samplesDir).filter((name) => fs.statSync(nodePath.join(samplesDir, name)).isFile());\n }\n } catch {\n /* return empty list on any I/O error */\n }\n }\n\n res.writeHead(200, { \"Content-Type\": \"application/json; charset=utf-8\" });\n res.end(JSON.stringify({ files }));\n }\n\n // -------------------------------------------------------------------------\n // Static file serving\n // -------------------------------------------------------------------------\n\n private _serveStatic(req: IncomingMessage, res: ServerResponse): void {\n const rawUrl = (req.url ?? \"/\").split(\"?\")[0].split(\"#\")[0];\n const mounts = this._options.staticMounts ?? [];\n\n const mount = [...mounts]\n .filter((m) => {\n const prefix = m.urlPrefix.endsWith(\"/\") ? m.urlPrefix : m.urlPrefix + \"/\";\n return rawUrl === m.urlPrefix || rawUrl.startsWith(prefix);\n })\n .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)[0];\n\n if (!mount) {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not found\");\n return;\n }\n\n const relative = rawUrl.slice(mount.urlPrefix.length) || \"/\";\n const normalized = nodePath.normalize(relative);\n\n if (normalized.startsWith(\"..\")) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n const mountAbs = nodePath.resolve(mount.dir);\n let filePath = nodePath.join(mountAbs, normalized);\n\n if (!filePath.startsWith(mountAbs + nodePath.sep) && filePath !== mountAbs) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n try {\n if (fs.statSync(filePath).isDirectory()) filePath = nodePath.join(filePath, \"index.html\");\n } catch {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n if (!fs.existsSync(filePath)) {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const ext = nodePath.extname(filePath).toLowerCase();\n res.writeHead(200, { \"Content-Type\": MIME[ext] ?? \"application/octet-stream\" });\n fs.createReadStream(filePath).pipe(res);\n }\n}\n","import * as fs from \"fs\";\nimport { WsTunnel } from \"./ws.tunnel\";\nimport type { AllowedOrigins, IStaticMount, IWsTunnelOptions, ProviderTakeoverMode } from \"./ws.interfaces\";\nimport type { IStdioUpstreamConfig } from \"../stdio.upstream\";\nimport type { IRemoteUpstreamConfig } from \"../remote.upstream\";\nimport { buildJwtAuth, SharedSecretProviderAuthenticator, type IJwtAuthOptions, type IResolvedAuth, type IProviderAuthenticator } from \"../auth/index\";\nimport {\n authorizationWithEngine,\n compileAuthorizationPolicy,\n type IAuthorizationPolicyConfig,\n type IPolicyAuthorization,\n type IPolicyEngine,\n type ISlotResourceResolver,\n} from \"../authorization/index\";\n\n/**\n * Fluent builder that constructs a configured {@link WsTunnel}.\n *\n * @example\n * ```typescript\n * const tunnel = new WsTunnelBuilder()\n * .withPort(3000)\n * .withHost(\"localhost\")\n * .withStaticMount(\"/\", \"/abs/path/to/www\")\n * .build();\n *\n * await tunnel.start();\n * console.log(\"Broker listening on ws://localhost:3000\");\n * console.log(\" Provider connects to: ws://localhost:3000/provider/<name>\");\n * console.log(\" Clients connect to: ws://localhost:3000/<name>\");\n * ```\n */\nexport class WsTunnelBuilder {\n private _port = 3000;\n private _host: string | undefined;\n private _providerPath = \"/provider\";\n private _providersPath = \"/providers\";\n private _clientPath = \"/\";\n private _ssePath = \"/sse\";\n private _messagesPath = \"/messages\";\n private _mcpPath = \"/mcp\";\n private _samplesIndexPath = \"/__samples_index__\";\n private _allowedOrigins: AllowedOrigins | undefined = undefined;\n private _providerHeartbeatIntervalMs: number | undefined = undefined;\n private _providerTakeover: ProviderTakeoverMode | undefined = undefined;\n private _providerRequestTimeoutMs: number | undefined = undefined;\n private _staticMounts: IStaticMount[] = [];\n private _stdioUpstreams: IStdioUpstreamConfig[] = [];\n private _remoteUpstreams: IRemoteUpstreamConfig[] = [];\n private _stdioClient: { providerName: string } | undefined = undefined;\n private _tls: { cert: string; key: string } | undefined = undefined;\n private _brokerLocalGrammarsDir: string | undefined = undefined;\n private _auth: IResolvedAuth | undefined = undefined;\n private _providerAuth: IProviderAuthenticator | undefined = undefined;\n private _authorization: IPolicyAuthorization | undefined = undefined;\n private _slotResourceResolver: ISlotResourceResolver | undefined = undefined;\n\n /** Sets the TCP port the broker listens on. */\n withPort(port: number): this {\n this._port = port;\n return this;\n }\n\n /**\n * Sets the host/interface to bind to.\n * @default \"0.0.0.0\" (all interfaces)\n */\n withHost(host: string): this {\n this._host = host;\n return this;\n }\n\n /**\n * Sets the URL path the MCP provider connects to.\n * @default \"/provider\"\n */\n withProviderPath(path: string): this {\n this._providerPath = path;\n return this;\n }\n\n /**\n * Sets the URL path for multiplexed provider connections.\n * Multiple providers share a single WebSocket using the envelope protocol.\n * @default \"/providers\"\n */\n withProvidersPath(path: string): this {\n this._providersPath = path;\n return this;\n }\n\n /**\n * Sets the URL path MCP clients connect to.\n * @default \"/\"\n */\n withClientPath(path: string): this {\n this._clientPath = path;\n return this;\n }\n\n /**\n * Sets the URL path for the SSE stream (legacy Claude transport, GET).\n * @default \"/sse\"\n */\n withSsePath(path: string): this {\n this._ssePath = path;\n return this;\n }\n\n /**\n * Sets the URL path for JSON-RPC POST requests (legacy Claude transport).\n * @default \"/messages\"\n */\n withMessagesPath(path: string): this {\n this._messagesPath = path;\n return this;\n }\n\n /**\n * Sets the URL path for the Streamable HTTP transport (MCP 2025-03-26).\n * MCP Inspector and other 2025+ clients POST JSON-RPC here.\n * @default \"/mcp\"\n */\n withMcpPath(path: string): this {\n this._mcpPath = path;\n return this;\n }\n\n /**\n * Sets the URL path that returns a `{ files: string[] }` listing of the\n * `samples/` subdirectory under the root static mount.\n * @default \"/__samples_index__\"\n */\n withSamplesIndexPath(path: string): this {\n this._samplesIndexPath = path;\n return this;\n }\n\n /**\n * Allows browser origins to reach `/<slot>/mcp`.\n *\n * Without this call no browser origin is accepted, which is the safe\n * default: a request carrying an `Origin` is refused with `403`, while one\n * carrying none (any non-browser client) always passes. Call it only when a\n * web page really has to talk to the broker over HTTP.\n *\n * @example\n * ```typescript\n * builder.withAllowedOrigins([\"https://app.example.com\"]);\n * builder.withAllowedOrigins(/^https:\\/\\/[a-z0-9-]+\\.example\\.com$/);\n * builder.withAllowedOrigins((origin) => origin.endsWith(\".example.com\"));\n * ```\n */\n withAllowedOrigins(allowed: AllowedOrigins): this {\n this._allowedOrigins = allowed;\n return this;\n }\n\n /**\n * Sets how often the broker pings each connected provider socket to check\n * it is still there. Pass `0` to disable the heartbeat.\n *\n * A provider that misses a full interval is terminated and its slot freed,\n * which is what stops a half-open socket (a killed tab, a slept laptop, a\n * dropped VPN) from holding a slot for the ~2 hours it takes the OS to give\n * up on the TCP connection, refusing every reconnect in the meantime.\n *\n * Honest about what it proves: a pong is answered by the peer's network\n * stack, not by the page's JavaScript. It detects a dead process, machine or\n * network path, not a provider that is connected and simply not serving.\n * For that, see {@link withProviderRequestTimeout}.\n *\n * @default 30000\n */\n withProviderHeartbeat(intervalMs: number): this {\n this._providerHeartbeatIntervalMs = intervalMs;\n return this;\n }\n\n /**\n * Sets what happens when a provider connects to a slot another socket\n * already holds.\n *\n * - `\"reject\"`: the incumbent always keeps the slot.\n * - `\"liveness\"` (default): the incumbent keeps it only while it answers the\n * heartbeat; a socket that missed its last ping is terminated.\n * - `\"always\"`: the newcomer wins, but **only** when\n * {@link withProviderSecret} / {@link withProviderAuth} is configured and\n * it authenticated as the same principal as the incumbent. Without that,\n * the broker falls back to `\"liveness\"` and logs why: with provider auth\n * off, unconditional takeover would let anyone who can reach the URL evict\n * the real provider.\n */\n withProviderTakeover(mode: ProviderTakeoverMode): this {\n this._providerTakeover = mode;\n return this;\n }\n\n /**\n * Sets how long the broker waits for a provider to answer one request before\n * failing it with a JSON-RPC error naming the slot. Pass `0` to disable.\n *\n * Without a deadline, a provider that stays connected and never answers (a\n * browser tab throttled in the background is the ordinary case) leaves the\n * caller waiting forever with nothing to release it. Raise it if you host\n * genuinely long-running tools.\n *\n * @default 60000\n */\n withProviderRequestTimeout(timeoutMs: number): this {\n this._providerRequestTimeoutMs = timeoutMs;\n return this;\n }\n\n /**\n * Adds a static-file mount served over plain HTTP.\n * Can be called multiple times; longest-prefix match wins at runtime.\n *\n * @param urlPrefix URL prefix that triggers this mount (e.g. `\"/\"` or `\"/bundle\"`).\n * @param dir Absolute path to the directory to serve.\n */\n withStaticMount(urlPrefix: string, dir: string): this {\n this._staticMounts.push({ urlPrefix, dir });\n return this;\n }\n\n /**\n * Registers a stdio upstream provider. The broker spawns the configured\n * command and bridges its stdin/stdout as an MCP transport. Clients reach\n * it using `config.name` directly (e.g. `/<name>/mcp`).\n *\n * Can be called multiple times to register multiple providers.\n */\n withStdioUpstream(config: IStdioUpstreamConfig): this {\n this._stdioUpstreams.push(config);\n return this;\n }\n\n /**\n * Registers a remote MCP server reached by URL. The broker connects out to\n * it and exposes it as a provider slot named `config.name`, bridging the\n * Streamable HTTP / SSE / WebSocket transport for the slot's clients.\n *\n * Can be called multiple times to register multiple servers.\n */\n withRemoteUpstream(config: IRemoteUpstreamConfig): this {\n this._remoteUpstreams.push(config);\n return this;\n }\n\n /**\n * Enables the stdio client transport. The broker will read JSON-RPC from\n * `process.stdin` and write responses to `process.stdout`, bridging Claude\n * Desktop (or any stdio MCP client) to the named provider.\n *\n * All console output is automatically redirected to stderr in this mode so\n * stdout stays clean for the JSON-RPC stream.\n *\n * @param providerName The provider the stdio client maps to.\n */\n withStdioClient(providerName: string): this {\n this._stdioClient = { providerName };\n return this;\n }\n\n /**\n * Enables HTTPS/WSS mode by supplying PEM-encoded certificate and key strings directly.\n * Call this when you already have the PEM content in memory.\n */\n withTls(cert: string, key: string): this {\n this._tls = { cert, key };\n return this;\n }\n\n /**\n * Enables HTTPS/WSS mode by reading the certificate and key from the given file paths.\n * Files are read synchronously at call time.\n *\n * @param certPath Path to the PEM certificate file (e.g. `fullchain.pem`).\n * @param keyPath Path to the PEM private-key file (e.g. `privkey.pem`).\n */\n withTlsFiles(certPath: string, keyPath: string): this {\n return this.withTls(fs.readFileSync(certPath, \"utf8\"), fs.readFileSync(keyPath, \"utf8\"));\n }\n\n /**\n * Sets the path to a user-supplied grammars directory whose\n * `<userAgent>/<locale>.json` files are merged on top of the packaged\n * grammars used by the embedded broker server (the reserved `_broker`\n * provider slot). Typically pointed at `.mcp-broker/grammars/`.\n */\n withBrokerLocalGrammarsDir(dir: string): this {\n this._brokerLocalGrammarsDir = dir;\n return this;\n }\n\n /**\n * Enables OAuth 2.1 resource-server authorization with a pre-resolved config\n * (e.g. a custom {@link IResolvedAuth} carrying your own `ITokenValidator`).\n * Prefer {@link withJwtAuth} for the standard JWKS-backed setup.\n */\n withAuth(auth: IResolvedAuth): this {\n this._auth = auth;\n return this;\n }\n\n /**\n * Enables OAuth 2.1 authorization with the default stateless JWT validator:\n * the broker verifies each bearer token's signature against the authorization\n * server's JWKS and its audience against the slot's canonical resource URI.\n *\n * @throws if `publicBaseUrl`, `authorizationServers`, or `jwksUri` are missing.\n */\n withJwtAuth(options: IJwtAuthOptions): this {\n this._auth = buildJwtAuth(options);\n return this;\n }\n\n /** Installs a custom policy engine behind the broker's transport-neutral API. */\n withPolicyEngine(engine: IPolicyEngine): this {\n this._authorization = authorizationWithEngine(engine, {\n slotResourceResolver: this._slotResourceResolver,\n });\n return this;\n }\n\n /** Compiles and validates roles, assignments, denies, mappings, and paths. */\n withAuthorizationPolicy(config: IAuthorizationPolicyConfig): this {\n this._authorization = compileAuthorizationPolicy(config);\n return this;\n }\n\n /** Overrides the technical slot to hierarchical resource resolution strategy. */\n withSlotResourceResolver(resolver: ISlotResourceResolver): this {\n this._slotResourceResolver = resolver;\n return this;\n }\n\n /**\n * Authenticates providers (engines) with a custom {@link IProviderAuthenticator}.\n * Prefer {@link withProviderSecret} for the standard shared-secret setup.\n */\n withProviderAuth(authenticator: IProviderAuthenticator): this {\n this._providerAuth = authenticator;\n return this;\n }\n\n /**\n * Requires every provider connecting to `/provider/<slot>` or `/providers` to\n * present the given shared secret (via `X-Provider-Token` or `Authorization:\n * Bearer`). Closes off slot occupation by strangers.\n */\n withProviderSecret(secret: string): this {\n this._providerAuth = new SharedSecretProviderAuthenticator(secret);\n return this;\n }\n\n /** Constructs and returns a configured {@link WsTunnel}. */\n build(): WsTunnel {\n const baseAuthorization = this._authorization ?? this._auth?.authorization;\n const authorization = baseAuthorization && this._slotResourceResolver ? { ...baseAuthorization, slotResourceResolver: this._slotResourceResolver } : baseAuthorization;\n const options: IWsTunnelOptions = {\n port: this._port,\n host: this._host,\n providerPath: this._providerPath,\n providersPath: this._providersPath,\n clientPath: this._clientPath,\n ssePath: this._ssePath,\n messagesPath: this._messagesPath,\n mcpPath: this._mcpPath,\n samplesIndexPath: this._samplesIndexPath,\n allowedOrigins: this._allowedOrigins,\n providerHeartbeatIntervalMs: this._providerHeartbeatIntervalMs,\n providerTakeover: this._providerTakeover,\n providerRequestTimeoutMs: this._providerRequestTimeoutMs,\n staticMounts: this._staticMounts.length > 0 ? [...this._staticMounts] : undefined,\n stdioUpstreams: this._stdioUpstreams.length > 0 ? [...this._stdioUpstreams] : undefined,\n remoteUpstreams: this._remoteUpstreams.length > 0 ? [...this._remoteUpstreams] : undefined,\n stdioClient: this._stdioClient,\n tls: this._tls,\n brokerLocalGrammarsDir: this._brokerLocalGrammarsDir,\n auth: this._auth,\n providerAuth: this._providerAuth,\n authorization,\n slotResourceResolver: this._slotResourceResolver ?? authorization?.slotResourceResolver ?? this._auth?.slotResourceResolver,\n };\n return new WsTunnel(options);\n }\n}\n","/**\n * Minimal ZIP extractor for `.mcpb` bundles, built on `node:zlib` only.\n *\n * A `.mcpb` bundle is an ordinary ZIP archive. The broker deliberately avoids\n * the `@anthropic-ai/mcpb` package so it stays compatible with the format\n * without being coupled to Anthropic's tooling, hence this small reader.\n *\n * Supports the two compression methods used in practice: stored (0) and\n * deflate (8). ZIP64 archives are rejected with a clear error (`.mcpb` bundles\n * are small and never need it). Any trailing bytes after the End Of Central\n * Directory record (e.g. a native PKCS#7 signature block) are ignored, since\n * extraction is driven entirely by the central directory.\n */\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\nimport { inflateRawSync } from \"node:zlib\";\n\nconst EOCD_SIGNATURE = 0x06054b50;\nconst CENTRAL_HEADER_SIGNATURE = 0x02014b50;\nconst LOCAL_HEADER_SIGNATURE = 0x04034b50;\n\n/** Locates the End Of Central Directory record by scanning backwards. */\nfunction findEocd(buf: Buffer): number {\n // The EOCD is 22 bytes plus a comment of up to 65535 bytes.\n const minPos = Math.max(0, buf.length - 22 - 0xffff);\n for (let pos = buf.length - 22; pos >= minPos; pos--) {\n if (buf.readUInt32LE(pos) === EOCD_SIGNATURE) return pos;\n }\n throw new Error(\"not a ZIP archive (no End Of Central Directory record found)\");\n}\n\n/**\n * Extracts every entry of the `.mcpb` archive at `mcpbPath` into `destDir`.\n * `destDir` is created if missing. Entries whose resolved path would escape\n * `destDir` (zip-slip) are rejected.\n */\nexport function unzipMcpb(mcpbPath: string, destDir: string): void {\n const buf = readFileSync(mcpbPath);\n const eocd = findEocd(buf);\n\n const totalEntries = buf.readUInt16LE(eocd + 10);\n const centralDirOffset = buf.readUInt32LE(eocd + 16);\n if (centralDirOffset === 0xffffffff || totalEntries === 0xffff) {\n throw new Error(\"ZIP64 archives are not supported\");\n }\n\n const absDest = resolve(destDir);\n mkdirSync(absDest, { recursive: true });\n\n let pos = centralDirOffset;\n for (let i = 0; i < totalEntries; i++) {\n if (buf.readUInt32LE(pos) !== CENTRAL_HEADER_SIGNATURE) {\n throw new Error(`corrupt ZIP: bad central directory header at offset ${pos}`);\n }\n const method = buf.readUInt16LE(pos + 10);\n const compressedSize = buf.readUInt32LE(pos + 20);\n const uncompressedSize = buf.readUInt32LE(pos + 24);\n const nameLen = buf.readUInt16LE(pos + 28);\n const extraLen = buf.readUInt16LE(pos + 30);\n const commentLen = buf.readUInt16LE(pos + 32);\n const localHeaderOffset = buf.readUInt32LE(pos + 42);\n const name = buf.toString(\"utf8\", pos + 46, pos + 46 + nameLen);\n pos += 46 + nameLen + extraLen + commentLen;\n\n if (compressedSize === 0xffffffff || uncompressedSize === 0xffffffff || localHeaderOffset === 0xffffffff) {\n throw new Error(\"ZIP64 archives are not supported\");\n }\n\n // Resolve the destination path and reject zip-slip escapes.\n const target = resolve(absDest, name);\n const rel = relative(absDest, target);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new Error(`unsafe ZIP entry path (zip-slip): ${name}`);\n }\n\n // Directory entry.\n if (name.endsWith(\"/\")) {\n mkdirSync(target, { recursive: true });\n continue;\n }\n\n // Parse the local header to locate the entry's data.\n if (buf.readUInt32LE(localHeaderOffset) !== LOCAL_HEADER_SIGNATURE) {\n throw new Error(`corrupt ZIP: bad local header for \"${name}\"`);\n }\n const localNameLen = buf.readUInt16LE(localHeaderOffset + 26);\n const localExtraLen = buf.readUInt16LE(localHeaderOffset + 28);\n const dataStart = localHeaderOffset + 30 + localNameLen + localExtraLen;\n const compressed = buf.subarray(dataStart, dataStart + compressedSize);\n\n let data: Buffer;\n if (method === 0) {\n data = compressed;\n } else if (method === 8) {\n data = inflateRawSync(compressed);\n } else {\n throw new Error(`unsupported ZIP compression method ${method} for \"${name}\"`);\n }\n\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, data);\n }\n}\n","/**\n * Loads a local `.mcpb` bundle into an {@link IStdioUpstreamConfig}.\n *\n * A `.mcpb` bundle is a ZIP holding a `manifest.json` whose `server.mcp_config`\n * describes a stdio MCP server process. The broker:\n *\n * 1. verifies a **detached signature** of the `.mcpb` file against a trusted\n * public key (PEM), integrity *and* provenance, using `node:crypto` only;\n * 2. unpacks the archive;\n * 3. reads the manifest, expands the `mcp_config` placeholders, and produces a\n * `IStdioUpstreamConfig` that the existing upstream wiring spawns.\n *\n * The broker stays compatible with the `.mcpb` format without depending on the\n * `@anthropic-ai/mcpb` package: the bundle's *own* (native PKCS#7) signature is\n * never parsed: the detached signature layer is the broker's trust anchor.\n *\n * Any failure (missing files, bad signature, malformed manifest, missing\n * `user_config` value) is logged and yields `null`: the bundle is refused and\n * no process is ever spawned. Never auto-runs an unverified bundle.\n */\nimport { createPublicKey, verify, X509Certificate, type KeyObject } from \"node:crypto\";\nimport { existsSync, readFileSync, rmSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve, sep } from \"node:path\";\nimport { unzipMcpb } from \"./mcpb.unzip\";\nimport type { IStdioUpstreamConfig } from \"../stdio.upstream\";\n\n/** A `.mcpb` bundle entry from the broker config file. */\nexport interface IMcpbBundleConfig {\n /** Provider slot name the bundle is bound to. */\n name: string;\n /** Path to the `.mcpb` file. */\n path: string;\n /** Path to the trusted public key (PEM) verifying the detached signature. */\n publicKey: string;\n /** Path to the detached signature file. Defaults to `<path>.sig`. */\n signature?: string;\n /** Values substituted into the manifest's `${user_config.*}` placeholders. */\n userConfig?: Record<string, string | number | boolean | Array<string | number>>;\n /** When `false`, the bundle stays out of the `_all` aggregate slot. Defaults to `true`. */\n aggregate?: boolean;\n}\n\ninterface IMcpConfig {\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n platform_overrides?: Record<string, { command?: string; args?: string[]; env?: Record<string, string> }>;\n}\n\n/** Loads a PEM that holds either an X.509 certificate or a bare public key. */\nfunction loadPublicKey(pem: string): KeyObject {\n if (pem.includes(\"BEGIN CERTIFICATE\")) {\n return new X509Certificate(pem).publicKey;\n }\n return createPublicKey(pem);\n}\n\n/** Verifies the detached `signature` of `data` against `publicKey`. */\nfunction verifyDetachedSignature(data: Buffer, signature: Buffer, publicKey: KeyObject): boolean {\n // Ed25519/Ed448 are used without a separate hash algorithm; RSA/EC need one.\n const keyType = publicKey.asymmetricKeyType;\n const algorithm = keyType === \"ed25519\" || keyType === \"ed448\" ? null : \"sha256\";\n return verify(algorithm, data, publicKey, signature);\n}\n\n/** Resolves a single `${...}` placeholder key, or `undefined` when unknown. */\nfunction resolvePlaceholder(key: string, dirname: string, userConfig: IMcpbBundleConfig[\"userConfig\"]): string | number | boolean | Array<string | number> | undefined {\n if (key === \"__dirname\") return dirname;\n if (key === \"HOME\") return homedir();\n if (key === \"DESKTOP\") return join(homedir(), \"Desktop\");\n if (key === \"DOCUMENTS\") return join(homedir(), \"Documents\");\n if (key === \"DOWNLOADS\") return join(homedir(), \"Downloads\");\n if (key === \"pathSeparator\" || key === \"/\") return sep;\n if (key.startsWith(\"user_config.\")) {\n const name = key.slice(\"user_config.\".length);\n const value = userConfig?.[name];\n if (value === undefined) throw new Error(`missing user_config value: \"${name}\"`);\n return value;\n }\n return undefined;\n}\n\n/** Expands placeholders in a scalar string (command, env value). */\nfunction expandScalar(input: string, dirname: string, userConfig: IMcpbBundleConfig[\"userConfig\"]): string {\n return input.replace(/\\$\\{([^}]+)\\}/g, (match, key: string) => {\n const value = resolvePlaceholder(key, dirname, userConfig);\n if (value === undefined) return match; // unknown placeholder, leave verbatim\n if (Array.isArray(value)) throw new Error(`placeholder \"\\${${key}}\" is multi-valued and cannot be used here`);\n return String(value);\n });\n}\n\n/** Expands one manifest argument; a standalone multi-valued placeholder spreads. */\nfunction expandArg(arg: string, dirname: string, userConfig: IMcpbBundleConfig[\"userConfig\"]): string[] {\n const standalone = /^\\$\\{(user_config\\.[^}]+)\\}$/.exec(arg);\n if (standalone) {\n const value = resolvePlaceholder(standalone[1], dirname, userConfig);\n if (Array.isArray(value)) return value.map(String);\n return [String(value)];\n }\n return [expandScalar(arg, dirname, userConfig)];\n}\n\n/**\n * Verifies, unpacks and resolves a `.mcpb` bundle into an `IStdioUpstreamConfig`.\n *\n * @param cfg The bundle entry from the broker config.\n * @param baseDir Directory the bundle paths are resolved against.\n * @returns A ready upstream config, or `null` when the bundle is refused.\n */\nexport async function loadMcpbBundle(cfg: IMcpbBundleConfig, baseDir: string): Promise<IStdioUpstreamConfig | null> {\n const tag = `[mcp-broker] mcpb bundle \"${cfg.name}\"`;\n try {\n const mcpbPath = resolve(baseDir, cfg.path);\n const publicKeyPath = resolve(baseDir, cfg.publicKey);\n const signaturePath = cfg.signature ? resolve(baseDir, cfg.signature) : `${mcpbPath}.sig`;\n\n for (const [label, file] of [\n [\"bundle\", mcpbPath],\n [\"public key\", publicKeyPath],\n [\"signature\", signaturePath],\n ] as const) {\n if (!existsSync(file)) {\n console.error(`${tag}: ${label} file not found at ${file}, bundle refused.`);\n return null;\n }\n }\n\n // ── Signature verification (mandatory) ──────────────────────────────\n const bundleBytes = readFileSync(mcpbPath);\n const signatureBytes = readFileSync(signaturePath);\n const publicKey = loadPublicKey(readFileSync(publicKeyPath, \"utf8\"));\n if (!verifyDetachedSignature(bundleBytes, signatureBytes, publicKey)) {\n console.error(`${tag}: detached signature is invalid for the configured public key, bundle refused.`);\n return null;\n }\n\n // ── Unpack ──────────────────────────────────────────────────────────\n const outputDir = resolve(baseDir, \".cache\", \"mcpb\", cfg.name);\n rmSync(outputDir, { recursive: true, force: true });\n unzipMcpb(mcpbPath, outputDir);\n\n // ── Manifest → mcp_config ───────────────────────────────────────────\n const manifestPath = join(outputDir, \"manifest.json\");\n if (!existsSync(manifestPath)) {\n console.error(`${tag}: manifest.json missing inside the bundle, bundle refused.`);\n return null;\n }\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as { server?: { mcp_config?: IMcpConfig } };\n const mcpConfig = manifest.server?.mcp_config;\n if (!mcpConfig) {\n console.error(`${tag}: manifest has no server.mcp_config, bundle refused.`);\n return null;\n }\n\n // Platform-specific overrides replace the base fields when present.\n const override = mcpConfig.platform_overrides?.[process.platform];\n const command = override?.command ?? mcpConfig.command;\n const rawArgs = override?.args ?? mcpConfig.args ?? [];\n const rawEnv = { ...mcpConfig.env, ...override?.env };\n if (!command) {\n console.error(`${tag}: manifest mcp_config has no command, bundle refused.`);\n return null;\n }\n\n // ── Placeholder expansion ───────────────────────────────────────────\n const expandedCommand = expandScalar(command, outputDir, cfg.userConfig);\n const expandedArgs = rawArgs.flatMap((arg) => expandArg(arg, outputDir, cfg.userConfig));\n const expandedEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(rawEnv)) {\n expandedEnv[key] = expandScalar(value, outputDir, cfg.userConfig);\n }\n\n return {\n name: cfg.name,\n command: expandedCommand,\n args: expandedArgs,\n env: Object.keys(expandedEnv).length > 0 ? expandedEnv : undefined,\n aggregate: cfg.aggregate ?? true,\n };\n } catch (err) {\n console.error(`${tag}: ${(err as Error).message}, bundle refused.`);\n return null;\n }\n}\n\n/** @deprecated Use {@link IMcpbBundleConfig}. */\nexport type McpbBundleConfig = IMcpbBundleConfig;\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport type { IAuthorizationPolicyConfig } from \"./authorization/index\";\n\nexport interface IBrokerAuthConfig extends IAuthorizationPolicyConfig {\n /** Master switch. Absent/`false` keeps the broker unauthenticated. */\n enabled?: boolean;\n /** Public origin the broker is reached at (e.g. `https://mcp.example.com`). */\n publicBaseUrl?: string;\n /** Authorization server issuer URL(s) advertised in the metadata. */\n authorizationServers?: string[];\n /** URL of the authorization server's JWKS document. */\n jwks?: string;\n /** Expected token issuer. Defaults to the sole `authorizationServers` entry. */\n issuer?: string;\n /** Scopes advertised in the metadata `scopes_supported`. */\n scopesSupported?: string[];\n /** Baseline scope(s) required to reach any slot. */\n requiredScopes?: string[];\n /** Per-slot required-scope overrides (e.g. an admin scope for `_broker`). */\n perSlotScopes?: Record<string, string[]>;\n /**\n * Per-provider scope requirements for the `_all` aggregate. Deprecated in\n * favor of hierarchical policy assignments.\n */\n providerScopes?: Record<string, string[]>;\n /**\n * Shared secret every provider must present to occupy a slot. Independent\n * of client authorization.\n */\n providerSecret?: string;\n}\n\n/**\n * Shape of the optional JSON config file consumed by `bin.ts` at startup.\n * Every field is optional. Environment variables (`MCP_BROKER_*`) always win\n * over file values, and file values win over the built-in defaults.\n *\n * @example\n * ```json\n * {\n * \"port\": 3001,\n * \"locale\": \"fr\",\n * \"tls\": { \"cert\": \"certs/cert.pem\", \"key\": \"certs/key.pem\" },\n * \"stdioUpstreams\": [\n * { \"name\": \"fs\", \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/data\"] }\n * ]\n * }\n * ```\n */\nexport interface IBrokerConfig {\n /** TCP port. Maps to `MCP_BROKER_PORT`. */\n port?: number;\n\n /** Bind host. Maps to `MCP_BROKER_HOST`. */\n host?: string;\n\n /** Force protocol (`http`/`https`) regardless of cert presence. Maps to `MCP_BROKER_PROTOCOL`. */\n protocol?: \"http\" | \"https\";\n\n /** Locale fed to the broker grammar resolver. Maps to `MCP_BROKER_LOCALE`. */\n locale?: string;\n\n /** Bridge stdin/stdout for a Claude-Desktop-style client. Maps to `MCP_BROKER_STDIO_PROVIDER`. */\n stdioProvider?: string;\n\n /**\n * Logical broker name reported by `broker_info`.\n *\n * **Library-only today.** `WsTunnel` honors it\n * (`IWsTunnelOptions.brokerName`), but `WsTunnelBuilder` has no\n * `withBrokerName()`, so the CLI cannot forward it and setting it in\n * `config.json` has no effect. Set it through the programmatic API until\n * the setter exists.\n */\n brokerName?: string;\n\n /**\n * How often (ms) the broker pings each connected provider socket to check\n * it is still there. `0` disables the heartbeat. Maps to\n * `MCP_BROKER_PROVIDER_HEARTBEAT_MS`.\n *\n * A provider that misses a full interval is terminated and its slot freed,\n * which is what stops a half-open socket (a killed browser tab, a slept\n * laptop, a dropped VPN) from holding a slot for the ~2 hours the OS takes\n * to give up on the TCP connection, refusing every reconnect meanwhile.\n *\n * @default 30000\n */\n providerHeartbeatIntervalMs?: number;\n\n /**\n * How long (ms) the broker waits for a provider to answer one request\n * before failing it with a JSON-RPC error naming the slot. `0` disables the\n * deadline. Maps to `MCP_BROKER_PROVIDER_REQUEST_TIMEOUT_MS`.\n *\n * Raise it if you host genuinely long-running tools; without it a provider\n * that stays connected and never answers (a throttled background browser\n * tab is the ordinary case) leaves the caller waiting forever.\n *\n * @default 60000\n */\n providerRequestTimeoutMs?: number;\n\n /**\n * What happens when a provider connects to a slot another socket already\n * holds. Maps to `MCP_BROKER_PROVIDER_TAKEOVER`.\n *\n * - `\"reject\"`: the incumbent always keeps the slot.\n * - `\"liveness\"` (default): the incumbent keeps it only while it answers\n * the heartbeat.\n * - `\"always\"`: the newcomer wins, but only when provider authentication is\n * configured and it authenticated as the same principal as the incumbent.\n * Without provider auth the broker falls back to `\"liveness\"` and says so,\n * because unconditional takeover would let anyone who can reach the URL\n * evict the real provider.\n *\n * @default \"liveness\"\n */\n providerTakeover?: \"reject\" | \"liveness\" | \"always\";\n\n /**\n * Browser origins allowed to reach `/<slot>/mcp`.\n *\n * Absent means no browser origin is accepted: a request carrying an\n * `Origin` header gets `403`, one carrying none (Claude Desktop, MCP\n * Inspector, any server-side SDK) always passes. The MCP specification asks\n * for this check, since without it any web page loaded in a browser that\n * can reach the broker could drive it.\n *\n * An array lists origins matched **exactly**. An object supplies a regular\n * expression tested against the whole `Origin` header. Also maps to\n * `MCP_BROKER_ALLOWED_ORIGINS` (comma-separated list form only; a pattern\n * needs the config file).\n *\n * @example\n * ```json\n * { \"allowedOrigins\": [\"https://app.example.com\", \"http://localhost:5173\"] }\n * { \"allowedOrigins\": { \"pattern\": \"^https://[a-z0-9-]+\\\\.example\\\\.com$\" } }\n * ```\n */\n allowedOrigins?: string[] | { pattern: string; flags?: string };\n\n /**\n * OAuth 2.1 resource-server authorization. When `enabled` is `true`, every\n * HTTP client request to a slot must carry a valid `Authorization: Bearer`\n * token issued for that slot, and the broker publishes Protected Resource\n * Metadata (RFC 9728). Absent/`false` ⇒ no authentication (trusted-network\n * mode, the historical behavior).\n *\n * Scalars also map to env vars (which win): `MCP_BROKER_AUTH_ENABLED`,\n * `MCP_BROKER_PUBLIC_BASE_URL`, `MCP_BROKER_JWKS`, `MCP_BROKER_ISSUER`.\n */\n auth?: IBrokerAuthConfig;\n\n /**\n * URL paths (override the defaults). Every key is also settable through an\n * environment variable, which wins.\n *\n * Changing one moves an endpoint for **every** peer: a provider SDK, a\n * client, and the startup banner all have to agree. The two provider paths\n * are not interchangeable, they carry different framing:\n * `provider` is a prefix (`<provider>/<slot>`) speaking plain JSON-RPC\n * frames (`DirectTransport`), `providers` is matched exactly and speaks\n * multiplex envelopes (`MultiplexTransport`).\n */\n paths?: {\n /** Prefix for one-slot-per-socket provider connections. Maps to `MCP_BROKER_PROVIDER_PATH`. @default \"/provider\" */\n provider?: string;\n /** Exact path for multiplexed provider connections. Maps to `MCP_BROKER_PROVIDERS_PATH`. @default \"/providers\" */\n providers?: string;\n /** Prefix raw-WebSocket clients connect to. Maps to `MCP_BROKER_CLIENT_PATH`. @default \"/\" */\n client?: string;\n /** Per-slot suffix for the Streamable HTTP transport. Maps to `MCP_BROKER_MCP_PATH`. @default \"/mcp\" */\n mcp?: string;\n /** Per-slot suffix for the legacy SSE stream (GET). Maps to `MCP_BROKER_SSE_PATH`. @default \"/sse\" */\n sse?: string;\n /** Per-slot suffix for legacy SSE JSON-RPC posts. Maps to `MCP_BROKER_MESSAGES_PATH`. @default \"/messages\" */\n messages?: string;\n };\n\n /** TLS material as paths on disk. Resolved against the config file's directory. */\n tls?: {\n cert: string;\n key: string;\n };\n\n /**\n * Static-file serving alongside the JSON-RPC endpoints. JSON-RPC routes\n * always take precedence.\n */\n www?: {\n /**\n * Auto-launch the default browser on startup. Maps to `MCP_BROKER_OPEN`.\n *\n * - `false` / absent / `\"\"` / `\"0\"`: do not open anything.\n * - `true` / `\"1\"`: open the broker root, `<scheme>://localhost:<port>/`.\n * - a path (`\"/app/index.html\"`): open that page on this broker.\n * - an absolute URL on this broker's own origin: opened as given.\n *\n * A URL on any other origin is refused with a message, and so is any\n * other string. See {@link resolveOpenTarget} for why.\n *\n * The browser opens only when a static mount actually covers the\n * resolved path; otherwise the broker says which mounts exist instead of\n * launching a browser onto a 404.\n */\n open?: boolean | string;\n /** URL-prefix → directory mappings. Longest-prefix match wins. */\n mounts?: Array<{\n urlPrefix: string;\n dir: string;\n }>;\n };\n\n /** Stdio upstream providers spawned by the broker at startup. */\n stdioUpstreams?: Array<{\n name: string;\n command: string;\n args?: string[];\n env?: Record<string, string>;\n /** When `true`, the upstream joins the `_all` aggregate slot once connected. */\n aggregate?: boolean;\n }>;\n\n /**\n * Remote MCP servers the broker connects out to and exposes as provider\n * slots. Each entry is reached by URL (Streamable HTTP / SSE / WebSocket);\n * local servers should be shipped as `.mcpb` bundles instead.\n */\n mcpServers?: Array<{\n name: string;\n url: string;\n transport?: \"streamable-http\" | \"sse\" | \"websocket\";\n headers?: Record<string, string>;\n /** Defaults to `true`; set to `false` to exclude this upstream from the `_all` aggregate slot. */\n aggregate?: boolean;\n }>;\n\n /**\n * Local `.mcpb` bundles the broker loads at startup and runs as stdio\n * provider slots. A bundle is a ZIP with a `manifest.json`; the broker\n * verifies a detached signature against a trusted public key before\n * unpacking and spawning it.\n */\n mcpbBundles?: Array<{\n /** Provider slot name the bundle is bound to. */\n name: string;\n /** Path to the `.mcpb` file (resolved against the config file's directory). */\n path: string;\n /** Path to the trusted public key (PEM) used to verify the detached signature. */\n publicKey: string;\n /** Path to the detached signature file. Defaults to `<path>.sig`. */\n signature?: string;\n /** Values substituted into the manifest's `${user_config.*}` placeholders. */\n userConfig?: Record<string, string | number | boolean | Array<string | number>>;\n /** Defaults to `true`; set to `false` to exclude this bundle from the `_all` aggregate slot. */\n aggregate?: boolean;\n }>;\n}\n\n/**\n * Returned by {@link loadBrokerConfig}. The {@link config} is the parsed JSON;\n * {@link baseDir} is the directory used to resolve relative paths inside it\n * (the directory containing the config file when one was found, otherwise\n * `process.cwd()`).\n */\nexport interface ILoadedBrokerConfig {\n config: IBrokerConfig;\n baseDir: string;\n /** Absolute path of the config file that was loaded, or `null` if none. */\n sourcePath: string | null;\n}\n\n/** Default folder name (relative to `process.cwd()`) holding broker-local files. */\nexport const DEFAULT_CONFIG_DIR = \".mcp-broker\";\n\n/** Default config filename inside {@link DEFAULT_CONFIG_DIR}. */\nexport const DEFAULT_CONFIG_FILENAME = \"config.json\";\n\n/** Legacy flat config filename at the cwd root (pre-`.mcp-broker/` layout). */\nexport const LEGACY_CONFIG_FILENAME = \"mcp-broker.config.json\";\n\n/**\n * Loads the broker config from a JSON file.\n *\n * Discovery order:\n * 1. The `path` argument when provided (explicit override).\n * 2. The `MCP_BROKER_CONFIG` env var.\n * 3. `./.mcp-broker/config.json` relative to `process.cwd()`.\n * 4. `./mcp-broker.config.json` relative to `process.cwd()` (legacy layout ,\n * a deprecation warning is written to stderr).\n *\n * When no file is found, returns the built-in empty config with\n * `baseDir = process.cwd()`. On invalid JSON, logs a warning to stderr and\n * returns the same empty config, never throws.\n *\n * Paths inside the config file are intended to be resolved against\n * {@link ILoadedBrokerConfig.baseDir} by the consumer.\n */\nexport function loadBrokerConfig(path?: string): ILoadedBrokerConfig {\n const cwd = process.cwd();\n const envPath = process.env[\"MCP_BROKER_CONFIG\"];\n\n let sourcePath: string | null = null;\n\n if (path) {\n sourcePath = resolve(cwd, path);\n } else if (envPath) {\n sourcePath = resolve(cwd, envPath);\n } else {\n const modern = resolve(cwd, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME);\n const legacy = resolve(cwd, LEGACY_CONFIG_FILENAME);\n if (existsSync(modern)) {\n sourcePath = modern;\n } else if (existsSync(legacy)) {\n sourcePath = legacy;\n process.stderr.write(\n `[mcp-broker] Using legacy config at ${legacy}. ` + `Move it to ${resolve(cwd, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME)} ` + `to silence this warning.\\n`\n );\n }\n }\n\n if (!sourcePath || !existsSync(sourcePath)) {\n return { config: {}, baseDir: cwd, sourcePath: null };\n }\n\n const baseDir = dirname(sourcePath);\n\n try {\n const raw = readFileSync(sourcePath, \"utf-8\");\n const config = JSON.parse(raw) as IBrokerConfig;\n return { config, baseDir, sourcePath };\n } catch (err) {\n process.stderr.write(`[mcp-broker] Failed to parse config file at ${sourcePath}: ${(err as Error).message}\\n`);\n return { config: {}, baseDir: cwd, sourcePath: null };\n }\n}\n\n/**\n * Outcome of {@link resolveOpenTarget}. Exactly one of the three states holds:\n *\n * - `{ url: null, path: null }` and no `error`: nothing should be opened.\n * - `{ url, path }`: open `url`; `path` is what a static mount has to cover.\n * - `{ url: null, path: null, error }`: the value was refused, `error` is a\n * sentence to print verbatim that names both the fault and the fix.\n */\nexport interface IOpenTargetResolution {\n /** Absolute URL to hand to the platform opener, or `null` to open nothing. */\n url: string | null;\n /** Path portion of {@link url} (always starts with `/`), or `null`. */\n path: string | null;\n /** Set when the raw value was refused. Human-readable, names the fix. */\n error?: string;\n}\n\n/**\n * Resolves `www.open` / `MCP_BROKER_OPEN` into an absolute URL to launch.\n *\n * Lives here rather than in `bin.ts` because `bin.ts` starts a server the\n * moment it is imported, so nothing in it can be unit-tested.\n *\n * Accepted forms (leading/trailing whitespace is trimmed):\n *\n * | `raw` | result |\n * |----------------------------|-------------------------------------------|\n * | `undefined`, `false`, `\"\"`, `\"0\"`, `\"false\"` | open nothing |\n * | `true`, `\"1\"`, `\"true\"` | `<baseUrl>/` |\n * | `\"/app/\"`, `\"/index.html\"` | resolved against `baseUrl` |\n * | `\"http://localhost:3000/x\"`| passed through when the origin is `baseUrl`'s |\n * | anything else | refused, with `error` explaining why |\n *\n * Two refusals are security-load-bearing rather than pedantic:\n *\n * - **A foreign origin is refused.** Auto-opening is a startup convenience, and\n * a config file (or an env var inherited from a parent process) that can make\n * the broker launch a browser at an arbitrary site is a phishing primitive\n * with no upside: nothing about starting a broker requires visiting another\n * host. Open it yourself, or point `open` at a page this broker serves.\n * - **`//host/path` is refused** even though it starts with `/`: it is a\n * protocol-relative URL, so `new URL(\"//evil.example/x\", base)` resolves to\n * `evil.example` and a naive \"starts with a slash so it is local\" test lets\n * it through.\n *\n * Anything that is neither is refused rather than forwarded, because the\n * platform opener performs no validation of its own: a typo'd relative path is\n * handed to the shell and can launch a local file or a registered application.\n *\n * @param raw The configured value (`config.www.open`) or the raw env string.\n * @param baseUrl Origin this broker is reachable at, e.g. `http://localhost:3000`.\n */\nexport function resolveOpenTarget(raw: boolean | string | undefined | null, baseUrl: string): IOpenTargetResolution {\n const nothing: IOpenTargetResolution = { url: null, path: null };\n\n if (raw === undefined || raw === null || raw === false) return nothing;\n if (raw === true) return resolveOpenTarget(\"/\", baseUrl);\n\n const value = String(raw).trim();\n if (value === \"\" || value === \"0\" || value === \"false\") return nothing;\n if (value === \"1\" || value === \"true\") return resolveOpenTarget(\"/\", baseUrl);\n\n const refuse = (why: string): IOpenTargetResolution => ({\n url: null,\n path: null,\n error:\n `${why} Set it to true (or \"1\") for the broker root, to a path on this broker such as \"/app/index.html\", ` +\n `or to an absolute URL on ${baseUrl}. Leave it out to open nothing.`,\n });\n\n // Protocol-relative: starts with a slash but resolves off-origin.\n if (value.startsWith(\"//\")) {\n return refuse(`Refusing to open \"${value}\": a value starting with \"//\" is a protocol-relative URL and points at another host, not at this broker.`);\n }\n\n // Only two spellings are accepted, so that a bare word (almost always a\n // typo) is reported rather than silently resolved onto the broker root.\n const isAbsolutePath = value.startsWith(\"/\");\n const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value);\n if (!isAbsolutePath && !hasScheme) {\n return refuse(`Refusing to open \"${value}\": it is neither a path starting with \"/\" nor an absolute http(s) URL.`);\n }\n\n let resolved: URL;\n try {\n resolved = new URL(value, baseUrl);\n } catch {\n return refuse(`Refusing to open \"${value}\": it is not a valid path or URL.`);\n }\n\n if (hasScheme) {\n // Decide on the parsed form, not on the raw string: `localhost:3000/x`\n // looks like a host but parses with the scheme `localhost:`.\n if (resolved.protocol !== \"http:\" && resolved.protocol !== \"https:\") {\n return refuse(`Refusing to open \"${value}\": only http and https URLs are opened, and \"${resolved.protocol}\" is neither.`);\n }\n const base = new URL(baseUrl);\n if (resolved.origin !== base.origin) {\n return refuse(`Refusing to open \"${value}\": it points at ${resolved.origin}, which is not this broker (${base.origin}).`);\n }\n }\n\n return { url: resolved.toString(), path: resolved.pathname };\n}\n\n/** @deprecated Use {@link IBrokerAuthConfig}. */\nexport type BrokerAuthConfig = IBrokerAuthConfig;\n\n/** @deprecated Use {@link IBrokerConfig}. */\nexport type BrokerConfig = IBrokerConfig;\n\n/** @deprecated Use {@link ILoadedBrokerConfig}. */\nexport type LoadedBrokerConfig = ILoadedBrokerConfig;\n"]}