@herbertgao/pi-extensions 2026.9.11 → 2026.9.12

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 (151) hide show
  1. package/node_modules/@herbertgao/pi-cc-extensions/package.json +1 -1
  2. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  3. package/node_modules/pi-mcp-adapter/CHANGELOG.md +62 -0
  4. package/node_modules/pi-mcp-adapter/README.md +75 -7
  5. package/node_modules/pi-mcp-adapter/bearer-command-resolver.ts +193 -0
  6. package/node_modules/pi-mcp-adapter/cli.js +56 -5
  7. package/node_modules/pi-mcp-adapter/commands.ts +96 -5
  8. package/node_modules/pi-mcp-adapter/config.ts +73 -6
  9. package/node_modules/pi-mcp-adapter/direct-tool-surface.ts +22 -28
  10. package/node_modules/pi-mcp-adapter/direct-tools.ts +13 -5
  11. package/node_modules/pi-mcp-adapter/dist/abort.d.ts +2 -0
  12. package/node_modules/pi-mcp-adapter/dist/abort.js +36 -0
  13. package/node_modules/pi-mcp-adapter/dist/abort.js.map +1 -0
  14. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.d.ts +6 -0
  15. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js +194 -0
  16. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js.map +1 -0
  17. package/node_modules/pi-mcp-adapter/dist/config.d.ts +5 -0
  18. package/node_modules/pi-mcp-adapter/dist/config.js +75 -6
  19. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
  20. package/node_modules/pi-mcp-adapter/dist/consent-manager.d.ts +18 -0
  21. package/node_modules/pi-mcp-adapter/dist/consent-manager.js +88 -0
  22. package/node_modules/pi-mcp-adapter/dist/consent-manager.js.map +1 -0
  23. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.d.ts +17 -0
  24. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js +316 -0
  25. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js.map +1 -0
  26. package/node_modules/pi-mcp-adapter/dist/errors.d.ts +131 -0
  27. package/node_modules/pi-mcp-adapter/dist/errors.js +278 -0
  28. package/node_modules/pi-mcp-adapter/dist/errors.js.map +1 -0
  29. package/node_modules/pi-mcp-adapter/dist/http-ca.d.ts +8 -0
  30. package/node_modules/pi-mcp-adapter/dist/http-ca.js +88 -0
  31. package/node_modules/pi-mcp-adapter/dist/http-ca.js.map +1 -0
  32. package/node_modules/pi-mcp-adapter/dist/jev-client.d.ts +15 -0
  33. package/node_modules/pi-mcp-adapter/dist/jev-client.js +340 -0
  34. package/node_modules/pi-mcp-adapter/dist/jev-client.js.map +1 -0
  35. package/node_modules/pi-mcp-adapter/dist/jev-contracts.d.ts +77 -0
  36. package/node_modules/pi-mcp-adapter/dist/jev-contracts.js +2 -0
  37. package/node_modules/pi-mcp-adapter/dist/jev-contracts.js.map +1 -0
  38. package/node_modules/pi-mcp-adapter/dist/jev-key-store.d.ts +22 -0
  39. package/node_modules/pi-mcp-adapter/dist/jev-key-store.js +85 -0
  40. package/node_modules/pi-mcp-adapter/dist/jev-key-store.js.map +1 -0
  41. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.d.ts +2 -0
  42. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js +55 -0
  43. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js.map +1 -0
  44. package/node_modules/pi-mcp-adapter/dist/lifecycle.d.ts +56 -0
  45. package/node_modules/pi-mcp-adapter/dist/lifecycle.js +410 -0
  46. package/node_modules/pi-mcp-adapter/dist/lifecycle.js.map +1 -0
  47. package/node_modules/pi-mcp-adapter/dist/logger.d.ts +51 -0
  48. package/node_modules/pi-mcp-adapter/dist/logger.js +131 -0
  49. package/node_modules/pi-mcp-adapter/dist/logger.js.map +1 -0
  50. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.d.ts +26 -0
  51. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js +103 -0
  52. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js.map +1 -0
  53. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.d.ts +118 -0
  54. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js +1098 -0
  55. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js.map +1 -0
  56. package/node_modules/pi-mcp-adapter/dist/mcp-auth.d.ts +168 -0
  57. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js +1117 -0
  58. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js.map +1 -0
  59. package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js +7 -140
  60. package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js.map +1 -1
  61. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.d.ts +53 -0
  62. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js +441 -0
  63. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js.map +1 -0
  64. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.d.ts +148 -0
  65. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js +689 -0
  66. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js.map +1 -0
  67. package/node_modules/pi-mcp-adapter/dist/mcp-probe.d.ts +6 -0
  68. package/node_modules/pi-mcp-adapter/dist/mcp-probe.js +166 -0
  69. package/node_modules/pi-mcp-adapter/dist/mcp-probe.js.map +1 -0
  70. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.d.ts +102 -0
  71. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js +369 -0
  72. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js.map +1 -0
  73. package/node_modules/pi-mcp-adapter/dist/mcp-trace.d.ts +95 -0
  74. package/node_modules/pi-mcp-adapter/dist/mcp-trace.js +242 -0
  75. package/node_modules/pi-mcp-adapter/dist/mcp-trace.js.map +1 -0
  76. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +2 -11
  77. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -1
  78. package/node_modules/pi-mcp-adapter/dist/npx-resolver.d.ts +6 -0
  79. package/node_modules/pi-mcp-adapter/dist/npx-resolver.js +505 -0
  80. package/node_modules/pi-mcp-adapter/dist/npx-resolver.js.map +1 -0
  81. package/node_modules/pi-mcp-adapter/dist/request-headers-command.d.ts +10 -0
  82. package/node_modules/pi-mcp-adapter/dist/request-headers-command.js +312 -0
  83. package/node_modules/pi-mcp-adapter/dist/request-headers-command.js.map +1 -0
  84. package/node_modules/pi-mcp-adapter/dist/runtime-owner.d.ts +13 -0
  85. package/node_modules/pi-mcp-adapter/dist/runtime-owner.js +97 -0
  86. package/node_modules/pi-mcp-adapter/dist/runtime-owner.js.map +1 -0
  87. package/node_modules/pi-mcp-adapter/dist/sampling-handler.d.ts +17 -0
  88. package/node_modules/pi-mcp-adapter/dist/sampling-handler.js +203 -0
  89. package/node_modules/pi-mcp-adapter/dist/sampling-handler.js.map +1 -0
  90. package/node_modules/pi-mcp-adapter/dist/secure-keyring.d.ts +11 -0
  91. package/node_modules/pi-mcp-adapter/dist/secure-keyring.js +172 -0
  92. package/node_modules/pi-mcp-adapter/dist/secure-keyring.js.map +1 -0
  93. package/node_modules/pi-mcp-adapter/dist/server-manager.d.ts +157 -0
  94. package/node_modules/pi-mcp-adapter/dist/server-manager.js +1743 -0
  95. package/node_modules/pi-mcp-adapter/dist/server-manager.js.map +1 -0
  96. package/node_modules/pi-mcp-adapter/dist/session-approvals.d.ts +34 -0
  97. package/node_modules/pi-mcp-adapter/dist/session-approvals.js +140 -0
  98. package/node_modules/pi-mcp-adapter/dist/session-approvals.js.map +1 -0
  99. package/node_modules/pi-mcp-adapter/dist/session-recovery.d.ts +26 -0
  100. package/node_modules/pi-mcp-adapter/dist/session-recovery.js +142 -0
  101. package/node_modules/pi-mcp-adapter/dist/session-recovery.js.map +1 -0
  102. package/node_modules/pi-mcp-adapter/dist/state.d.ts +73 -0
  103. package/node_modules/pi-mcp-adapter/dist/state.js +2 -0
  104. package/node_modules/pi-mcp-adapter/dist/state.js.map +1 -0
  105. package/node_modules/pi-mcp-adapter/dist/types.d.ts +36 -0
  106. package/node_modules/pi-mcp-adapter/dist/types.js +18 -0
  107. package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -1
  108. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.d.ts +17 -0
  109. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js +219 -0
  110. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js.map +1 -0
  111. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.d.ts +15 -0
  112. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js +85 -0
  113. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js.map +1 -0
  114. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +1 -0
  115. package/node_modules/pi-mcp-adapter/dist/utils.js +13 -0
  116. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -1
  117. package/node_modules/pi-mcp-adapter/elicitation-handler.ts +29 -19
  118. package/node_modules/pi-mcp-adapter/examples/jev-accessibility-loop.mjs +85 -0
  119. package/node_modules/pi-mcp-adapter/examples/jev-semantic-filter.mjs +34 -0
  120. package/node_modules/pi-mcp-adapter/index.ts +129 -6
  121. package/node_modules/pi-mcp-adapter/init.ts +6 -19
  122. package/node_modules/pi-mcp-adapter/jev-client.ts +273 -0
  123. package/node_modules/pi-mcp-adapter/jev-contracts.ts +53 -0
  124. package/node_modules/pi-mcp-adapter/jev-key-store.ts +79 -0
  125. package/node_modules/pi-mcp-adapter/lifecycle.ts +14 -3
  126. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +7 -142
  127. package/node_modules/pi-mcp-adapter/mcp-code.ts +119 -11
  128. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +4 -0
  129. package/node_modules/pi-mcp-adapter/mcp-references.ts +5 -3
  130. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +5 -0
  131. package/node_modules/pi-mcp-adapter/mcp-tasks.ts +467 -0
  132. package/node_modules/pi-mcp-adapter/metadata-cache.ts +2 -13
  133. package/node_modules/pi-mcp-adapter/namespace-tools.ts +1 -1
  134. package/node_modules/pi-mcp-adapter/package.json +17 -9
  135. package/node_modules/pi-mcp-adapter/proxy-modes.ts +319 -166
  136. package/node_modules/pi-mcp-adapter/request-headers-command.ts +6 -3
  137. package/node_modules/pi-mcp-adapter/search-ranking.ts +38 -7
  138. package/node_modules/pi-mcp-adapter/secure-keyring.ts +170 -0
  139. package/node_modules/pi-mcp-adapter/semantic-search.ts +186 -0
  140. package/node_modules/pi-mcp-adapter/server-manager.ts +293 -50
  141. package/node_modules/pi-mcp-adapter/session-approvals.ts +14 -0
  142. package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +2 -0
  143. package/node_modules/pi-mcp-adapter/state.ts +3 -1
  144. package/node_modules/pi-mcp-adapter/tool-approval.ts +26 -4
  145. package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -14
  146. package/node_modules/pi-mcp-adapter/tool-registrar.ts +8 -6
  147. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +4 -1
  148. package/node_modules/pi-mcp-adapter/types.ts +53 -0
  149. package/node_modules/pi-mcp-adapter/ui-server.ts +17 -9
  150. package/node_modules/pi-mcp-adapter/utils.ts +16 -0
  151. package/package.json +7 -6
