@apnex/network-adapter 0.1.0

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.
Files changed (52) hide show
  1. package/dist/hub-error.d.ts +42 -0
  2. package/dist/hub-error.js +74 -0
  3. package/dist/hub-error.js.map +1 -0
  4. package/dist/index.d.ts +29 -0
  5. package/dist/index.js +31 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/kernel/agent-client.d.ts +192 -0
  8. package/dist/kernel/agent-client.js +44 -0
  9. package/dist/kernel/agent-client.js.map +1 -0
  10. package/dist/kernel/event-router.d.ts +49 -0
  11. package/dist/kernel/event-router.js +150 -0
  12. package/dist/kernel/event-router.js.map +1 -0
  13. package/dist/kernel/handshake.d.ts +161 -0
  14. package/dist/kernel/handshake.js +257 -0
  15. package/dist/kernel/handshake.js.map +1 -0
  16. package/dist/kernel/instance.d.ts +40 -0
  17. package/dist/kernel/instance.js +79 -0
  18. package/dist/kernel/instance.js.map +1 -0
  19. package/dist/kernel/mcp-agent-client.d.ts +139 -0
  20. package/dist/kernel/mcp-agent-client.js +505 -0
  21. package/dist/kernel/mcp-agent-client.js.map +1 -0
  22. package/dist/kernel/poll-backstop.d.ts +108 -0
  23. package/dist/kernel/poll-backstop.js +243 -0
  24. package/dist/kernel/poll-backstop.js.map +1 -0
  25. package/dist/kernel/session-claim.d.ts +67 -0
  26. package/dist/kernel/session-claim.js +106 -0
  27. package/dist/kernel/session-claim.js.map +1 -0
  28. package/dist/kernel/state-sync.d.ts +43 -0
  29. package/dist/kernel/state-sync.js +85 -0
  30. package/dist/kernel/state-sync.js.map +1 -0
  31. package/dist/logger.d.ts +82 -0
  32. package/dist/logger.js +114 -0
  33. package/dist/logger.js.map +1 -0
  34. package/dist/notification-log.d.ts +29 -0
  35. package/dist/notification-log.js +66 -0
  36. package/dist/notification-log.js.map +1 -0
  37. package/dist/prompt-format.d.ts +38 -0
  38. package/dist/prompt-format.js +220 -0
  39. package/dist/prompt-format.js.map +1 -0
  40. package/dist/tool-manager/dispatcher.d.ts +180 -0
  41. package/dist/tool-manager/dispatcher.js +379 -0
  42. package/dist/tool-manager/dispatcher.js.map +1 -0
  43. package/dist/tool-manager/tool-catalog-cache.d.ts +85 -0
  44. package/dist/tool-manager/tool-catalog-cache.js +137 -0
  45. package/dist/tool-manager/tool-catalog-cache.js.map +1 -0
  46. package/dist/wire/mcp-transport.d.ts +120 -0
  47. package/dist/wire/mcp-transport.js +447 -0
  48. package/dist/wire/mcp-transport.js.map +1 -0
  49. package/dist/wire/transport.d.ts +174 -0
  50. package/dist/wire/transport.js +43 -0
  51. package/dist/wire/transport.js.map +1 -0
  52. package/package.json +32 -0
