@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.
- package/dist/core/ai-provider-factory.d.ts.map +1 -1
- package/dist/core/ai-provider-factory.js +1 -0
- package/dist/core/error-handling.js +1 -1
- package/dist/core/git-utils.d.ts +5 -0
- package/dist/core/git-utils.d.ts.map +1 -1
- package/dist/core/git-utils.js +16 -0
- package/dist/core/internal-tools.d.ts +35 -0
- package/dist/core/internal-tools.d.ts.map +1 -0
- package/dist/core/internal-tools.js +286 -0
- package/dist/core/mcp-client-manager.d.ts +88 -0
- package/dist/core/mcp-client-manager.d.ts.map +1 -0
- package/dist/core/mcp-client-manager.js +362 -0
- package/dist/core/mcp-client-registry.d.ts +36 -0
- package/dist/core/mcp-client-registry.d.ts.map +1 -0
- package/dist/core/mcp-client-registry.js +52 -0
- package/dist/core/mcp-client-types.d.ts +84 -0
- package/dist/core/mcp-client-types.d.ts.map +1 -0
- package/dist/core/mcp-client-types.js +24 -0
- package/dist/core/model-config.d.ts +1 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -0
- package/dist/core/providers/vercel-provider.d.ts.map +1 -1
- package/dist/core/providers/vercel-provider.js +5 -0
- package/dist/interfaces/mcp.d.ts.map +1 -1
- package/dist/interfaces/mcp.js +13 -0
- package/dist/mcp/server.js +26 -1
- package/dist/tools/generate-manifests.d.ts.map +1 -1
- package/dist/tools/generate-manifests.js +2 -1
- package/dist/tools/impact-analysis.d.ts +51 -0
- package/dist/tools/impact-analysis.d.ts.map +1 -0
- package/dist/tools/impact-analysis.js +204 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -1
- package/dist/tools/operate-analysis.d.ts +1 -1
- package/dist/tools/operate-analysis.d.ts.map +1 -1
- package/dist/tools/operate-analysis.js +17 -6
- package/dist/tools/operate.d.ts +1 -1
- package/dist/tools/operate.d.ts.map +1 -1
- package/dist/tools/operate.js +1 -1
- package/dist/tools/organizational-data.d.ts +1 -1
- package/dist/tools/push-to-git.d.ts.map +1 -1
- package/dist/tools/push-to-git.js +1 -11
- package/dist/tools/query.d.ts +1 -1
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +18 -8
- package/dist/tools/remediate.d.ts +9 -0
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +45 -10
- package/dist/tools/version.d.ts +12 -0
- package/dist/tools/version.d.ts.map +1 -1
- package/dist/tools/version.js +16 -1
- package/package.json +3 -1
- package/prompts/impact-analysis-system.md +32 -0
- package/prompts/operate-system.md +3 -3
- 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
|
|
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;
|
|
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;
|
|
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"}
|
package/dist/interfaces/mcp.js
CHANGED
|
@@ -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
|
/**
|