@@ -0,0 +1,56 @@
1
+ import { type ServerDefinition } from "./types.ts";
2
+ import { type McpServerManager } from "./server-manager.ts";
3
+ import { hasPendingAuth } from "./mcp-auth-flow.ts";
4
+ export type ReconnectCallback = (serverName: string) => void | Promise<void>;
5
+ export type ReconnectFailureCallback = (serverName: string, error: unknown) => void;
6
+ export type HealthRestoredCallback = (serverName: string) => void | Promise<void>;
7
+ export type AuthRequiredCallback = (serverName: string) => void | Promise<void>;
8
+ export declare class McpLifecycleManager {
9
+ private readonly manager;
10
+ private readonly hasPendingAuthForServer;
11
+ private keepAliveServers;
12
+ private allServers;
13
+ private serverSettings;
14
+ private globalIdleTimeout;
15
+ private healthCheckInterval;
16
+ private onReconnect;
17
+ private onReconnectFailure;
18
+ private onHealthRestored;
19
+ private onAuthRequired;
20
+ private onIdleShutdown;
21
+ private activeHealthCheck;
22
+ private activeConvergence;
23
+ private shutdownPromise;
24
+ private retryStates;
25
+ private pendingMetadataPublications;
26
+ private stopped;
27
+ private removeHealthAbortListener;
28
+ constructor(manager: McpServerManager, hasPendingAuthForServer?: typeof hasPendingAuth);
29
+ setReconnectCallback(callback: ReconnectCallback): void;
30
+ setReconnectFailureCallback(callback: ReconnectFailureCallback): void;
31
+ setHealthRestoredCallback(callback: HealthRestoredCallback): void;
32
+ setAuthRequiredCallback(callback: AuthRequiredCallback): void;
33
+ markKeepAlive(name: string, definition: ServerDefinition): void;
34
+ registerServer(name: string, definition: ServerDefinition, settings?: {
35
+ idleTimeout?: number;
36
+ }): void;
37
+ unregisterServer(name: string): void;
38
+ setGlobalIdleTimeout(minutes: number): void;
39
+ setIdleShutdownCallback(callback: (serverName: string) => void): void;
40
+ startHealthChecks(signalOrInterval?: AbortSignal | number, maybeIntervalMs?: number): void;
41
+ ensureConverged(signal?: AbortSignal): Promise<void>;
42
+ private checkConnections;
43
+ private checkKeepAliveConnections;
44
+ private checkKeepAliveConnection;
45
+ private handleSupersededConnection;
46
+ private publishConnectedMetadata;
47
+ private notifyAuthRequired;
48
+ private shouldAttemptConnection;
49
+ private connectionFailureTarget;
50
+ private reportConnectionFailure;
51
+ private deferRefreshTimeout;
52
+ private recordRetry;
53
+ private getIdleTimeout;
54
+ gracefulShutdown(): Promise<void>;
55
+ private shutdownOnce;
56
+ }
@@ -0,0 +1,410 @@
1
+ import { SdkError, SdkErrorCode } from "@modelcontextprotocol/client";
2
+ import { isServerDisabled } from "./types.js";
3
+ import { isTransientHttpConnectError, isUnauthorizedHttpError, } from "./server-manager.js";
4
+ import { hasPendingAuth } from "./mcp-auth-flow.js";
5
+ import { logger } from "./logger.js";
6
+ import { formatTerminalError, parallelLimit, sanitizeTerminalText } from "./utils.js";
7
+ import { isTerminatedSession } from "./session-recovery.js";
8
+ const KEEP_ALIVE_RETRY_BASE_MS = 30_000;
9
+ const KEEP_ALIVE_RETRY_MAX_MS = 5 * 60_000;
10
+ const KEEP_ALIVE_CHECK_CONCURRENCY = 10;
11
+ export class McpLifecycleManager {
12
+ manager;
13
+ hasPendingAuthForServer;
14
+ keepAliveServers = new Map();
15
+ allServers = new Map();
16
+ serverSettings = new Map();
17
+ globalIdleTimeout = 10 * 60 * 1000;
18
+ healthCheckInterval;
19
+ onReconnect;
20
+ onReconnectFailure;
21
+ onHealthRestored;
22
+ onAuthRequired;
23
+ onIdleShutdown;
24
+ activeHealthCheck;
25
+ activeConvergence;
26
+ shutdownPromise;
27
+ retryStates = new Map();
28
+ pendingMetadataPublications = new Set();
29
+ stopped = false;
30
+ removeHealthAbortListener;
31
+ constructor(manager, hasPendingAuthForServer = hasPendingAuth) {
32
+ this.manager = manager;
33
+ this.hasPendingAuthForServer = hasPendingAuthForServer;
34
+ }
35
+ setReconnectCallback(callback) {
36
+ this.onReconnect = callback;
37
+ }
38
+ setReconnectFailureCallback(callback) {
39
+ this.onReconnectFailure = callback;
40
+ }
41
+ setHealthRestoredCallback(callback) {
42
+ this.onHealthRestored = callback;
43
+ }
44
+ setAuthRequiredCallback(callback) {
45
+ this.onAuthRequired = callback;
46
+ }
47
+ markKeepAlive(name, definition) {
48
+ if (isServerDisabled(definition))
49
+ return;
50
+ this.keepAliveServers.set(name, definition);
51
+ }
52
+ registerServer(name, definition, settings) {
53
+ if (isServerDisabled(definition))
54
+ return;
55
+ this.allServers.set(name, definition);
56
+ if (settings?.idleTimeout !== undefined)
57
+ this.serverSettings.set(name, settings);
58
+ }
59
+ unregisterServer(name) {
60
+ this.allServers.delete(name);
61
+ this.keepAliveServers.delete(name);
62
+ this.serverSettings.delete(name);
63
+ this.retryStates.delete(name);
64
+ this.pendingMetadataPublications.delete(name);
65
+ }
66
+ setGlobalIdleTimeout(minutes) {
67
+ this.globalIdleTimeout = minutes * 60 * 1000;
68
+ }
69
+ setIdleShutdownCallback(callback) {
70
+ this.onIdleShutdown = callback;
71
+ }
72
+ startHealthChecks(signalOrInterval, maybeIntervalMs = 30000) {
73
+ const signal = typeof signalOrInterval === "number" ? undefined : signalOrInterval;
74
+ const intervalMs = typeof signalOrInterval === "number" ? signalOrInterval : maybeIntervalMs;
75
+ this.stopped = false;
76
+ if (signal?.aborted) {
77
+ this.stopped = true;
78
+ return;
79
+ }
80
+ const stop = () => {
81
+ this.stopped = true;
82
+ if (this.healthCheckInterval)
83
+ clearInterval(this.healthCheckInterval);
84
+ this.healthCheckInterval = undefined;
85
+ };
86
+ signal?.addEventListener("abort", stop, { once: true });
87
+ this.removeHealthAbortListener = () => signal?.removeEventListener("abort", stop);
88
+ this.healthCheckInterval = setInterval(() => {
89
+ if (this.stopped || signal?.aborted || this.activeHealthCheck)
90
+ return;
91
+ const check = this.checkConnections(signal)
92
+ .catch(error => {
93
+ console.error(`MCP: Health check failed: ${formatTerminalError(error)}`);
94
+ })
95
+ .finally(() => {
96
+ if (this.activeHealthCheck === check)
97
+ this.activeHealthCheck = undefined;
98
+ });
99
+ this.activeHealthCheck = check;
100
+ }, intervalMs);
101
+ this.healthCheckInterval.unref();
102
+ }
103
+ async ensureConverged(signal) {
104
+ if (this.stopped || signal?.aborted)
105
+ return;
106
+ if (this.activeConvergence)
107
+ return this.activeConvergence;
108
+ const check = this.checkKeepAliveConnections(signal);
109
+ this.activeConvergence = check;
110
+ try {
111
+ await check;
112
+ }
113
+ finally {
114
+ if (this.activeConvergence === check)
115
+ this.activeConvergence = undefined;
116
+ }
117
+ }
118
+ async checkConnections(signal) {
119
+ if (this.stopped || signal?.aborted)
120
+ return;
121
+ await this.ensureConverged(signal);
122
+ if (this.stopped || signal?.aborted)
123
+ return;
124
+ for (const [name] of this.allServers) {
125
+ if (this.keepAliveServers.has(name))
126
+ continue;
127
+ const timeout = this.getIdleTimeout(name);
128
+ if (timeout > 0 && this.manager.isIdle(name, timeout)) {
129
+ await this.manager.close(name);
130
+ if (this.stopped || signal?.aborted)
131
+ return;
132
+ this.onIdleShutdown?.(name);
133
+ }
134
+ }
135
+ }
136
+ async checkKeepAliveConnections(signal) {
137
+ if (this.stopped || signal?.aborted)
138
+ return;
139
+ await parallelLimit([...this.keepAliveServers], KEEP_ALIVE_CHECK_CONCURRENCY, ([name, definition]) => this.checkKeepAliveConnection(name, definition, signal));
140
+ }
141
+ async checkKeepAliveConnection(name, definition, signal, retrySuperseded = true) {
142
+ if (isServerDisabled(definition) || this.stopped || signal?.aborted)
143
+ return;
144
+ // Fence against unregisterServer racing an in-flight convergence pass.
145
+ // Identity comparison also rejects stale passes after a same-name
146
+ // replacement registration, which a name check would wrongly accept.
147
+ if (this.keepAliveServers.get(name) !== definition)
148
+ return;
149
+ const connection = this.manager.getConnection(name);
150
+ if (connection?.status === "needs-auth") {
151
+ this.pendingMetadataPublications.delete(name);
152
+ return;
153
+ }
154
+ if (!this.shouldAttemptConnection(name, connection))
155
+ return;
156
+ if (!connection || connection.status !== "connected") {
157
+ if (this.hasPendingAuthForServer(name)) {
158
+ logger.debug(`Skipping reconnect for ${name} while OAuth authorization is pending`);
159
+ return;
160
+ }
161
+ let freshConnection;
162
+ try {
163
+ freshConnection = await this.manager.connect(name, definition, signal);
164
+ }
165
+ catch (error) {
166
+ if (this.stopped || signal?.aborted)
167
+ return;
168
+ this.reportConnectionFailure(name, definition, error, "reconnect", this.manager.getConnection(name));
169
+ return;
170
+ }
171
+ if (this.stopped || signal?.aborted)
172
+ return;
173
+ if (freshConnection.status === "needs-auth") {
174
+ await this.notifyAuthRequired(name, definition, freshConnection);
175
+ return;
176
+ }
177
+ if (freshConnection.status !== "connected") {
178
+ this.reportConnectionFailure(name, definition, new Error(`MCP server ${name} did not return a connected session`), "reconnect", freshConnection);
179
+ return;
180
+ }
181
+ logger.debug(`Reconnected to ${name}`);
182
+ await this.publishConnectedMetadata(name, definition, freshConnection);
183
+ return;
184
+ }
185
+ if (this.pendingMetadataPublications.has(name)) {
186
+ await this.publishConnectedMetadata(name, definition, connection);
187
+ return;
188
+ }
189
+ if (!definition.url)
190
+ return;
191
+ const hadSessionId = connection.transport?.sessionId != null;
192
+ let refreshResult;
193
+ try {
194
+ refreshResult = await this.manager.refreshTools(name, connection, signal);
195
+ }
196
+ catch (error) {
197
+ if (this.stopped || signal?.aborted)
198
+ return;
199
+ const current = this.manager.getConnection(name);
200
+ if (current !== connection || connection.status !== "connected") {
201
+ await this.handleSupersededConnection(name, definition, connection, signal, retrySuperseded);
202
+ return;
203
+ }
204
+ if (!shouldReconnectAfterRefresh(error, hadSessionId, definition)) {
205
+ this.reportConnectionFailure(name, definition, error, "refresh", connection);
206
+ return;
207
+ }
208
+ if (this.hasPendingAuthForServer(name)) {
209
+ logger.debug(`Skipping reconnect for ${name} while OAuth authorization is pending`);
210
+ return;
211
+ }
212
+ let freshConnection;
213
+ try {
214
+ freshConnection = await this.manager.reconnect(name, definition, connection, signal);
215
+ }
216
+ catch (reconnectError) {
217
+ if (this.stopped || signal?.aborted)
218
+ return;
219
+ this.reportConnectionFailure(name, definition, reconnectError, "reconnect", this.manager.getConnection(name));
220
+ return;
221
+ }
222
+ if (this.stopped || signal?.aborted)
223
+ return;
224
+ if (freshConnection.status === "needs-auth") {
225
+ await this.notifyAuthRequired(name, definition, freshConnection);
226
+ return;
227
+ }
228
+ if (freshConnection.status !== "connected") {
229
+ this.reportConnectionFailure(name, definition, new Error(`MCP server ${name} did not return a connected session`), "reconnect", freshConnection);
230
+ return;
231
+ }
232
+ logger.debug(`Reconnected stale MCP session for ${name}`);
233
+ await this.publishConnectedMetadata(name, definition, freshConnection);
234
+ return;
235
+ }
236
+ if (refreshResult === "superseded") {
237
+ await this.handleSupersededConnection(name, definition, connection, signal, retrySuperseded);
238
+ return;
239
+ }
240
+ if (refreshResult === "refresh-timeout") {
241
+ this.deferRefreshTimeout(name, definition, connection);
242
+ return;
243
+ }
244
+ if (this.keepAliveServers.get(name) !== definition)
245
+ return;
246
+ if (this.retryStates.delete(name)) {
247
+ await this.onHealthRestored?.(name);
248
+ }
249
+ }
250
+ async handleSupersededConnection(name, definition, staleConnection, signal, retrySuperseded) {
251
+ const current = this.manager.getConnection(name);
252
+ if (this.keepAliveServers.get(name) !== definition)
253
+ return;
254
+ if (current === staleConnection && current.status === "connected") {
255
+ if (this.retryStates.delete(name))
256
+ await this.onHealthRestored?.(name);
257
+ return;
258
+ }
259
+ if (current?.status === "connected") {
260
+ await this.publishConnectedMetadata(name, definition, current);
261
+ return;
262
+ }
263
+ if (current?.status === "needs-auth") {
264
+ await this.notifyAuthRequired(name, definition, current);
265
+ return;
266
+ }
267
+ if (retrySuperseded) {
268
+ await this.checkKeepAliveConnection(name, definition, signal, false);
269
+ }
270
+ }
271
+ async publishConnectedMetadata(name, definition, connection) {
272
+ // Fence stale convergence passes by definition identity so disposal, and
273
+ // disposal followed by a same-name replacement, never re-track this
274
+ // server. Close the pass's own connection only when it is still current,
275
+ // so a replacement's connection is never touched.
276
+ if (this.keepAliveServers.get(name) !== definition) {
277
+ if (this.manager.getConnection(name) === connection)
278
+ await this.manager.close(name);
279
+ return;
280
+ }
281
+ this.pendingMetadataPublications.add(name);
282
+ try {
283
+ await this.onReconnect?.(name);
284
+ this.pendingMetadataPublications.delete(name);
285
+ this.retryStates.delete(name);
286
+ }
287
+ catch (error) {
288
+ if (this.stopped)
289
+ return;
290
+ this.reportConnectionFailure(name, definition, error, "publish", connection);
291
+ }
292
+ }
293
+ async notifyAuthRequired(name, definition, connection) {
294
+ // Fence stale convergence passes by definition identity. Close the
295
+ // leftover needs-auth connection only while it is still the manager's
296
+ // current entry, so a replacement's connection is never touched and the
297
+ // stale client/transport cannot leak when a replacement connects later.
298
+ if (this.keepAliveServers.get(name) !== definition) {
299
+ if (this.manager.getConnection(name) === connection)
300
+ await this.manager.close(name);
301
+ return;
302
+ }
303
+ this.pendingMetadataPublications.delete(name);
304
+ this.retryStates.delete(name);
305
+ try {
306
+ await this.onAuthRequired?.(name);
307
+ }
308
+ catch (error) {
309
+ const message = error instanceof Error ? error.message : String(error);
310
+ logger.debug(`MCP: auth-required callback failed for ${name}: ${sanitizeTerminalText(message)}`);
311
+ }
312
+ }
313
+ shouldAttemptConnection(name, connection) {
314
+ const retry = this.retryStates.get(name);
315
+ if (!retry)
316
+ return true;
317
+ if (retry.connection !== connection || retry.status !== connection?.status) {
318
+ this.retryStates.delete(name);
319
+ return true;
320
+ }
321
+ return Date.now() >= retry.nextAttemptAt;
322
+ }
323
+ connectionFailureTarget(action, name) {
324
+ if (action === "reconnect")
325
+ return `reconnect to ${name}`;
326
+ if (action === "publish")
327
+ return `publish metadata for ${name}`;
328
+ return `refresh ${name}`;
329
+ }
330
+ reportConnectionFailure(name, definition, error, action, connection) {
331
+ if (!this.recordRetry(name, definition, connection))
332
+ return;
333
+ this.onReconnectFailure?.(name, error);
334
+ if (isTransientHttpConnectError(error))
335
+ return;
336
+ const retry = this.retryStates.get(name);
337
+ if (retry?.warningReported)
338
+ return;
339
+ if (retry)
340
+ retry.warningReported = true;
341
+ const message = error instanceof Error ? error.message : String(error);
342
+ console.error(`MCP: Failed to ${this.connectionFailureTarget(action, name)}: ${sanitizeTerminalText(message)}`);
343
+ }
344
+ deferRefreshTimeout(name, definition, connection) {
345
+ if (!this.recordRetry(name, definition, connection))
346
+ return;
347
+ logger.debug(`MCP: keep-alive tools/list refresh timed out for ${name}; retrying after backoff`);
348
+ }
349
+ recordRetry(name, definition, connection) {
350
+ // Do not recreate retry/failure state from a stale convergence pass after
351
+ // disposal or a same-name replacement registration.
352
+ if (this.keepAliveServers.get(name) !== definition)
353
+ return false;
354
+ const previous = this.retryStates.get(name);
355
+ const attempts = (previous?.attempts ?? 0) + 1;
356
+ const delay = Math.min(KEEP_ALIVE_RETRY_BASE_MS * 2 ** Math.min(attempts - 1, 10), KEEP_ALIVE_RETRY_MAX_MS);
357
+ this.retryStates.set(name, {
358
+ attempts,
359
+ nextAttemptAt: Date.now() + delay,
360
+ connection,
361
+ status: connection?.status,
362
+ warningReported: previous?.warningReported ?? false,
363
+ });
364
+ return true;
365
+ }
366
+ getIdleTimeout(name) {
367
+ const perServer = this.serverSettings.get(name)?.idleTimeout;
368
+ if (perServer !== undefined)
369
+ return perServer * 60 * 1000;
370
+ return this.globalIdleTimeout;
371
+ }
372
+ async gracefulShutdown() {
373
+ if (this.shutdownPromise)
374
+ return this.shutdownPromise;
375
+ this.shutdownPromise = this.shutdownOnce();
376
+ return this.shutdownPromise;
377
+ }
378
+ async shutdownOnce() {
379
+ this.stopped = true;
380
+ if (this.healthCheckInterval)
381
+ clearInterval(this.healthCheckInterval);
382
+ this.healthCheckInterval = undefined;
383
+ this.removeHealthAbortListener?.();
384
+ this.removeHealthAbortListener = undefined;
385
+ await this.activeHealthCheck;
386
+ this.activeHealthCheck = undefined;
387
+ await this.activeConvergence;
388
+ this.activeConvergence = undefined;
389
+ this.onReconnect = undefined;
390
+ this.onReconnectFailure = undefined;
391
+ this.onHealthRestored = undefined;
392
+ this.onAuthRequired = undefined;
393
+ this.onIdleShutdown = undefined;
394
+ this.retryStates.clear();
395
+ this.pendingMetadataPublications.clear();
396
+ if (typeof this.manager.closeAll === "function") {
397
+ await this.manager.closeAll();
398
+ }
399
+ }
400
+ }
401
+ function shouldReconnectAfterRefresh(error, hadSessionId, definition) {
402
+ if (isTerminatedSession(error, hadSessionId))
403
+ return true;
404
+ // Reconnect baked bearer sources so connect-time resolution runs again.
405
+ if (definition.auth === "bearer" && isUnauthorizedHttpError(error))
406
+ return true;
407
+ return error instanceof SdkError
408
+ && (error.code === SdkErrorCode.NotConnected || error.code === SdkErrorCode.ConnectionClosed);
409
+ }
410
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Centralized logging for MCP UI operations.
3
+ * Provides structured, contextual logs with levels.
4
+ */
5
+ export type LogLevel = "debug" | "info" | "warn" | "error";
6
+ export interface LogContext {
7
+ server?: string;
8
+ session?: string;
9
+ tool?: string;
10
+ uri?: string;
11
+ [key: string]: unknown;
12
+ }
13
+ export interface LogEntry {
14
+ level: LogLevel;
15
+ message: string;
16
+ context?: LogContext;
17
+ error?: Error;
18
+ timestamp: Date;
19
+ }
20
+ type LogHandler = (entry: LogEntry) => void;
21
+ declare class Logger {
22
+ private minLevel;
23
+ private handlers;
24
+ private defaultContext;
25
+ setLevel(level: LogLevel): void;
26
+ setDefaultContext(context: LogContext): void;
27
+ addHandler(handler: LogHandler): void;
28
+ clearHandlers(): void;
29
+ private shouldLog;
30
+ private emit;
31
+ debug(message: string, context?: LogContext): void;
32
+ info(message: string, context?: LogContext): void;
33
+ warn(message: string, context?: LogContext): void;
34
+ error(message: string, error?: Error, context?: LogContext): void;
35
+ /**
36
+ * Create a child logger with additional default context.
37
+ */
38
+ child(context: LogContext): ChildLogger;
39
+ }
40
+ declare class ChildLogger {
41
+ private parent;
42
+ private context;
43
+ constructor(parent: Logger, context: LogContext);
44
+ debug(message: string, context?: LogContext): void;
45
+ info(message: string, context?: LogContext): void;
46
+ warn(message: string, context?: LogContext): void;
47
+ error(message: string, error?: Error, context?: LogContext): void;
48
+ child(context: LogContext): ChildLogger;
49
+ }
50
+ export declare const logger: Logger;
51
+ export {};
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Centralized logging for MCP UI operations.
3
+ * Provides structured, contextual logs with levels.
4
+ */
5
+ const LEVEL_PRIORITY = {
6
+ debug: 0,
7
+ info: 1,
8
+ warn: 2,
9
+ error: 3,
10
+ };
11
+ const LEVEL_PREFIX = {
12
+ debug: "[MCP-UI:DEBUG]",
13
+ info: "[MCP-UI]",
14
+ warn: "[MCP-UI:WARN]",
15
+ error: "[MCP-UI:ERROR]",
16
+ };
17
+ class Logger {
18
+ minLevel = "info";
19
+ handlers = [];
20
+ defaultContext = {};
21
+ setLevel(level) {
22
+ this.minLevel = level;
23
+ }
24
+ setDefaultContext(context) {
25
+ this.defaultContext = context;
26
+ }
27
+ addHandler(handler) {
28
+ this.handlers.push(handler);
29
+ }
30
+ clearHandlers() {
31
+ this.handlers = [];
32
+ }
33
+ shouldLog(level) {
34
+ return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[this.minLevel];
35
+ }
36
+ emit(level, message, context, error) {
37
+ if (!this.shouldLog(level))
38
+ return;
39
+ const entry = {
40
+ level,
41
+ message,
42
+ context: { ...this.defaultContext, ...context },
43
+ ...(error !== undefined ? { error } : {}),
44
+ timestamp: new Date(),
45
+ };
46
+ // Default console output
47
+ const prefix = LEVEL_PREFIX[level];
48
+ const contextStr = formatContext(entry.context);
49
+ const fullMessage = contextStr ? `${prefix} ${message} ${contextStr}` : `${prefix} ${message}`;
50
+ if (level === "error") {
51
+ console.error(fullMessage, error ?? "");
52
+ }
53
+ else if (level === "warn") {
54
+ console.warn(fullMessage);
55
+ }
56
+ else if (level === "debug") {
57
+ console.debug(fullMessage);
58
+ }
59
+ else {
60
+ console.log(fullMessage);
61
+ }
62
+ // Custom handlers
63
+ for (const handler of this.handlers) {
64
+ try {
65
+ handler(entry);
66
+ }
67
+ catch {
68
+ // Ignore handler errors
69
+ }
70
+ }
71
+ }
72
+ debug(message, context) {
73
+ this.emit("debug", message, context);
74
+ }
75
+ info(message, context) {
76
+ this.emit("info", message, context);
77
+ }
78
+ warn(message, context) {
79
+ this.emit("warn", message, context);
80
+ }
81
+ error(message, error, context) {
82
+ this.emit("error", message, context, error);
83
+ }
84
+ /**
85
+ * Create a child logger with additional default context.
86
+ */
87
+ child(context) {
88
+ return new ChildLogger(this, context);
89
+ }
90
+ }
91
+ class ChildLogger {
92
+ parent;
93
+ context;
94
+ constructor(parent, context) {
95
+ this.parent = parent;
96
+ this.context = context;
97
+ }
98
+ debug(message, context) {
99
+ this.parent.debug(message, { ...this.context, ...context });
100
+ }
101
+ info(message, context) {
102
+ this.parent.info(message, { ...this.context, ...context });
103
+ }
104
+ warn(message, context) {
105
+ this.parent.warn(message, { ...this.context, ...context });
106
+ }
107
+ error(message, error, context) {
108
+ this.parent.error(message, error, { ...this.context, ...context });
109
+ }
110
+ child(context) {
111
+ return new ChildLogger(this.parent, { ...this.context, ...context });
112
+ }
113
+ }
114
+ function formatContext(context) {
115
+ if (!context || Object.keys(context).length === 0)
116
+ return "";
117
+ const parts = [];
118
+ for (const [key, value] of Object.entries(context)) {
119
+ if (value !== undefined && value !== null) {
120
+ parts.push(`${key}=${typeof value === "string" ? value : JSON.stringify(value)}`);
121
+ }
122
+ }
123
+ return parts.length > 0 ? `(${parts.join(", ")})` : "";
124
+ }
125
+ // Singleton instance
126
+ export const logger = new Logger();
127
+ // Enable debug mode via environment variable
128
+ if (process.env.MCP_UI_DEBUG === "1" || process.env.MCP_UI_DEBUG === "true") {
129
+ logger.setLevel("debug");
130
+ }
131
+ //# sourceMappingURL=logger.js.map