@@ -0,0 +1,447 @@
1
+ /**
2
+ * McpTransport — first `ITransport` implementation, backed by the MCP
3
+ * SDK's `Client` + `StreamableHTTPClientTransport`.
4
+ *
5
+ * Phase 2 of the L4/L7 refactor: extracted alongside the existing
6
+ * `McpConnectionManager`, which stays intact for the rest of the
7
+ * migration. Nothing in the current runtime uses this file yet — it
8
+ * exists so the Phase-2 gap tests can exercise the L4 surface in
9
+ * isolation and prove the split holds before Phase 3 relocates the
10
+ * session FSM.
11
+ *
12
+ * ## What this class owns (L4)
13
+ *
14
+ * - The MCP wire: SDK `Client` + `StreamableHTTPClientTransport`.
15
+ * - SSE liveness: first-keepalive deadline, mid-stream watchdog,
16
+ * heartbeat POST loop.
17
+ * - Wire-level reconnection: on SSE death or heartbeat failure it
18
+ * tears down the SDK client and rebuilds a fresh one. Callers see
19
+ * only `reconnecting` + `reconnected` wire events.
20
+ * - Untyped `request(method, params)` over MCP `callTool`.
21
+ * - `listMethods()` via MCP `listTools`.
22
+ *
23
+ * ## What this class deliberately does NOT own
24
+ *
25
+ * - `register_role`. The bare register_role call that the legacy
26
+ * `McpConnectionManager` fires during `connect()` is a session
27
+ * concern — it binds the MCP session to an engineer role on the
28
+ * Hub. `McpTransport.connect()` returns once the MCP wire is
29
+ * initialized, *without* calling register_role. The caller
30
+ * (future `IAgentClient`) issues the role call via
31
+ * `transport.request("register_role", {role})` itself.
32
+ * - Session FSM. No synchronizing / streaming vocabulary, no
33
+ * sync buffer, no `completeSync()`.
34
+ * - `session_invalid` classification and retry. Callers see the
35
+ * raw error from `request()` and reconnect at the session layer.
36
+ *
37
+ * ## Hub-event push delivery
38
+ *
39
+ * SSE notifications land on the MCP client's `LoggingMessageNotification`
40
+ * handler. This class splits them into two streams:
41
+ *
42
+ * - `logger === "keepalive"` frames feed the SSE watchdog and are
43
+ * NOT forwarded to subscribers — they are wire noise.
44
+ * - `logger === "hub-event"` frames are emitted as
45
+ * `{ type: "push", method: "hub-event", payload }` via the
46
+ * `onWireEvent` stream. Classification, dedup, and routing happen
47
+ * above this layer.
48
+ */
49
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
50
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
51
+ import { LoggingMessageNotificationSchema } from "@modelcontextprotocol/sdk/types.js";
52
+ import { normalizeToILogger } from "../logger.js";
53
+ /**
54
+ * Wire-level reconnect backoff curve. Pure function so the invariant
55
+ * (start at `baseDelay`, double each consecutive failure, clamp at
56
+ * `maxDelay`) is unit-testable without spinning a real wire.
57
+ *
58
+ * The cap on the exponent (`6`) matches the legacy manager: after six
59
+ * consecutive failures we're pegged at 60s and further failures don't
60
+ * push the delay higher — they just sit at the cap until a keepalive
61
+ * arrives and resets `consecutiveReconnects` to zero.
62
+ */
63
+ export function computeReconnectBackoff(consecutiveReconnects, baseDelay, maxDelay = 60_000) {
64
+ const exp = Math.min(Math.max(consecutiveReconnects, 0), 6);
65
+ return Math.min(baseDelay * Math.pow(2, exp), maxDelay);
66
+ }
67
+ export class McpTransport {
68
+ cfg;
69
+ log;
70
+ client = null;
71
+ sdkTransport = null;
72
+ _wireState = "disconnected";
73
+ handlers = [];
74
+ // SSE liveness
75
+ lastKeepaliveAt = 0;
76
+ sseVerified = false;
77
+ // Timers
78
+ heartbeatTimer = null;
79
+ sseWatchdogTimer = null;
80
+ firstKeepaliveTimer = null;
81
+ reconnectTimer = null;
82
+ // Metrics
83
+ totalReconnects = 0;
84
+ consecutiveReconnects = 0;
85
+ lastReconnectCause;
86
+ requestsInFlight = 0;
87
+ // Re-entrancy guard: prevents overlapping reconnects.
88
+ reconnecting = false;
89
+ // True once `close()` was called — suppresses further reconnect attempts.
90
+ closed = false;
91
+ constructor(config) {
92
+ this.cfg = {
93
+ url: config.url,
94
+ token: config.token,
95
+ heartbeatInterval: config.heartbeatInterval ?? 30_000,
96
+ sseKeepaliveTimeout: config.sseKeepaliveTimeout ?? 90_000,
97
+ firstKeepaliveDeadline: config.firstKeepaliveDeadline ?? 60_000,
98
+ sseWatchdogInterval: config.sseWatchdogInterval ?? 30_000,
99
+ reconnectDelay: config.reconnectDelay ?? 5_000,
100
+ getLastEventId: config.getLastEventId,
101
+ };
102
+ this.log = normalizeToILogger(config.logger, "McpTransport");
103
+ }
104
+ // ── ITransport: public surface ──────────────────────────────────────
105
+ get wireState() {
106
+ return this._wireState;
107
+ }
108
+ async connect() {
109
+ if (this._wireState === "connected" || this._wireState === "connecting") {
110
+ this.log.log("transport.connect.ignored", { wireState: this._wireState }, `connect() ignored in wireState=${this._wireState}`);
111
+ return;
112
+ }
113
+ this.closed = false;
114
+ this.transition("connecting");
115
+ try {
116
+ await this.createWire();
117
+ this.transition("connected");
118
+ this.startHeartbeat();
119
+ this.startSseWatchdog();
120
+ this.startFirstKeepaliveDeadline();
121
+ }
122
+ catch (err) {
123
+ this.log.log("transport.connect.failed", { error: String(err) }, `connect failed: ${err}`);
124
+ this.transition("disconnected");
125
+ throw err;
126
+ }
127
+ }
128
+ async close() {
129
+ this.closed = true;
130
+ this.cancelReconnectTimer();
131
+ this.stopHeartbeat();
132
+ this.stopSseWatchdog();
133
+ this.cancelFirstKeepaliveDeadline();
134
+ const wasConnected = this._wireState !== "disconnected";
135
+ this.transition("disconnected");
136
+ await this.teardownWire();
137
+ if (wasConnected) {
138
+ this.emit({ type: "closed", reason: "caller-closed" });
139
+ }
140
+ }
141
+ async request(method, params) {
142
+ if (this._wireState !== "connected" || !this.client) {
143
+ throw new Error(`McpTransport.request: wire is ${this._wireState}`);
144
+ }
145
+ this.requestsInFlight++;
146
+ try {
147
+ const result = await this.client.callTool({
148
+ name: method,
149
+ arguments: params,
150
+ });
151
+ const content = result.content;
152
+ if (content?.[0]?.text) {
153
+ try {
154
+ return JSON.parse(content[0].text);
155
+ }
156
+ catch {
157
+ return content[0].text;
158
+ }
159
+ }
160
+ return null;
161
+ }
162
+ finally {
163
+ this.requestsInFlight--;
164
+ }
165
+ }
166
+ async listMethods() {
167
+ if (this._wireState !== "connected" || !this.client)
168
+ return [];
169
+ try {
170
+ const { tools } = await this.client.listTools();
171
+ return tools.map((t) => t.name);
172
+ }
173
+ catch {
174
+ return [];
175
+ }
176
+ }
177
+ /**
178
+ * Escape hatch for shims that need full MCP tool definitions
179
+ * (name + inputSchema + description), not just method names.
180
+ * Consumed by proxy shims that re-advertise the Hub's tool surface
181
+ * to another MCP client (e.g. Claude Code stdio proxy).
182
+ */
183
+ async listToolsRaw() {
184
+ if (this._wireState !== "connected" || !this.client)
185
+ return [];
186
+ try {
187
+ const { tools } = await this.client.listTools();
188
+ return tools;
189
+ }
190
+ catch {
191
+ return [];
192
+ }
193
+ }
194
+ onWireEvent(handler) {
195
+ this.handlers.push(handler);
196
+ }
197
+ getMetrics() {
198
+ return {
199
+ wireState: this._wireState,
200
+ totalReconnects: this.totalReconnects,
201
+ consecutiveReconnects: this.consecutiveReconnects,
202
+ lastReconnectCause: this.lastReconnectCause,
203
+ lastKeepaliveAt: this.lastKeepaliveAt || undefined,
204
+ requestsInFlight: this.requestsInFlight,
205
+ };
206
+ }
207
+ /**
208
+ * Test-only helper. Session IDs are an MCP-specific concept exposed
209
+ * here so Phase-2 integration tests can assert that a wire reconnect
210
+ * rebuilds the session. Not part of `ITransport`.
211
+ */
212
+ getSessionId() {
213
+ return this.sdkTransport?.sessionId ?? undefined;
214
+ }
215
+ // ── Internal: wire lifecycle ────────────────────────────────────────
216
+ async createWire() {
217
+ const headers = {
218
+ "Content-Type": "application/json",
219
+ Accept: "application/json, text/event-stream",
220
+ };
221
+ if (this.cfg.token) {
222
+ headers["Authorization"] = `Bearer ${this.cfg.token}`;
223
+ }
224
+ // Mission-56 W2.2: attach `Last-Event-ID` when the layer above
225
+ // (McpAgentClient) has observed at least one Hub event. The Hub's
226
+ // W1b wrapper backfills Messages with id > lastEventId before
227
+ // resuming live emit. Cold-start (provider returns undefined or no
228
+ // provider configured) falls through to the stream-all-with-soft-cap
229
+ // path on the Hub side.
230
+ const lastEventId = this.cfg.getLastEventId?.();
231
+ if (lastEventId !== undefined && lastEventId !== "") {
232
+ headers["Last-Event-ID"] = lastEventId;
233
+ }
234
+ // Same rationale as McpConnectionManager: disable the SDK's
235
+ // internal SSE reconnection so our watchdog is the single authority
236
+ // for liveness. A split-brain where the SDK reopens the stream
237
+ // internally would leave our notification handler wired to the
238
+ // dead one.
239
+ this.sdkTransport = new StreamableHTTPClientTransport(new URL(this.cfg.url), {
240
+ requestInit: { headers },
241
+ reconnectionOptions: {
242
+ initialReconnectionDelay: 1000,
243
+ maxReconnectionDelay: 30_000,
244
+ reconnectionDelayGrowFactor: 1.5,
245
+ maxRetries: 0,
246
+ },
247
+ });
248
+ this.client = new Client({ name: "ois-mcp-transport", version: "1.0.0" }, { capabilities: {} });
249
+ this.sseVerified = false;
250
+ this.lastKeepaliveAt = 0;
251
+ this.client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => {
252
+ const params = notification.params;
253
+ if (!params)
254
+ return;
255
+ if (params.logger === "keepalive") {
256
+ this.lastKeepaliveAt = Date.now();
257
+ if (!this.sseVerified) {
258
+ this.sseVerified = true;
259
+ this.cancelFirstKeepaliveDeadline();
260
+ this.log.log("transport.sse.verified", undefined, "SSE verified (first keepalive received)");
261
+ }
262
+ return;
263
+ }
264
+ if (params.logger === "hub-event" && params.data) {
265
+ this.emit({
266
+ type: "push",
267
+ method: "hub-event",
268
+ payload: params.data,
269
+ });
270
+ }
271
+ });
272
+ this.sdkTransport.onclose = () => {
273
+ this.log.log("transport.sdk.onclose", undefined, "SDK transport onclose fired");
274
+ if (this._wireState === "connected") {
275
+ void this.reconnectWire("peer_closed");
276
+ }
277
+ };
278
+ this.sdkTransport.onerror = (err) => {
279
+ this.log.log("transport.sdk.onerror", { error: err?.message || String(err) }, `SDK transport onerror: ${err?.message || err}`);
280
+ if (this._wireState === "connected") {
281
+ void this.reconnectWire("wire_error");
282
+ }
283
+ };
284
+ this.client.onerror = (err) => {
285
+ this.log.log("transport.client.onerror", { error: err?.message || String(err) }, `SDK client onerror: ${err?.message || err}`);
286
+ };
287
+ await this.client.connect(this.sdkTransport);
288
+ this.log.log("transport.wire.initialized", undefined, "MCP wire initialized");
289
+ }
290
+ async teardownWire() {
291
+ const oldClient = this.client;
292
+ this.client = null;
293
+ this.sdkTransport = null;
294
+ this.stopHeartbeat();
295
+ this.stopSseWatchdog();
296
+ this.cancelFirstKeepaliveDeadline();
297
+ if (oldClient) {
298
+ try {
299
+ await oldClient.close();
300
+ }
301
+ catch {
302
+ // expected on dead wires
303
+ }
304
+ }
305
+ // Let any in-flight SSE callbacks settle before the next wire opens.
306
+ await new Promise((resolve) => setTimeout(resolve, 1000));
307
+ }
308
+ /**
309
+ * Wire-level reconnect loop. Entered on any wire-death signal
310
+ * (SSE drop, heartbeat failure, transport error). Emits
311
+ * `reconnecting` + (on success) `reconnected` wire events so the
312
+ * AgentClient above can re-run its L7 handshake.
313
+ */
314
+ async reconnectWire(cause) {
315
+ if (this.reconnecting || this.closed)
316
+ return;
317
+ this.reconnecting = true;
318
+ this.totalReconnects++;
319
+ this.consecutiveReconnects++;
320
+ this.lastReconnectCause = cause;
321
+ this.log.log("transport.reconnect.start", { cause, consecutive: this.consecutiveReconnects }, `reconnectWire: cause=${cause}, consecutive=${this.consecutiveReconnects}`);
322
+ this.emit({ type: "reconnecting", cause });
323
+ this.transition("connecting");
324
+ await this.teardownWire();
325
+ try {
326
+ await this.createWire();
327
+ if (this.closed) {
328
+ // close() called mid-reconnect — bail out.
329
+ await this.teardownWire();
330
+ this.transition("disconnected");
331
+ return;
332
+ }
333
+ this.transition("connected");
334
+ this.startHeartbeat();
335
+ this.startSseWatchdog();
336
+ this.startFirstKeepaliveDeadline();
337
+ this.emit({ type: "reconnected" });
338
+ }
339
+ catch (err) {
340
+ this.log.log("transport.reconnect.failed", { cause, error: String(err) }, `reconnectWire failed: ${err}`);
341
+ this.transition("disconnected");
342
+ this.scheduleReconnectTimer(cause);
343
+ }
344
+ finally {
345
+ this.reconnecting = false;
346
+ }
347
+ }
348
+ scheduleReconnectTimer(cause) {
349
+ if (this.closed)
350
+ return;
351
+ this.cancelReconnectTimer();
352
+ const backoff = computeReconnectBackoff(this.consecutiveReconnects, this.cfg.reconnectDelay);
353
+ this.log.log("transport.reconnect.retry_scheduled", { cause, backoffMs: backoff }, `scheduling retry in ${backoff}ms`);
354
+ this.reconnectTimer = setTimeout(() => {
355
+ this.reconnectTimer = null;
356
+ void this.reconnectWire(cause);
357
+ }, backoff);
358
+ }
359
+ cancelReconnectTimer() {
360
+ if (this.reconnectTimer) {
361
+ clearTimeout(this.reconnectTimer);
362
+ this.reconnectTimer = null;
363
+ }
364
+ }
365
+ // ── Internal: liveness timers ───────────────────────────────────────
366
+ startHeartbeat() {
367
+ this.stopHeartbeat();
368
+ this.heartbeatTimer = setInterval(async () => {
369
+ if (this._wireState !== "connected" || !this.client)
370
+ return;
371
+ try {
372
+ await this.client.listTools();
373
+ }
374
+ catch {
375
+ this.log.log("transport.heartbeat.failed", undefined, "heartbeat failed, triggering wire reconnect");
376
+ void this.reconnectWire("heartbeat_failed");
377
+ }
378
+ }, this.cfg.heartbeatInterval);
379
+ }
380
+ stopHeartbeat() {
381
+ if (this.heartbeatTimer) {
382
+ clearInterval(this.heartbeatTimer);
383
+ this.heartbeatTimer = null;
384
+ }
385
+ }
386
+ startSseWatchdog() {
387
+ this.stopSseWatchdog();
388
+ this.sseWatchdogTimer = setInterval(() => {
389
+ if (this._wireState !== "connected")
390
+ return;
391
+ if (!this.sseVerified)
392
+ return;
393
+ const gap = Date.now() - this.lastKeepaliveAt;
394
+ if (gap > this.cfg.sseKeepaliveTimeout) {
395
+ this.log.log("transport.sse.watchdog.fired", { gapMs: gap, thresholdMs: this.cfg.sseKeepaliveTimeout }, `SSE watchdog: ${Math.round(gap / 1000)}s without keepalive (threshold ${this.cfg.sseKeepaliveTimeout / 1000}s)`);
396
+ void this.reconnectWire("sse_watchdog");
397
+ }
398
+ }, this.cfg.sseWatchdogInterval);
399
+ }
400
+ stopSseWatchdog() {
401
+ if (this.sseWatchdogTimer) {
402
+ clearInterval(this.sseWatchdogTimer);
403
+ this.sseWatchdogTimer = null;
404
+ }
405
+ }
406
+ startFirstKeepaliveDeadline() {
407
+ this.cancelFirstKeepaliveDeadline();
408
+ this.firstKeepaliveTimer = setTimeout(() => {
409
+ this.firstKeepaliveTimer = null;
410
+ if (this._wireState !== "connected")
411
+ return;
412
+ if (this.sseVerified)
413
+ return;
414
+ this.log.log("transport.sse.never_opened", { deadlineMs: this.cfg.firstKeepaliveDeadline }, `first keepalive deadline: ${this.cfg.firstKeepaliveDeadline}ms elapsed without SSE`);
415
+ void this.reconnectWire("sse_never_opened");
416
+ }, this.cfg.firstKeepaliveDeadline);
417
+ }
418
+ cancelFirstKeepaliveDeadline() {
419
+ if (this.firstKeepaliveTimer) {
420
+ clearTimeout(this.firstKeepaliveTimer);
421
+ this.firstKeepaliveTimer = null;
422
+ }
423
+ }
424
+ // ── Internal: state + event emission ────────────────────────────────
425
+ transition(to) {
426
+ if (this._wireState === to)
427
+ return;
428
+ const from = this._wireState;
429
+ this._wireState = to;
430
+ if (to === "connected") {
431
+ this.consecutiveReconnects = 0;
432
+ }
433
+ this.log.log("transport.wire.state", { from, to }, `wire ${from} → ${to}`);
434
+ this.emit({ type: "state", from, to });
435
+ }
436
+ emit(event) {
437
+ for (const h of this.handlers) {
438
+ try {
439
+ h(event);
440
+ }
441
+ catch (err) {
442
+ this.log.log("transport.handler.error", { error: String(err) }, `wire-event handler error: ${err}`);
443
+ }
444
+ }
445
+ }
446
+ }
447
+ //# sourceMappingURL=mcp-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-transport.js","sourceRoot":"","sources":["../../src/wire/mcp-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * ITransport — Layer-4 wire surface for the network-adapter package.
3
+ *
4
+ * Phase 1: types only. Zero runtime change. The real implementation
5
+ * (`McpTransport`) lands in Phase 2, extracted out of the current
6
+ * `McpConnectionManager`.
7
+ *
8
+ * ## Responsibility boundary
9
+ *
10
+ * A Transport owns exactly one logical wire to a Hub. It is responsible
11
+ * for:
12
+ *
13
+ * 1. Opening and closing that wire.
14
+ * 2. Shipping untyped request/response pairs over it (`request`).
15
+ * 3. Enumerating what method names the remote peer advertises
16
+ * (`listMethods` — used by the adapter for discovery translation).
17
+ * 4. Surfacing liveness: a coarse 3-value `wireState` and a stream of
18
+ * `WireEvent`s (connected, disconnected, peer-closed, etc.).
19
+ * 5. Wire-level reconnect policy: it transparently reconnects the
20
+ * underlying socket/HTTP/SSE stream on transient failure. It does
21
+ * NOT know about sessions, roles, handshakes, or FSM.
22
+ *
23
+ * It is NOT responsible for:
24
+ *
25
+ * - Session lifecycle (bind/rebind/teardown). That lives on the
26
+ * `IAgentClient` above it.
27
+ * - Authentication and handshake semantics (register_role, enriched handshake).
28
+ * - Event classification, dedup, or state sync.
29
+ * - Retry-on-session-invalid (that policy is above the wire).
30
+ *
31
+ * ## Why untyped `request(method, params)`
32
+ *
33
+ * The adapter and shim above must be transport-agnostic. By keeping the
34
+ * request surface a plain string-keyed call, the same adapter code can
35
+ * run against a future gRPC or QUIC transport without leaking protocol
36
+ * detail. MCP-specific encodings (tool calls, list_tools, etc.) are
37
+ * translated inside `McpTransport`, not exposed here.
38
+ *
39
+ * The trade-off: type safety on the wire is the transport's problem.
40
+ * Callers (the adapter) validate response shapes at the L7 seam.
41
+ */
42
+ import type { ILogger, LegacyStringLogger } from "../logger.js";
43
+ /**
44
+ * Coarse-grained wire state.
45
+ *
46
+ * Deliberately only three values — the transport does NOT model a
47
+ * session FSM. "connected" means "the wire is up right now"; anything
48
+ * stronger (handshake done, session bound, streaming) lives on the
49
+ * AgentClient layer.
50
+ */
51
+ export type WireState = "disconnected" | "connecting" | "connected";
52
+ /**
53
+ * Why the wire reconnected. A narrower vocabulary than
54
+ * `SessionReconnectReason` (in `agent-client.ts`), because the
55
+ * transport doesn't classify session-level failures.
56
+ */
57
+ export type WireReconnectCause = "sse_watchdog" | "sse_never_opened" | "heartbeat_failed" | "peer_closed" | "wire_error";
58
+ /**
59
+ * Stream of wire-level events the AgentClient subscribes to. The
60
+ * transport emits these; the AgentClient uses them to drive its
61
+ * session FSM. Intentionally narrow — this is the entire L4→L7 event
62
+ * protocol.
63
+ */
64
+ export type WireEvent = {
65
+ type: "state";
66
+ from: WireState;
67
+ to: WireState;
68
+ } | {
69
+ type: "reconnecting";
70
+ cause: WireReconnectCause;
71
+ } | {
72
+ type: "reconnected";
73
+ } | {
74
+ type: "closed";
75
+ reason?: string;
76
+ } | {
77
+ /**
78
+ * Unsolicited inbound message from the remote (push notification,
79
+ * server-sent event). The transport delivers the raw body and
80
+ * the method name; the adapter decides what to do with it.
81
+ */
82
+ type: "push";
83
+ method: string;
84
+ payload: unknown;
85
+ };
86
+ export type WireEventHandler = (event: WireEvent) => void;
87
+ /**
88
+ * Transport configuration — minimal. Anything session- or role-related
89
+ * belongs in `IAgentClient` config, not here.
90
+ */
91
+ export interface TransportConfig {
92
+ url: string;
93
+ token?: string;
94
+ heartbeatInterval?: number;
95
+ sseKeepaliveTimeout?: number;
96
+ firstKeepaliveDeadline?: number;
97
+ sseWatchdogInterval?: number;
98
+ reconnectDelay?: number;
99
+ /**
100
+ * Logger injection. Preferred is `ILogger`; the string variant is a
101
+ * Phase-2 migration aid so existing string-logger call sites can
102
+ * wire up a transport without being rewritten first.
103
+ */
104
+ logger?: ILogger | LegacyStringLogger;
105
+ /**
106
+ * Mission-56 W2.2: optional provider for the most-recent Hub event id
107
+ * the layer above has observed. The transport reads this at
108
+ * (re)connect time and, when a value is returned, attaches it as the
109
+ * canonical SSE `Last-Event-ID` header on the inbound stream. The
110
+ * Hub-side W1b wrapper consumes the header to backfill missed
111
+ * Messages before resuming live emit. Returning `undefined` (no
112
+ * value yet) means cold-start — Hub falls through to the
113
+ * stream-all-with-soft-cap path.
114
+ */
115
+ getLastEventId?: () => string | undefined;
116
+ }
117
+ /**
118
+ * Pull-style telemetry on a Transport. Deliberately a point-in-time
119
+ * snapshot — the log stream is the authoritative event record. These
120
+ * counters exist so an AgentClient (or operator) can report
121
+ * "how is this wire doing right now" without subscribing.
122
+ */
123
+ export interface TransportMetrics {
124
+ readonly wireState: WireState;
125
+ readonly totalReconnects: number;
126
+ readonly consecutiveReconnects: number;
127
+ readonly lastReconnectCause?: WireReconnectCause;
128
+ readonly lastKeepaliveAt?: number;
129
+ readonly requestsInFlight: number;
130
+ }
131
+ export interface ITransport {
132
+ /** Current coarse wire state. */
133
+ readonly wireState: WireState;
134
+ /**
135
+ * Open the wire. Resolves when `wireState === "connected"`. Idempotent:
136
+ * calling `connect()` on an already-connected transport is a no-op.
137
+ */
138
+ connect(): Promise<void>;
139
+ /**
140
+ * Close the wire cleanly. After this resolves, `wireState === "disconnected"`
141
+ * and no further `WireEvent`s will be delivered except a final
142
+ * `{type:"state", to:"disconnected"}` if one hasn't fired yet.
143
+ */
144
+ close(): Promise<void>;
145
+ /**
146
+ * Ship an untyped request/response pair over the wire.
147
+ *
148
+ * Protocol framing is the transport's problem. Session-invalid
149
+ * classification is NOT — callers receive the raw error and decide
150
+ * whether to reconnect at the session layer.
151
+ */
152
+ request(method: string, params: Record<string, unknown>): Promise<unknown>;
153
+ /**
154
+ * Enumerate the method names currently advertised by the remote peer.
155
+ * Used by the AgentClient for discovery translation: it rewrites this
156
+ * list into an `IAgentClient`-shaped descriptor set exposed to shims.
157
+ *
158
+ * The return shape is intentionally `string[]` rather than full
159
+ * JSON-schema descriptors — richer discovery, if needed, is a
160
+ * future extension via an optional second method. Keeping the minimum
161
+ * here means every transport can satisfy it cheaply.
162
+ */
163
+ listMethods(): Promise<string[]>;
164
+ /** Subscribe to the wire-event stream. Multiple subscribers allowed. */
165
+ onWireEvent(handler: WireEventHandler): void;
166
+ /** Point-in-time snapshot of wire-level telemetry. */
167
+ getMetrics(): TransportMetrics;
168
+ /**
169
+ * Current wire-level session id, if any. For MCP this is the
170
+ * StreamableHTTP session id issued by the server; for a loopback
171
+ * transport it's a synthetic handle. Undefined before first `connect()`.
172
+ */
173
+ getSessionId(): string | undefined;
174
+ }