@vfarcic/dot-ai 1.0.0 → 1.0.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.
@@ -5,10 +5,18 @@
5
5
  * Provides discovered tools to the MCP server for registration.
6
6
  *
7
7
  * PRD #343: kubectl Plugin Migration
8
+ *
9
+ * Background Retry: If plugins aren't ready at startup, discovery continues
10
+ * in the background every 30 seconds. MCP server starts immediately and
11
+ * remains observable via the version tool.
8
12
  */
9
13
  import { PluginConfig, DiscoveredPlugin, InvokeResponse } from './plugin-types';
10
14
  import { Logger } from './error-handling';
11
15
  import { AITool, ToolExecutor } from './ai-provider.interface';
16
+ /**
17
+ * Callback invoked when a plugin is discovered in the background
18
+ */
19
+ export type PluginDiscoveredCallback = (plugin: DiscoveredPlugin) => void;
12
20
  /**
13
21
  * Error thrown when plugin discovery fails
14
22
  */
@@ -30,6 +38,14 @@ export declare class PluginManager {
30
38
  private readonly plugins;
31
39
  private readonly discoveredPlugins;
32
40
  private readonly toolToPlugin;
41
+ /** Plugins pending background discovery */
42
+ private pendingPlugins;
43
+ /** Background retry timer */
44
+ private backgroundRetryTimer;
45
+ /** When background retry started */
46
+ private backgroundRetryStartTime;
47
+ /** Callback for background discovery */
48
+ private onPluginDiscovered;
33
49
  constructor(logger: Logger);
34
50
  /**
35
51
  * Parse plugin configuration from file
@@ -39,20 +55,57 @@ export declare class PluginManager {
39
55
  * Throws on invalid JSON or malformed plugin configuration.
40
56
  */
41
57
  static parsePluginConfig(): PluginConfig[];
58
+ /**
59
+ * Set callback for when plugins are discovered in the background
60
+ *
61
+ * This allows the MCP server to register new tools when plugins
62
+ * become available after initial startup.
63
+ */
64
+ setOnPluginDiscovered(callback: PluginDiscoveredCallback): void;
42
65
  /**
43
66
  * Discover all configured plugins
44
67
  *
45
- * Calls describe hook on each plugin and registers their tools.
46
- * Non-required plugins that fail to respond are logged but don't fail startup.
68
+ * Does a quick initial discovery attempt (2 retries, 1s apart).
69
+ * Plugins that fail are queued for background retry.
70
+ * Required plugins that fail will throw PluginDiscoveryError.
71
+ *
72
+ * Call startBackgroundDiscovery() after this to enable background retries.
47
73
  */
48
74
  discoverPlugins(configs: PluginConfig[]): Promise<void>;
49
75
  /**
50
- * Discover a single plugin with retry logic
76
+ * Start background discovery for plugins that failed initial discovery
77
+ *
78
+ * Retries every 30 seconds for up to 10 minutes.
79
+ * When a plugin is discovered, calls the onPluginDiscovered callback.
80
+ */
81
+ startBackgroundDiscovery(): void;
82
+ /**
83
+ * Stop background discovery
84
+ */
85
+ stopBackgroundDiscovery(): void;
86
+ /**
87
+ * Get pending plugins that are still awaiting discovery
88
+ */
89
+ getPendingPlugins(): string[];
90
+ /**
91
+ * Check if background discovery is active
92
+ */
93
+ isBackgroundDiscoveryActive(): boolean;
94
+ /**
95
+ * Schedule the next background retry attempt
96
+ */
97
+ private scheduleBackgroundRetry;
98
+ /**
99
+ * Run a background retry attempt for all pending plugins
100
+ */
101
+ private runBackgroundRetry;
102
+ /**
103
+ * Quick discovery attempt for a single plugin
51
104
  *
52
- * Retries with exponential backoff to handle Kubernetes startup ordering
53
- * where plugin service may not be ready when MCP server starts.
105
+ * Does 2 retries with 1 second delay. Returns true if discovered,
106
+ * false if should be queued for background retry.
54
107
  */
55
- private discoverPlugin;
108
+ private discoverPluginQuick;
56
109
  /**
57
110
  * Get all discovered tools as AITool format for registration
58
111
  *
@@ -110,6 +163,8 @@ export declare class PluginManager {
110
163
  version: string;
111
164
  toolCount: number;
112
165
  }>;
166
+ pendingDiscovery: string[];
167
+ backgroundDiscoveryActive: boolean;
113
168
  };
114
169
  /**
115
170
  * Convert PluginToolDefinition to AITool format
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/core/plugin-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,YAAY,EAEZ,gBAAgB,EAChB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAK/D;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAG3B,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;gBADrE,OAAO,EAAE,MAAM,EACC,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAKxE;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAChE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4C;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;gBAEnD,MAAM,EAAE,MAAM;IAI1B;;;;;;OAMG;IACH,MAAM,CAAC,iBAAiB,IAAI,YAAY,EAAE;IAuC1C;;;;;OAKG;IACG,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD7D;;;;;OAKG;YACW,cAAc;IA0E5B;;;;;OAKG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAgB9B;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAQ5C;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD;;OAEG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,CAAC;IA8B1B;;;;;;;;;OASG;IACH,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,YAAY,GAAG,YAAY;IAqDjE;;OAEG;IACH,wBAAwB,IAAI,MAAM,EAAE;IAIpC;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAI/D;;OAEG;IACH,uBAAuB,IAAI,gBAAgB,EAAE;IAI7C;;OAEG;IACH,QAAQ,IAAI;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACtE;IAcD;;OAEG;IACH,OAAO,CAAC,eAAe;CAOxB"}
1
+ {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/core/plugin-manager.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,10 @@
6
6
  * Provides discovered tools to the MCP server for registration.
7
7
  *
8
8
  * PRD #343: kubectl Plugin Migration
9
+ *
10
+ * Background Retry: If plugins aren't ready at startup, discovery continues
11
+ * in the background every 30 seconds. MCP server starts immediately and
12
+ * remains observable via the version tool.
9
13
  */
10
14
  Object.defineProperty(exports, "__esModule", { value: true });
11
15
  exports.PluginManager = exports.PluginDiscoveryError = void 0;
@@ -13,6 +17,10 @@ const node_fs_1 = require("node:fs");
13
17
  const plugin_client_1 = require("./plugin-client");
14
18
  /** Path for plugins config file (mounted from ConfigMap in K8s) */
15
19
  const PLUGINS_CONFIG_PATH = '/etc/dot-ai/plugins.json';
20
+ /** Background retry interval in milliseconds */
21
+ const BACKGROUND_RETRY_INTERVAL_MS = 30_000;
22
+ /** Maximum time to keep retrying in background (10 minutes) */
23
+ const BACKGROUND_RETRY_MAX_DURATION_MS = 10 * 60 * 1000;
16
24
  /**
17
25
  * Error thrown when plugin discovery fails
18
26
  */
@@ -33,6 +41,14 @@ class PluginManager {
33
41
  plugins = new Map();
34
42
  discoveredPlugins = new Map();
35
43
  toolToPlugin = new Map();
44
+ /** Plugins pending background discovery */
45
+ pendingPlugins = [];
46
+ /** Background retry timer */
47
+ backgroundRetryTimer = null;
48
+ /** When background retry started */
49
+ backgroundRetryStartTime = null;
50
+ /** Callback for background discovery */
51
+ onPluginDiscovered = null;
36
52
  constructor(logger) {
37
53
  this.logger = logger;
38
54
  }
@@ -79,11 +95,23 @@ class PluginManager {
79
95
  };
80
96
  });
