@vfarcic/dot-ai 1.10.2 → 1.12.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 (56) hide show
  1. package/dist/core/ai-provider-factory.d.ts.map +1 -1
  2. package/dist/core/ai-provider-factory.js +1 -0
  3. package/dist/core/error-handling.js +1 -1
  4. package/dist/core/git-utils.d.ts +5 -0
  5. package/dist/core/git-utils.d.ts.map +1 -1
  6. package/dist/core/git-utils.js +16 -0
  7. package/dist/core/internal-tools.d.ts +35 -0
  8. package/dist/core/internal-tools.d.ts.map +1 -0
  9. package/dist/core/internal-tools.js +286 -0
  10. package/dist/core/mcp-client-manager.d.ts +88 -0
  11. package/dist/core/mcp-client-manager.d.ts.map +1 -0
  12. package/dist/core/mcp-client-manager.js +362 -0
  13. package/dist/core/mcp-client-registry.d.ts +36 -0
  14. package/dist/core/mcp-client-registry.d.ts.map +1 -0
  15. package/dist/core/mcp-client-registry.js +52 -0
  16. package/dist/core/mcp-client-types.d.ts +84 -0
  17. package/dist/core/mcp-client-types.d.ts.map +1 -0
  18. package/dist/core/mcp-client-types.js +24 -0
  19. package/dist/core/model-config.d.ts +1 -0
  20. package/dist/core/model-config.d.ts.map +1 -1
  21. package/dist/core/model-config.js +1 -0
  22. package/dist/core/providers/vercel-provider.d.ts.map +1 -1
  23. package/dist/core/providers/vercel-provider.js +5 -0
  24. package/dist/interfaces/mcp.d.ts.map +1 -1
  25. package/dist/interfaces/mcp.js +13 -0
  26. package/dist/mcp/server.js +26 -1
  27. package/dist/tools/generate-manifests.d.ts.map +1 -1
  28. package/dist/tools/generate-manifests.js +2 -1
  29. package/dist/tools/impact-analysis.d.ts +51 -0
  30. package/dist/tools/impact-analysis.d.ts.map +1 -0
  31. package/dist/tools/impact-analysis.js +204 -0
  32. package/dist/tools/index.d.ts +1 -0
  33. package/dist/tools/index.d.ts.map +1 -1
  34. package/dist/tools/index.js +6 -1
  35. package/dist/tools/operate-analysis.d.ts +1 -1
  36. package/dist/tools/operate-analysis.d.ts.map +1 -1
  37. package/dist/tools/operate-analysis.js +17 -6
  38. package/dist/tools/operate.d.ts +1 -1
  39. package/dist/tools/operate.d.ts.map +1 -1
  40. package/dist/tools/operate.js +1 -1
  41. package/dist/tools/organizational-data.d.ts +1 -1
  42. package/dist/tools/push-to-git.d.ts.map +1 -1
  43. package/dist/tools/push-to-git.js +1 -11
  44. package/dist/tools/query.d.ts +1 -1
  45. package/dist/tools/query.d.ts.map +1 -1
  46. package/dist/tools/query.js +18 -8
  47. package/dist/tools/remediate.d.ts +9 -0
  48. package/dist/tools/remediate.d.ts.map +1 -1
  49. package/dist/tools/remediate.js +45 -10
  50. package/dist/tools/version.d.ts +12 -0
  51. package/dist/tools/version.d.ts.map +1 -1
  52. package/dist/tools/version.js +16 -1
  53. package/package.json +3 -1
  54. package/prompts/impact-analysis-system.md +32 -0
  55. package/prompts/operate-system.md +3 -3
  56. package/prompts/remediate-system.md +62 -2
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Client Manager for dot-ai MCP Server Integration
4
+ *
5
+ * Connects to external MCP servers running in the cluster, discovers their tools,
6
+ * and makes them available to dot-ai operations (remediate, operate, query) via
7
+ * the attachTo routing mechanism.
8
+ *
9
+ * PRD #358: MCP Server Integration
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.McpClientManager = void 0;
13
+ const node_fs_1 = require("node:fs");
14
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
15
+ const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
16
+ const mcp_client_types_1 = require("./mcp-client-types");
17
+ /** Path for MCP servers config file (mounted from ConfigMap in K8s) */
18
+ const MCP_SERVERS_CONFIG_PATH = '/etc/dot-ai-mcp/mcp-servers.json';
19
+ /** Separator used to namespace MCP tools: {serverName}__{toolName} */
20
+ const TOOL_NAME_SEPARATOR = '__';
21
+ /** Default timeout for MCP requests in milliseconds */
22
+ const DEFAULT_TIMEOUT_MS = 30_000;
23
+ /**
24
+ * Manages MCP server connections, tool discovery, and tool routing.
25
+ *
26
+ * Follows the same structural patterns as PluginManager but uses
27
+ * the MCP SDK (Client + StreamableHTTPClientTransport) instead of HTTP REST.
28
+ */
29
+ class McpClientManager {
30
+ logger;
31
+ /** MCP SDK Client instances keyed by server name */
32
+ clients = new Map();
33
+ /** Transport instances keyed by server name (needed for cleanup) */
34
+ transports = new Map();
35
+ /** Discovered server metadata keyed by server name */
36
+ discoveredServers = new Map();
37
+ /** Maps namespaced tool name → server name for routing */
38
+ toolToServer = new Map();
39
+ constructor(logger) {
40
+ this.logger = logger;
41
+ }
42
+ /**
43
+ * Parse MCP server configuration from file.
44
+ *
45
+ * Reads from /etc/dot-ai-mcp/mcp-servers.json (mounted from ConfigMap in K8s).
46
+ * Returns empty array if file doesn't exist (MCP servers only work in-cluster).
47
+ * Throws on invalid JSON or malformed configuration.
48
+ */
49
+ static parseMcpServerConfig() {
50
+ if (!(0, node_fs_1.existsSync)(MCP_SERVERS_CONFIG_PATH)) {
51
+ return [];
52
+ }
53
+ let content;
54
+ try {
55
+ content = (0, node_fs_1.readFileSync)(MCP_SERVERS_CONFIG_PATH, 'utf-8');
56
+ }
57
+ catch (err) {
58
+ throw new Error(`Failed to read MCP server config at ${MCP_SERVERS_CONFIG_PATH}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
59
+ }
60
+ let parsed;
61
+ try {
62
+ parsed = JSON.parse(content);
63
+ }
64
+ catch (err) {
65
+ throw new Error(`Invalid JSON in MCP server config at ${MCP_SERVERS_CONFIG_PATH}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
66
+ }
67
+ if (!Array.isArray(parsed)) {
68
+ throw new Error(`MCP server config at ${MCP_SERVERS_CONFIG_PATH} must be an array, got ${typeof parsed}`);
69
+ }
70
+ const validOperations = ['remediate', 'operate', 'query'];
71
+ return parsed.map((s, index) => {
72
+ if (!s || typeof s !== 'object') {
73
+ throw new Error(`MCP server at index ${index} must be an object`);
74
+ }
75
+ if (!s.endpoint || typeof s.endpoint !== 'string') {
76
+ throw new Error(`MCP server at index ${index} (${s.name || 'unnamed'}) is missing required 'endpoint' field`);
77
+ }
78
+ if (!Array.isArray(s.attachTo) || s.attachTo.length === 0) {
79
+ throw new Error(`MCP server at index ${index} (${s.name || 'unnamed'}) must have a non-empty 'attachTo' array`);
80
+ }
81
+ for (const op of s.attachTo) {
82
+ if (!validOperations.includes(op)) {
83
+ throw new Error(`MCP server at index ${index} (${s.name || 'unnamed'}) has invalid attachTo value '${op}'. Must be one of: ${validOperations.join(', ')}`);
84
+ }
85
+ }
86
+ return {
87
+ name: s.name || `mcp-server-${index}`,
88
+ endpoint: s.endpoint,
89
+ attachTo: s.attachTo,
90
+ timeout: s.timeout,
91
+ };
92
+ });
93
+ }
94
+ /**
95
+ * Discover all configured MCP servers.
96
+ *
97
+ * Connects to each server, performs MCP handshake, and discovers available tools.
98
+ * All servers must connect successfully — any failure throws McpDiscoveryError.
99
+ */
100
+ async discoverMcpServers(configs) {
101
+ if (configs.length === 0) {
102
+ this.logger.debug('No MCP servers configured for discovery');
103
+ return;
104
+ }
105
+ this.logger.info('Starting MCP server discovery', {
106
+ serverCount: configs.length,
107
+ servers: configs.map(c => c.name),
108
+ });
109
+ const results = await Promise.allSettled(configs.map(config => this.connectAndDiscover(config)));
110
+ const failed = [];
111
+ results.forEach((result, index) => {
112
+ const config = configs[index];
113
+ if (result.status === 'rejected') {
114
+ const error = result.reason instanceof Error
115
+ ? result.reason.message
116
+ : String(result.reason);
117
+ failed.push({ name: config.name, error });
118
+ }
119
+ });
120
+ if (failed.length > 0) {
121
+ throw new mcp_client_types_1.McpDiscoveryError(`MCP server discovery failed: ${failed.map(f => `${f.name} (${f.error})`).join(', ')}`, failed);
122
+ }
123
+ this.logger.info('MCP server discovery complete', {
124
+ discovered: this.discoveredServers.size,
125
+ totalTools: this.toolToServer.size,
126
+ });
127
+ }
128
+ /**
129
+ * Connect to a single MCP server and discover its tools.
130
+ */
131
+ async connectAndDiscover(config) {
132
+ const timeout = config.timeout || DEFAULT_TIMEOUT_MS;
133
+ this.logger.debug('Connecting to MCP server', {
134
+ name: config.name,
135
+ endpoint: config.endpoint,
136
+ attachTo: config.attachTo,
137
+ });
138
+ const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(config.endpoint), {
139
+ reconnectionOptions: {
140
+ maxReconnectionDelay: 30_000,
141
+ initialReconnectionDelay: 1_000,
142
+ reconnectionDelayGrowFactor: 1.5,
143
+ maxRetries: 2,
144
+ },
145
+ });
146
+ const client = new index_js_1.Client({ name: 'dot-ai', version: '1.0.0' }, { capabilities: {} });
147
+ // Connect with timeout
148
+ const connectPromise = client.connect(transport);
149
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Connection timed out after ${timeout}ms`)), timeout));
150
+ try {
151
+ await Promise.race([connectPromise, timeoutPromise]);
152
+ }
153
+ catch (err) {
154
+ // Clean up transport on failure
155
+ try {
156
+ await transport.close();
157
+ }
158
+ catch { /* ignore cleanup errors */ }
159
+ throw new Error(`Failed to connect to MCP server '${config.name}' at ${config.endpoint}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
160
+ }
161
+ // Discover tools
162
+ let tools;
163
+ try {
164
+ const result = await client.listTools();
165
+ tools = result.tools.map(t => ({
166
+ name: t.name,
167
+ description: t.description,
168
+ inputSchema: {
169
+ type: t.inputSchema.type,
170
+ properties: t.inputSchema.properties,
171
+ required: t.inputSchema.required,
172
+ },
173
+ }));
174
+ }
175
+ catch (err) {
176
+ try {
177
+ await transport.close();
178
+ }
179
+ catch { /* ignore cleanup errors */ }
180
+ throw new Error(`Failed to list tools from MCP server '${config.name}': ${err instanceof Error ? err.message : String(err)}`, { cause: err });
181
+ }
182
+ // Store client and transport
183
+ this.clients.set(config.name, client);
184
+ this.transports.set(config.name, transport);
185
+ // Store discovered server metadata
186
+ this.discoveredServers.set(config.name, {
187
+ name: config.name,
188
+ endpoint: config.endpoint,
189
+ attachTo: config.attachTo,
190
+ version: client.getServerVersion()?.version,
191
+ tools,
192
+ discoveredAt: new Date(),
193
+ });
194
+ // Map namespaced tools to server
195
+ for (const tool of tools) {
196
+ const namespacedName = `${config.name}${TOOL_NAME_SEPARATOR}${tool.name}`;
197
+ if (this.toolToServer.has(namespacedName)) {
198
+ this.logger.warn('Namespaced tool name conflict - overwriting', {
199
+ tool: namespacedName,
200
+ existingServer: this.toolToServer.get(namespacedName),
201
+ newServer: config.name,
202
+ });
203
+ }
204
+ this.toolToServer.set(namespacedName, config.name);
205
+ }
206
+ this.logger.info('MCP server discovered', {
207
+ name: config.name,
208
+ version: client.getServerVersion()?.version,
209
+ tools: tools.map(t => t.name),
210
+ namespacedTools: tools.map(t => `${config.name}${TOOL_NAME_SEPARATOR}${t.name}`),
211
+ });
212
+ }
213
+ /**
214
+ * Get tools available for a specific dot-ai operation, filtered by attachTo.
215
+ *
216
+ * Returns tools as AITool[] with namespaced names ({serverName}__{toolName}).
217
+ */
218
+ getToolsForOperation(operation) {
219
+ const tools = [];
220
+ for (const server of this.discoveredServers.values()) {
221
+ if (!server.attachTo.includes(operation)) {
222
+ continue;
223
+ }
224
+ for (const tool of server.tools) {
225
+ const namespacedName = `${server.name}${TOOL_NAME_SEPARATOR}${tool.name}`;
226
+ // Only include if this server owns the routing
227
+ if (this.toolToServer.get(namespacedName) === server.name) {
228
+ tools.push(this.convertToAITool(server.name, tool));
229
+ }
230
+ }
231
+ }
232
+ return tools;
233
+ }
234
+ /**
235
+ * Get all discovered tools across all servers.
236
+ */
237
+ getAllDiscoveredTools() {
238
+ const tools = [];
239
+ for (const server of this.discoveredServers.values()) {
240
+ for (const tool of server.tools) {
241
+ const namespacedName = `${server.name}${TOOL_NAME_SEPARATOR}${tool.name}`;
242
+ if (this.toolToServer.get(namespacedName) === server.name) {
243
+ tools.push(this.convertToAITool(server.name, tool));
244
+ }
245
+ }
246
+ }
247
+ return tools;
248
+ }
249
+ /**
250
+ * Check if a tool name belongs to an MCP server (is namespaced).
251
+ */
252
+ isMcpTool(toolName) {
253
+ return this.toolToServer.has(toolName);
254
+ }
255
+ /**
256
+ * Create a ToolExecutor that routes MCP tools to their servers.
257
+ *
258
+ * Returns a function compatible with toolLoop's toolExecutor parameter.
259
+ * MCP tools (namespaced) are routed to their MCP servers; non-MCP tools
260
+ * are routed to the optional fallback executor.
261
+ */
262
+ createToolExecutor(fallbackExecutor) {
263
+ return async (toolName, input) => {
264
+ if (this.isMcpTool(toolName)) {
265
+ this.logger.debug('Routing tool to MCP server', {
266
+ tool: toolName,
267
+ server: this.toolToServer.get(toolName),
268
+ });
269
+ try {
270
+ const serverName = this.toolToServer.get(toolName);
271
+ const originalToolName = toolName.substring(serverName.length + TOOL_NAME_SEPARATOR.length);
272
+ const client = this.clients.get(serverName);
273
+ if (!client) {
274
+ return `Error: MCP server '${serverName}' is not connected`;
275
+ }
276
+ const result = await client.callTool({
277
+ name: originalToolName,
278
+ arguments: input,
279
+ });
280
+ // Extract text content from MCP response
281
+ const contentArray = result.content;
282
+ if (result.isError) {
283
+ const errorText = contentArray
284
+ ?.filter(c => c.type === 'text')
285
+ .map(c => c.text)
286
+ .join('\n') || 'Unknown MCP tool error';
287
+ return `Error: ${errorText}`;
288
+ }
289
+ // Return text content for AI consumption
290
+ const textContent = contentArray
291
+ ?.filter(c => c.type === 'text')
292
+ .map(c => c.text)
293
+ .join('\n');
294
+ return textContent || '';
295
+ }
296
+ catch (err) {
297
+ const message = err instanceof Error ? err.message : String(err);
298
+ this.logger.error('MCP tool invocation failed', new Error(message), { tool: toolName, server: this.toolToServer.get(toolName) });
299
+ return `Error: ${message}`;
300
+ }
301
+ }
302
+ // Fall back to provided executor for non-MCP tools
303
+ if (fallbackExecutor) {
304
+ return fallbackExecutor(toolName, input);
305
+ }
306
+ return `Error: Tool '${toolName}' not found in MCP servers or fallback executor`;
307
+ };
308
+ }
309
+ /**
310
+ * Get statistics about MCP server connections.
311
+ */
312
+ getStats() {
313
+ return {
314
+ serverCount: this.discoveredServers.size,
315
+ toolCount: this.toolToServer.size,
316
+ servers: Array.from(this.discoveredServers.keys()),
317
+ };
318
+ }
319
+ /**
320
+ * Get discovered server metadata.
321
+ */
322
+ getDiscoveredServers() {
323
+ return Array.from(this.discoveredServers.values());
324
+ }
325
+ /**
326
+ * Close all MCP server connections.
327
+ */
328
+ async close() {
329
+ for (const [name, transport] of this.transports.entries()) {
330
+ try {
331
+ await transport.close();
332
+ this.logger.debug('Closed MCP server connection', { name });
333
+ }
334
+ catch (err) {
335
+ this.logger.warn('Error closing MCP server connection', {
336
+ name,
337
+ error: err instanceof Error ? err.message : String(err),
338
+ });
339
+ }
340
+ }
341
+ this.clients.clear();
342
+ this.transports.clear();
343
+ this.discoveredServers.clear();
344
+ this.toolToServer.clear();
345
+ }
346
+ /**
347
+ * Convert an MCP tool definition to AITool format with namespaced name.
348
+ */
349
+ convertToAITool(serverName, tool) {
350
+ const namespacedName = `${serverName}${TOOL_NAME_SEPARATOR}${tool.name}`;
351
+ return {
352
+ name: namespacedName,
353
+ description: `[${serverName}] ${tool.description || tool.name}`,
354
+ inputSchema: {
355
+ type: 'object',
356
+ properties: tool.inputSchema.properties || {},
357
+ required: tool.inputSchema.required,
358
+ },
359
+ };
360
+ }
361
+ }
362
+ exports.McpClientManager = McpClientManager;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * MCP Client Registry - Unified MCP Server Tool Access
3
+ *
4
+ * PRD #358: Provides a single, consistent way to access MCP server tools
5
+ * from anywhere in the codebase (remediate, operate, query).
6
+ *
7
+ * Usage:
8
+ * // At startup (src/mcp/server.ts):
9
+ * initializeMcpClientRegistry(mcpClientManager);
10
+ *
11
+ * // Anywhere in the codebase:
12
+ * if (isMcpClientInitialized()) {
13
+ * const tools = getMcpClientManager()!.getToolsForOperation('remediate');
14
+ * }
15
+ */
16
+ import type { McpClientManager } from './mcp-client-manager';
17
+ /**
18
+ * Initialize the MCP client registry with a McpClientManager instance.
19
+ * Must be called once at startup after MCP servers are discovered.
20
+ */
21
+ export declare function initializeMcpClientRegistry(manager: McpClientManager): void;
22
+ /**
23
+ * Get the McpClientManager instance.
24
+ * Returns null if not initialized.
25
+ */
26
+ export declare function getMcpClientManager(): McpClientManager | null;
27
+ /**
28
+ * Check if the MCP client registry is initialized.
29
+ */
30
+ export declare function isMcpClientInitialized(): boolean;
31
+ /**
32
+ * Reset the MCP client registry (for testing only).
33
+ * @internal
34
+ */
35
+ export declare function resetMcpClientRegistry(): void;
36
+ //# sourceMappingURL=mcp-client-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client-registry.d.ts","sourceRoot":"","sources":["../../src/core/mcp-client-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Client Registry - Unified MCP Server Tool Access
4
+ *
5
+ * PRD #358: Provides a single, consistent way to access MCP server tools
6
+ * from anywhere in the codebase (remediate, operate, query).
7
+ *
8
+ * Usage:
9
+ * // At startup (src/mcp/server.ts):
10
+ * initializeMcpClientRegistry(mcpClientManager);
11
+ *
12
+ * // Anywhere in the codebase:
13
+ * if (isMcpClientInitialized()) {
14
+ * const tools = getMcpClientManager()!.getToolsForOperation('remediate');
15
+ * }
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.initializeMcpClientRegistry = initializeMcpClientRegistry;
19
+ exports.getMcpClientManager = getMcpClientManager;
20
+ exports.isMcpClientInitialized = isMcpClientInitialized;
21
+ exports.resetMcpClientRegistry = resetMcpClientRegistry;
22
+ /**
23
+ * Global MCP client manager instance (set once at startup)
24
+ */
25
+ let mcpClientManager = null;
26
+ /**
27
+ * Initialize the MCP client registry with a McpClientManager instance.
28
+ * Must be called once at startup after MCP servers are discovered.
29
+ */
30
+ function initializeMcpClientRegistry(manager) {
31
+ mcpClientManager = manager;
32
+ }
33
+ /**
34
+ * Get the McpClientManager instance.
35
+ * Returns null if not initialized.
36
+ */
37
+ function getMcpClientManager() {
38
+ return mcpClientManager;
39
+ }
40
+ /**
41
+ * Check if the MCP client registry is initialized.
42
+ */
43
+ function isMcpClientInitialized() {
44
+ return mcpClientManager !== null;
45
+ }
46
+ /**
47
+ * Reset the MCP client registry (for testing only).
48
+ * @internal
49
+ */
50
+ function resetMcpClientRegistry() {
51
+ mcpClientManager = null;
52
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * MCP Client Types for dot-ai MCP Server Integration
3
+ *
4
+ * Defines the interface contract for connecting to external MCP servers.
5
+ * MCP servers provide additional tools (e.g., Prometheus metrics, tracing)
6
+ * that augment dot-ai's built-in kubectl/helm tools.
7
+ *
8
+ * PRD #358: MCP Server Integration
9
+ */
10
+ /**
11
+ * Valid dot-ai operations that MCP servers can attach to
12
+ */
13
+ export type McpAttachableOperation = 'remediate' | 'operate' | 'query';
14
+ /**
15
+ * Configuration for an MCP server connection.
16
+ * Loaded from /etc/dot-ai-mcp/mcp-servers.json (mounted via Helm ConfigMap).
17
+ */
18
+ export interface McpServerConfig {
19
+ /** Unique server name (e.g., "prometheus", "jaeger") */
20
+ name: string;
21
+ /** MCP server HTTP endpoint URL (e.g., "http://prometheus-mcp.monitoring.svc:3000") */
22
+ endpoint: string;
23
+ /** Which dot-ai operations this server's tools should be available to */
24
+ attachTo: McpAttachableOperation[];
25
+ /** Optional timeout in milliseconds for MCP requests (default: 30000) */
26
+ timeout?: number;
27
+ }
28
+ /**
29
+ * Tool definition discovered from an MCP server via client.listTools()
30
+ */
31
+ export interface McpToolDefinition {
32
+ /** Original tool name from MCP server */
33
+ name: string;
34
+ /** Tool description */
35
+ description?: string;
36
+ /** JSON Schema for tool input */
37
+ inputSchema: {
38
+ type: string;
39
+ properties?: Record<string, unknown>;
40
+ required?: string[];
41
+ };
42
+ }
43
+ /**
44
+ * MCP server metadata after successful discovery
45
+ */
46
+ export interface DiscoveredMcpServer {
47
+ /** Server name from config */
48
+ name: string;
49
+ /** Server endpoint URL */
50
+ endpoint: string;
51
+ /** Which operations this server is attached to */
52
+ attachTo: McpAttachableOperation[];
53
+ /** Server version from MCP protocol (if available) */
54
+ version?: string;
55
+ /** Tools provided by this server */
56
+ tools: McpToolDefinition[];
57
+ /** Discovery timestamp */
58
+ discoveredAt: Date;
59
+ }
60
+ /**
61
+ * Stats about MCP server connections
62
+ */
63
+ export interface McpServerStats {
64
+ /** Number of connected servers */
65
+ serverCount: number;
66
+ /** Total number of discovered tools across all servers */
67
+ toolCount: number;
68
+ /** Names of connected servers */
69
+ servers: string[];
70
+ }
71
+ /**
72
+ * Error thrown when MCP server discovery fails
73
+ */
74
+ export declare class McpDiscoveryError extends Error {
75
+ readonly failedServers: Array<{
76
+ name: string;
77
+ error: string;
78
+ }>;
79
+ constructor(message: string, failedServers: Array<{
80
+ name: string;
81
+ error: string;
82
+ }>);
83
+ }
84
+ //# sourceMappingURL=mcp-client-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client-types.d.ts","sourceRoot":"","sources":["../../src/core/mcp-client-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,0BAA0B;IAC1B,YAAY,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,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"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Client Types for dot-ai MCP Server Integration
4
+ *
5
+ * Defines the interface contract for connecting to external MCP servers.
6
+ * MCP servers provide additional tools (e.g., Prometheus metrics, tracing)
7
+ * that augment dot-ai's built-in kubectl/helm tools.
8
+ *
9
+ * PRD #358: MCP Server Integration
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.McpDiscoveryError = void 0;
13
+ /**
14
+ * Error thrown when MCP server discovery fails
15
+ */
16
+ class McpDiscoveryError extends Error {
17
+ failedServers;
18
+ constructor(message, failedServers) {
19
+ super(message);
20
+ this.failedServers = failedServers;
21
+ this.name = 'McpDiscoveryError';
22
+ }
23
+ }
24
+ exports.McpDiscoveryError = McpDiscoveryError;
@@ -12,6 +12,7 @@ export declare const CURRENT_MODELS: {
12
12
  readonly google: "gemini-3.1-pro-preview";
13
13
  readonly google_flash: "gemini-3-flash-preview";
14
14
  readonly kimi: "kimi-k2.5";
15
+ readonly alibaba: "qwen3.5-plus";
15
16
  readonly xai: "grok-4";
16
17
  readonly host: "host";
17
18
  readonly openrouter: "anthropic/claude-haiku-4.5";
@@ -1 +1 @@
1
- {"version":3,"file":"model-config.d.ts","sourceRoot":"","sources":["../../src/core/model-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;CAajB,CAAC;AAEX;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,OAAO,cAAc,GAAG,MAAM,CAE7E"}
1
+ {"version":3,"file":"model-config.d.ts","sourceRoot":"","sources":["../../src/core/model-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;CAcjB,CAAC;AAEX;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,OAAO,cAAc,GAAG,MAAM,CAE7E"}
@@ -16,6 +16,7 @@ exports.CURRENT_MODELS = {
16
16
  google: 'gemini-3.1-pro-preview',
17
17
  google_flash: 'gemini-3-flash-preview', // PRD #294: Gemini 3 Flash - faster/cheaper variant with same 1M context
18
18
  kimi: 'kimi-k2.5', // PRD #353: Moonshot AI Kimi K2.5 - single model with thinking by default, 256K context
19
+ alibaba: 'qwen3.5-plus', // PRD #382: Alibaba Qwen 3.5 Plus - 262K context, 201 languages, MoE architecture
19
20
  xai: 'grok-4',
20
21
  host: 'host', // Delegates generation to the client via MCP Sampling
21
22
  openrouter: 'anthropic/claude-haiku-4.5', // PRD #194: OpenRouter default model (overridden by AI_MODEL env var)
@@ -1 +1 @@
1
- {"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AA4DlC,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,aAAa,CAAiB;gBAE1B,MAAM,EAAE,gBAAgB;IAWpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,eAAe;IAwFvB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAItB,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAyBnB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAkB,EAC7B,iBAAiB,CAAC,EAAE;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,UAAU,CAAC;IAsJtB;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA6b/D"}
1
+ {"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AA4DlC,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,aAAa,CAAiB;gBAE1B,MAAM,EAAE,gBAAgB;IAWpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,eAAe;IA4FvB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAItB,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAyBnB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAkB,EAC7B,iBAAiB,CAAC,EAAE;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,UAAU,CAAC;IAsJtB;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA6b/D"}
@@ -13,6 +13,7 @@ const openai_compatible_1 = require("@ai-sdk/openai-compatible");
13
13
  const google_1 = require("@ai-sdk/google");
14
14
  const anthropic_1 = require("@ai-sdk/anthropic");
15
15
  const xai_1 = require("@ai-sdk/xai");
16
+ const alibaba_1 = require("@ai-sdk/alibaba");
16
17
  const amazon_bedrock_1 = require("@ai-sdk/amazon-bedrock");
17
18
  const ai_sdk_provider_1 = require("@openrouter/ai-sdk-provider");
18
19
  const constants_1 = require("../constants");
@@ -75,6 +76,10 @@ class VercelProvider {
75
76
  case 'xai':
76
77
  provider = (0, xai_1.createXai)({ apiKey: this.apiKey });
77
78
  break;
79
+ case 'alibaba':
80
+ // PRD #382: Alibaba Qwen 3.5 Plus - uses @ai-sdk/alibaba dedicated SDK
81
+ provider = (0, alibaba_1.createAlibaba)({ apiKey: this.apiKey });
82
+ break;
78
83
  case 'kimi':
79
84
  // PRD #353: Moonshot AI Kimi K2.5 - uses @ai-sdk/openai-compatible for proper
80
85
  // reasoning_content preservation in multi-turn tool calling
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAwEtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAcvD,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,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAmBD,qBAAa,SAAS;IACpB,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,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAM;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IA6BjD;;;OAGG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAQ7C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA2CvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkKnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;;OAIG;YACW,mBAAmB;IA6CjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAed,kBAAkB;YAuQlB,gBAAgB;IAexB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3B,OAAO,IAAI,OAAO;CAGnB"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AA8EtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAcvD,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,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAmBD,qBAAa,SAAS;IACpB,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,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAM;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IA6BjD;;;OAGG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAQ7C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA2CvB;;OAEG;IACH,OAAO,CAAC,WAAW;IA8KnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;;OAIG;YACW,mBAAmB;IA6CjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAed,kBAAkB;YAuQlB,gBAAgB;IAexB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3B,OAAO,IAAI,OAAO;CAGnB"}
@@ -24,6 +24,7 @@ const operate_1 = require("../tools/operate");
24
24
  const project_setup_1 = require("../tools/project-setup");
25
25
  const query_1 = require("../tools/query");
26
26
  const manage_knowledge_1 = require("../tools/manage-knowledge");
27
+ const impact_analysis_1 = require("../tools/impact-analysis");
27
28
  const prompts_1 = require("../tools/prompts");
28
29
  const rest_registry_1 = require("./rest-registry");
29
30
  const rest_api_1 = require("./rest-api");
@@ -264,6 +265,18 @@ class MCPServer {
264
265
  category: 'Knowledge',
265
266
  tags: ['knowledge', 'documents', 'ingest', 'semantic', 'search'],
266
267
  },
268
+ {
269
+ name: impact_analysis_1.IMPACT_ANALYSIS_TOOL_NAME,
270
+ description: impact_analysis_1.IMPACT_ANALYSIS_TOOL_DESCRIPTION,
271
+ schema: impact_analysis_1.IMPACT_ANALYSIS_TOOL_INPUT_SCHEMA,
272
+ handler: async (args) => {
273
+ const requestId = this.generateRequestId();
274
+ this.logger.info(`Processing ${impact_analysis_1.IMPACT_ANALYSIS_TOOL_NAME} tool request`, { requestId });
275
+ return await (0, impact_analysis_1.handleImpactAnalysisTool)(args, this.pluginManager);
276
+ },
277
+ category: 'Intelligence',
278
+ tags: ['impact', 'dependency', 'blast-radius', 'analysis', 'safety'],
279
+ },
267
280
  ];
268
281
  }
269
282
  /**