81
97
  }
98
+ /**
99
+ * Set callback for when plugins are discovered in the background
100
+ *
101
+ * This allows the MCP server to register new tools when plugins
102
+ * become available after initial startup.
103
+ */
104
+ setOnPluginDiscovered(callback) {
105
+ this.onPluginDiscovered = callback;
106
+ }
82
107
  /**
83
108
  * Discover all configured plugins
84
109
  *
85
- * Calls describe hook on each plugin and registers their tools.
86
- * Non-required plugins that fail to respond are logged but don't fail startup.
110
+ * Does a quick initial discovery attempt (2 retries, 1s apart).
111
+ * Plugins that fail are queued for background retry.
112
+ * Required plugins that fail will throw PluginDiscoveryError.
113
+ *
114
+ * Call startBackgroundDiscovery() after this to enable background retries.
87
115
  */
88
116
  async discoverPlugins(configs) {
89
117
  if (configs.length === 0) {
@@ -94,24 +122,29 @@ class PluginManager {
94
122
  pluginCount: configs.length,
95
123
  plugins: configs.map((c) => c.name),
96
124
  });
97
- const results = await Promise.allSettled(configs.map((config) => this.discoverPlugin(config)));
125
+ const results = await Promise.allSettled(configs.map((config) => this.discoverPluginQuick(config)));
98
126
  const failed = [];
99
127
  const requiredFailed = [];
100
128
  results.forEach((result, index) => {
101
129
  const config = configs[index];
102
- if (result.status === 'rejected') {
103
- const error = result.reason instanceof Error
104
- ? result.reason.message
105
- : String(result.reason);
130
+ if (result.status === 'rejected' || (result.status === 'fulfilled' && !result.value)) {
131
+ const error = result.status === 'rejected'
132
+ ? (result.reason instanceof Error ? result.reason.message : String(result.reason))
133
+ : 'Discovery failed';
106
134
  failed.push({ name: config.name, error });
107
135
  if (config.required) {
108
136
  requiredFailed.push({ name: config.name, error });
109
137
  }
138
+ else {
139
+ // Queue for background retry
140
+ this.pendingPlugins.push(config);
141
+ }
110
142
  }
111
143
  });
112
144
  if (failed.length > 0) {
113
- this.logger.warn('Some plugins failed to discover', {
145
+ this.logger.warn('Some plugins failed initial discovery', {
114
146
  failed: failed.map((f) => f.name),
147
+ willRetryInBackground: this.pendingPlugins.map((p) => p.name),
115
148
  });
116
149
  }
117
150
  if (requiredFailed.length > 0) {
@@ -120,19 +153,120 @@ class PluginManager {
120
153
  this.logger.info('Plugin discovery complete', {
121
154
  discovered: this.discoveredPlugins.size,
122
155
  totalTools: this.toolToPlugin.size,
156
+ pendingBackgroundRetry: this.pendingPlugins.length,
157
+ });
158
+ }
159
+ /**
160
+ * Start background discovery for plugins that failed initial discovery
161
+ *
162
+ * Retries every 30 seconds for up to 10 minutes.
163
+ * When a plugin is discovered, calls the onPluginDiscovered callback.
164
+ */
165
+ startBackgroundDiscovery() {
166
+ if (this.pendingPlugins.length === 0) {
167
+ this.logger.debug('No pending plugins for background discovery');
168
+ return;
169
+ }
170
+ this.backgroundRetryStartTime = Date.now();
171
+ this.logger.info('Starting background plugin discovery', {
172
+ pendingPlugins: this.pendingPlugins.map((p) => p.name),
173
+ retryIntervalMs: BACKGROUND_RETRY_INTERVAL_MS,
174
+ maxDurationMs: BACKGROUND_RETRY_MAX_DURATION_MS,
175
+ });
176
+ this.scheduleBackgroundRetry();
177
+ }
178
+ /**
179
+ * Stop background discovery
180
+ */
181
+ stopBackgroundDiscovery() {
182
+ if (this.backgroundRetryTimer) {
183
+ clearTimeout(this.backgroundRetryTimer);
184
+ this.backgroundRetryTimer = null;
185
+ this.logger.info('Stopped background plugin discovery', {
186
+ remainingPending: this.pendingPlugins.map((p) => p.name),
187
+ });
188
+ }
189
+ this.backgroundRetryStartTime = null;
190
+ }
191
+ /**
192
+ * Get pending plugins that are still awaiting discovery
193
+ */
194
+ getPendingPlugins() {
195
+ return this.pendingPlugins.map((p) => p.name);
196
+ }
197
+ /**
198
+ * Check if background discovery is active
199
+ */
200
+ isBackgroundDiscoveryActive() {
201
+ return this.backgroundRetryTimer !== null;
202
+ }
203
+ /**
204
+ * Schedule the next background retry attempt
205
+ */
206
+ scheduleBackgroundRetry() {
207
+ this.backgroundRetryTimer = setTimeout(async () => {
208
+ await this.runBackgroundRetry();
209
+ }, BACKGROUND_RETRY_INTERVAL_MS);
210
+ }
211
+ /**
212
+ * Run a background retry attempt for all pending plugins
213
+ */
214
+ async runBackgroundRetry() {
215
+ // Check if we've exceeded max duration
216
+ if (this.backgroundRetryStartTime) {
217
+ const elapsed = Date.now() - this.backgroundRetryStartTime;
218
+ if (elapsed >= BACKGROUND_RETRY_MAX_DURATION_MS) {
219
+ this.logger.warn('Background plugin discovery timed out', {
220
+ elapsedMs: elapsed,
221
+ remainingPending: this.pendingPlugins.map((p) => p.name),
222
+ });
223
+ this.stopBackgroundDiscovery();
224
+ return;
225
+ }
226
+ }
227
+ this.logger.debug('Running background plugin discovery attempt', {
228
+ pendingCount: this.pendingPlugins.length,
123
229
  });
230
+ // Try each pending plugin
231
+ const stillPending = [];
232
+ for (const config of this.pendingPlugins) {
233
+ const discovered = await this.discoverPluginQuick(config);
234
+ if (discovered) {
235
+ // Plugin discovered - notify callback
236
+ const plugin = this.discoveredPlugins.get(config.name);
237
+ if (plugin && this.onPluginDiscovered) {
238
+ this.logger.info('Plugin discovered in background', {
239
+ name: plugin.name,
240
+ version: plugin.version,
241
+ toolCount: plugin.tools.length,
242
+ });
243
+ this.onPluginDiscovered(plugin);
244
+ }
245
+ }
246
+ else {
247
+ stillPending.push(config);
248
+ }
249
+ }
250
+ this.pendingPlugins = stillPending;
251
+ // If all discovered, stop background retry
252
+ if (this.pendingPlugins.length === 0) {
253
+ this.logger.info('All plugins discovered, stopping background discovery');
254
+ this.stopBackgroundDiscovery();
255
+ return;
256
+ }
257
+ // Schedule next retry
258
+ this.scheduleBackgroundRetry();
124
259
  }
125
260
  /**
126
- * Discover a single plugin with retry logic
261
+ * Quick discovery attempt for a single plugin
127
262
  *
128
- * Retries with exponential backoff to handle Kubernetes startup ordering
129
- * where plugin service may not be ready when MCP server starts.
263
+ * Does 2 retries with 1 second delay. Returns true if discovered,
264
+ * false if should be queued for background retry.
130
265
  */
131
- async discoverPlugin(config) {
266
+ async discoverPluginQuick(config) {
132
267
  const client = new plugin_client_1.PluginClient(config, this.logger);
133
- const maxRetries = 5;
134
- const baseDelayMs = 1000;
135
- let lastError;
268
+ const maxRetries = 2;
269
+ const retryDelayMs = 1000;
136
270
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
137
271
  try {
138
272
  const response = await client.describe();
@@ -163,33 +297,28 @@ class PluginManager {
163
297
  tools: response.tools.map((t) => t.name),
164
298
  attempts: attempt,
165
299
  });
166
- return;
300
+ return true;
167
301
  }
168
302
  catch (error) {
169
- lastError = error instanceof Error ? error : new Error(String(error));
303
+ const errorMessage = error instanceof Error ? error.message : String(error);
170
304
  if (attempt < maxRetries) {
171
- const delayMs = baseDelayMs * Math.pow(2, attempt - 1);
172
- this.logger.warn('Plugin discovery failed, retrying', {
305
+ this.logger.debug('Plugin discovery attempt failed, retrying', {
173
306
  plugin: config.name,
174
307
  attempt,
175
- maxRetries,
176
- delayMs,
177
- error: lastError.message,
308
+ error: errorMessage,
309
+ });
310
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
311
+ }
312
+ else {
313
+ this.logger.debug('Plugin discovery failed, will retry in background', {
314
+ plugin: config.name,
315
+ attempts: maxRetries,
316
+ error: errorMessage,
178
317
  });
179
- await new Promise((resolve) => setTimeout(resolve, delayMs));
180
318
  }
181
319
  }
182
320
  }
183
- // All retries exhausted - throw the last error
184
- const message = lastError instanceof plugin_client_1.PluginClientError
185
- ? lastError.message
186
- : lastError?.message || 'Unknown error';
187
- this.logger.error('Failed to discover plugin after retries', new Error(message), {
188
- plugin: config.name,
189
- url: config.url,
190
- attempts: maxRetries,
191
- });
192
- throw lastError;
321
+ return false;
193
322
  }
194
323
  /**
195
324
  * Get all discovered tools as AITool format for registration
@@ -350,6 +479,8 @@ class PluginManager {
350
479
  pluginCount: this.discoveredPlugins.size,
351
480
  toolCount: this.toolToPlugin.size,
352
481
  plugins,
482
+ pendingDiscovery: this.pendingPlugins.map((p) => p.name),
483
+ backgroundDiscoveryActive: this.isBackgroundDiscoveryActive(),
353
484
  };
354
485
  }
355
486
  /**
@@ -44,10 +44,6 @@ export declare class MCPServer {
44
44
  * Register all tools with McpServer and REST registry
45
45
  */
46
46
  private registerTools;
47
- /**
48
- * Register tools from discovered plugins (PRD #343)
49
- */
50
- private registerPluginTools;
51
47
  /**
52
48
  * Register prompts capability with McpServer
53
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAuDtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACvC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAC,CAAkC;IACrD,OAAO,CAAC,aAAa,CAAC,CAAgC;IACtD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAE1B,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IAiEjD;;OAEG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoKrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA2D3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,qBAAqB;YAgBf,qBAAqB;IAyBnC,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,kBAAkB;YA+HlB,gBAAgB;IAexB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,OAAO,IAAI,OAAO;CAGnB"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAuDtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACvC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAC,CAAkC;IACrD,OAAO,CAAC,aAAa,CAAC,CAAgC;IACtD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAE1B,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IAiEjD;;OAEG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAwKrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,qBAAqB;YAgBf,qBAAqB;IAyBnC,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,kBAAkB;YA+HlB,gBAAgB;IAexB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,OAAO,IAAI,OAAO;CAGnB"}
@@ -187,8 +187,10 @@ class MCPServer {
187
187
  this.logger.info(`Processing ${query_1.QUERY_TOOL_NAME} tool request`, { requestId });
188
188
  return await (0, query_1.handleQueryTool)(args, this.pluginManager);
189
189
  }, 'Intelligence', ['query', 'search', 'discover', 'capabilities', 'cluster']);
190
- // Register plugin tools (PRD #343)
191
- const pluginTools = this.registerPluginTools();
190
+ // NOTE: Plugin tools (kubectl_*, helm_*, shell_exec) are NOT registered as MCP tools.
191
+ // They are internal implementation details used by built-in tools like remediate/query.
192
+ // Plugin tools remain available internally via pluginManager.invokeTool().
193
+ // Only the 7 built-in MCP tools are exposed to clients.
192
194
  const builtInTools = [
193
195
  recommend_1.RECOMMEND_TOOL_NAME,
194
196
  version_1.VERSION_TOOL_NAME,
@@ -198,55 +200,14 @@ class MCPServer {
198
200
  project_setup_1.PROJECT_SETUP_TOOL_NAME,
199
201
  query_1.QUERY_TOOL_NAME
200
202
  ];
201
- this.logger.info('Registered all tools with McpServer', {
203
+ // Log summary of tool registration
204
+ const pluginToolCount = this.pluginManager?.getDiscoveredTools().length || 0;
205
+ this.logger.info('Registered tools with McpServer', {
202
206
  builtInTools,
203
- pluginTools,
204
- totalTools: builtInTools.length + pluginTools.length,
207
+ totalRegistered: builtInTools.length,
208
+ pluginToolsAvailableInternally: pluginToolCount,
205
209
  });
206
210
  }
207
- /**
208
- * Register tools from discovered plugins (PRD #343)
209
- */
210
- registerPluginTools() {
211
- if (!this.pluginManager) {
212
- return [];
213
- }
214
- const tools = this.pluginManager.getDiscoveredTools();
215
- const registeredTools = [];
216
- for (const tool of tools) {
217
- // Create handler that routes to plugin
218
- const pluginHandler = async (args) => {
219
- const response = await this.pluginManager.invokeTool(tool.name, args, {}, undefined);
220
- // Return proper MCP CallToolResult format
221
- if (response.success) {
222
- return {
223
- content: [{
224
- type: 'text',
225
- text: JSON.stringify(response.result)
226
- }]
227
- };
228
- }
229
- else {
230
- return {
231
- content: [{
232
- type: 'text',
233
- text: JSON.stringify({ error: response.error?.message || 'Plugin invocation failed' })
234
- }],
235
- isError: true
236
- };
237
- }
238
- };
239
- this.registerTool(tool.name, tool.description, tool.inputSchema, pluginHandler, 'Plugin', ['plugin', 'kubectl', 'kubernetes']);
240
- registeredTools.push(tool.name);
241
- }
242
- if (registeredTools.length > 0) {
243
- this.logger.info('Registered plugin tools', {
244
- tools: registeredTools,
245
- count: registeredTools.length,
246
- });
247
- }
248
- return registeredTools;
249
- }
250
211
  /**
251
212
  * Register prompts capability with McpServer
252
213
  */
@@ -132,7 +132,11 @@ async function main() {
132
132
  try {
133
133
  await pluginManager.discoverPlugins(pluginConfigs);
134
134
  const stats = pluginManager.getStats();
135
+ const pending = pluginManager.getPendingPlugins();
135
136
  process.stderr.write(`Plugin discovery complete: ${stats.pluginCount} plugin(s), ${stats.toolCount} tool(s)\n`);
137
+ if (pending.length > 0) {
138
+ process.stderr.write(`Plugins pending background discovery: ${pending.join(', ')}\n`);
139
+ }
136
140
  }
137
141
  catch (error) {
138
142
  // Non-required plugin failures are warnings, required failures throw
@@ -142,6 +146,16 @@ async function main() {
142
146
  }
143
147
  process.stderr.write(`Plugin discovery warning: ${error}\n`);
144
148
  }
149
+ // Start background discovery for any plugins that failed initial discovery
150
+ // They will be retried every 30 seconds for up to 10 minutes
151
+ if (pluginManager.getPendingPlugins().length > 0) {
152
+ pluginManager.setOnPluginDiscovered((plugin) => {
153
+ process.stderr.write(`Background discovery: Plugin '${plugin.name}' now available with ${plugin.tools.length} tool(s)\n`);
154
+ // Note: Tools are automatically registered via pluginManager's internal maps
155
+ // The version tool will reflect the updated plugin status
156
+ });
157
+ pluginManager.startBackgroundDiscovery();
158
+ }
145
159
  }
146
160
  else {
147
161
  process.stderr.write('No plugins configured (mount plugins.json at /etc/dot-ai/plugins.json to enable)\n');
@@ -170,6 +184,8 @@ async function main() {
170
184
  // Handle graceful shutdown
171
185
  const gracefulShutdown = async (signal) => {
172
186
  process.stderr.write(`Shutting down DevOps AI Toolkit MCP server (${signal})...\n`);
187
+ // Stop background plugin discovery if active
188
+ pluginManager.stopBackgroundDiscovery();
173
189
  // Track server stop telemetry
174
190
  const uptimeSeconds = Math.floor((Date.now() - serverStartTime) / 1000);
175
191
  (0, index_js_3.getTelemetry)().trackServerStop(uptimeSeconds);
@@ -107,6 +107,8 @@ export interface SystemStatus {
107
107
  version: string;
108
108
  toolCount: number;
109
109
  }>;
110
+ pendingDiscovery: string[];
111
+ backgroundDiscoveryActive: boolean;
110
112
  };
111
113
  }
112
114
  export interface VersionSessionData extends BaseVisualizationData {
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/tools/version.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/tools/version.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
5
5
  "mcpName": "io.github.vfarcic/dot-ai",
6
6
  "main": "dist/index.js",