@vfarcic/dot-ai 0.4.9 → 0.5.1
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/.claude/commands/context-load.md +11 -0
- package/.claude/commands/context-save.md +16 -0
- package/.claude/commands/prd-done.md +115 -0
- package/.claude/commands/prd-get.md +25 -0
- package/.claude/commands/prd-start.md +87 -0
- package/.claude/commands/task-done.md +77 -0
- package/.claude/commands/tests-reminder.md +32 -0
- package/.claude/settings.local.json +20 -0
- package/.eslintrc.json +25 -0
- package/.github/workflows/ci.yml +170 -0
- package/.prettierrc.json +10 -0
- package/.teller.yml +8 -0
- package/CLAUDE.md +162 -0
- package/assets/images/logo.png +0 -0
- package/bin/dot-ai.ts +47 -0
- package/destroy.sh +45 -0
- package/devbox.json +13 -0
- package/devbox.lock +225 -0
- package/docs/API.md +449 -0
- package/docs/CONTEXT.md +49 -0
- package/docs/DEVELOPMENT.md +203 -0
- package/docs/NEXT_STEPS.md +97 -0
- package/docs/STAGE_BASED_API.md +97 -0
- package/docs/cli-guide.md +798 -0
- package/docs/design.md +750 -0
- package/docs/discovery-engine.md +515 -0
- package/docs/error-handling.md +429 -0
- package/docs/function-registration.md +157 -0
- package/docs/mcp-guide.md +416 -0
- package/package.json +2 -123
- package/renovate.json +51 -0
- package/setup.sh +111 -0
- package/{dist/cli.js → src/cli.ts} +26 -19
- package/src/core/claude.ts +280 -0
- package/src/core/deploy-operation.ts +127 -0
- package/src/core/discovery.ts +900 -0
- package/src/core/error-handling.ts +562 -0
- package/src/core/index.ts +143 -0
- package/src/core/kubernetes-utils.ts +218 -0
- package/src/core/memory.ts +148 -0
- package/src/core/schema.ts +830 -0
- package/src/core/session-utils.ts +97 -0
- package/src/core/workflow.ts +234 -0
- package/src/index.ts +18 -0
- package/src/interfaces/cli.ts +872 -0
- package/src/interfaces/mcp.ts +183 -0
- package/src/mcp/server.ts +131 -0
- package/src/tools/answer-question.ts +807 -0
- package/src/tools/choose-solution.ts +169 -0
- package/src/tools/deploy-manifests.ts +94 -0
- package/src/tools/generate-manifests.ts +502 -0
- package/src/tools/index.ts +41 -0
- package/src/tools/recommend.ts +370 -0
- package/tests/__mocks__/@kubernetes/client-node.ts +106 -0
- package/tests/build-system.test.ts +345 -0
- package/tests/configuration.test.ts +226 -0
- package/tests/core/deploy-operation.test.ts +38 -0
- package/tests/core/discovery.test.ts +1648 -0
- package/tests/core/error-handling.test.ts +632 -0
- package/tests/core/schema.test.ts +1658 -0
- package/tests/core/session-utils.test.ts +245 -0
- package/tests/core.test.ts +439 -0
- package/tests/fixtures/configmap-no-labels.yaml +8 -0
- package/tests/fixtures/crossplane-app-configuration.yaml +6 -0
- package/tests/fixtures/crossplane-providers.yaml +45 -0
- package/tests/fixtures/crossplane-rbac.yaml +48 -0
- package/tests/fixtures/invalid-configmap.yaml +8 -0
- package/tests/fixtures/invalid-deployment.yaml +17 -0
- package/tests/fixtures/test-deployment.yaml +28 -0
- package/tests/fixtures/valid-configmap.yaml +15 -0
- package/tests/infrastructure.test.ts +426 -0
- package/tests/interfaces/cli.test.ts +1036 -0
- package/tests/interfaces/mcp.test.ts +139 -0
- package/tests/kubernetes-utils.test.ts +200 -0
- package/tests/mcp/server.test.ts +126 -0
- package/tests/setup.ts +31 -0
- package/tests/tools/answer-question.test.ts +367 -0
- package/tests/tools/choose-solution.test.ts +481 -0
- package/tests/tools/deploy-manifests.test.ts +185 -0
- package/tests/tools/generate-manifests.test.ts +441 -0
- package/tests/tools/index.test.ts +111 -0
- package/tests/tools/recommend.test.ts +180 -0
- package/tsconfig.json +34 -0
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/core/claude.d.ts +0 -42
- package/dist/core/claude.d.ts.map +0 -1
- package/dist/core/claude.js +0 -229
- package/dist/core/deploy-operation.d.ts +0 -38
- package/dist/core/deploy-operation.d.ts.map +0 -1
- package/dist/core/deploy-operation.js +0 -101
- package/dist/core/discovery.d.ts +0 -162
- package/dist/core/discovery.d.ts.map +0 -1
- package/dist/core/discovery.js +0 -758
- package/dist/core/error-handling.d.ts +0 -167
- package/dist/core/error-handling.d.ts.map +0 -1
- package/dist/core/error-handling.js +0 -399
- package/dist/core/index.d.ts +0 -42
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -123
- package/dist/core/kubernetes-utils.d.ts +0 -38
- package/dist/core/kubernetes-utils.d.ts.map +0 -1
- package/dist/core/kubernetes-utils.js +0 -177
- package/dist/core/memory.d.ts +0 -45
- package/dist/core/memory.d.ts.map +0 -1
- package/dist/core/memory.js +0 -113
- package/dist/core/schema.d.ts +0 -187
- package/dist/core/schema.d.ts.map +0 -1
- package/dist/core/schema.js +0 -655
- package/dist/core/session-utils.d.ts +0 -29
- package/dist/core/session-utils.d.ts.map +0 -1
- package/dist/core/session-utils.js +0 -121
- package/dist/core/workflow.d.ts +0 -70
- package/dist/core/workflow.d.ts.map +0 -1
- package/dist/core/workflow.js +0 -161
- package/dist/index.d.ts +0 -15
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -32
- package/dist/interfaces/cli.d.ts +0 -74
- package/dist/interfaces/cli.d.ts.map +0 -1
- package/dist/interfaces/cli.js +0 -769
- package/dist/interfaces/mcp.d.ts +0 -30
- package/dist/interfaces/mcp.d.ts.map +0 -1
- package/dist/interfaces/mcp.js +0 -105
- package/dist/mcp/server.d.ts +0 -9
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -151
- package/dist/tools/answer-question.d.ts +0 -27
- package/dist/tools/answer-question.d.ts.map +0 -1
- package/dist/tools/answer-question.js +0 -696
- package/dist/tools/choose-solution.d.ts +0 -23
- package/dist/tools/choose-solution.d.ts.map +0 -1
- package/dist/tools/choose-solution.js +0 -171
- package/dist/tools/deploy-manifests.d.ts +0 -25
- package/dist/tools/deploy-manifests.d.ts.map +0 -1
- package/dist/tools/deploy-manifests.js +0 -74
- package/dist/tools/generate-manifests.d.ts +0 -23
- package/dist/tools/generate-manifests.d.ts.map +0 -1
- package/dist/tools/generate-manifests.js +0 -424
- package/dist/tools/index.d.ts +0 -11
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -34
- package/dist/tools/recommend.d.ts +0 -23
- package/dist/tools/recommend.d.ts.map +0 -1
- package/dist/tools/recommend.js +0 -332
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# Error Handling Patterns and Best Practices
|
|
2
|
+
|
|
3
|
+
This document outlines the comprehensive error handling system implemented in the DevOps AI Toolkit MCP server.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The error handling system provides:
|
|
8
|
+
- **Centralized Error Management**: Consistent error creation, categorization, and processing
|
|
9
|
+
- **Structured Logging**: Comprehensive logging with configurable levels and component-based filtering
|
|
10
|
+
- **Context Preservation**: Rich error context including operation details, stack traces, and retry information
|
|
11
|
+
- **MCP Protocol Integration**: Seamless conversion between internal errors and MCP protocol errors
|
|
12
|
+
- **Retry Logic**: Intelligent retry mechanisms with configurable parameters
|
|
13
|
+
|
|
14
|
+
## Core Components
|
|
15
|
+
|
|
16
|
+
### 1. Error Categories (`ErrorCategory`)
|
|
17
|
+
|
|
18
|
+
Errors are systematically classified into categories for better debugging and handling:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
enum ErrorCategory {
|
|
22
|
+
// Infrastructure errors
|
|
23
|
+
KUBERNETES = "kubernetes",
|
|
24
|
+
NETWORK = "network",
|
|
25
|
+
AUTHENTICATION = "authentication",
|
|
26
|
+
AUTHORIZATION = "authorization",
|
|
27
|
+
|
|
28
|
+
// Application errors
|
|
29
|
+
VALIDATION = "validation",
|
|
30
|
+
CONFIGURATION = "configuration",
|
|
31
|
+
OPERATION = "operation",
|
|
32
|
+
|
|
33
|
+
// External service errors
|
|
34
|
+
AI_SERVICE = "ai_service",
|
|
35
|
+
STORAGE = "storage",
|
|
36
|
+
|
|
37
|
+
// Protocol errors
|
|
38
|
+
MCP_PROTOCOL = "mcp_protocol",
|
|
39
|
+
CLI_INTERFACE = "cli_interface",
|
|
40
|
+
|
|
41
|
+
// System errors
|
|
42
|
+
INTERNAL = "internal",
|
|
43
|
+
UNKNOWN = "unknown"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Error Severity Levels (`ErrorSeverity`)
|
|
48
|
+
|
|
49
|
+
Errors are assigned severity levels to indicate impact and urgency:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
enum ErrorSeverity {
|
|
53
|
+
LOW = "low", // Minor issues, logging/monitoring
|
|
54
|
+
MEDIUM = "medium", // Functional impact, user-facing errors
|
|
55
|
+
HIGH = "high", // Service degradation, auth failures
|
|
56
|
+
CRITICAL = "critical" // System-threatening, immediate action required
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. AppError Interface
|
|
61
|
+
|
|
62
|
+
All application errors implement the `AppError` interface:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
interface AppError {
|
|
66
|
+
id: string; // Unique error identifier
|
|
67
|
+
code: string; // Generated error code
|
|
68
|
+
category: ErrorCategory; // Error classification
|
|
69
|
+
severity: ErrorSeverity; // Impact level
|
|
70
|
+
message: string; // Technical error message
|
|
71
|
+
userMessage: string; // User-friendly message
|
|
72
|
+
technicalDetails?: string; // Additional technical info
|
|
73
|
+
context: ErrorContext; // Rich contextual information
|
|
74
|
+
timestamp: Date; // When the error occurred
|
|
75
|
+
suggestedActions: string[]; // Recommended remediation steps
|
|
76
|
+
isRetryable: boolean; // Whether operation can be retried
|
|
77
|
+
cause?: Error; // Original causing error
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4. Error Context (`ErrorContext`)
|
|
82
|
+
|
|
83
|
+
Rich context is captured for each error:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface ErrorContext {
|
|
87
|
+
operation: string; // What operation was being performed
|
|
88
|
+
component: string; // Which component generated the error
|
|
89
|
+
requestId?: string; // Request tracking ID
|
|
90
|
+
userId?: string; // Associated user
|
|
91
|
+
sessionId?: string; // Session identifier
|
|
92
|
+
timestamp: Date; // Context timestamp
|
|
93
|
+
version: string; // Application version
|
|
94
|
+
originalError?: Error; // Source error object
|
|
95
|
+
stackTrace?: string; // Full stack trace
|
|
96
|
+
isRetryable: boolean; // Retry eligibility
|
|
97
|
+
retryCount: number; // Current retry attempt
|
|
98
|
+
input?: any; // Input that caused the error
|
|
99
|
+
suggestedActions?: string[]; // Context-specific actions
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Error Handler Class
|
|
104
|
+
|
|
105
|
+
The `ErrorHandler` class provides centralized error management:
|
|
106
|
+
|
|
107
|
+
### Core Methods
|
|
108
|
+
|
|
109
|
+
#### `createError(category, severity, message, context, originalError?): AppError`
|
|
110
|
+
Creates a comprehensive AppError with automatic context enhancement and logging.
|
|
111
|
+
|
|
112
|
+
#### `toMcpError(appError): McpError`
|
|
113
|
+
Converts AppError to MCP protocol-compliant error format.
|
|
114
|
+
|
|
115
|
+
#### `handleError(error, context, options?): AppError | McpError`
|
|
116
|
+
Processes any error type with automatic categorization and optional MCP conversion.
|
|
117
|
+
|
|
118
|
+
#### `withErrorHandling<T>(operation, context, options?): Promise<T>`
|
|
119
|
+
Wraps operations with error handling and retry logic.
|
|
120
|
+
|
|
121
|
+
### Usage Examples
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Create a validation error
|
|
125
|
+
const error = ErrorHandler.createError(
|
|
126
|
+
ErrorCategory.VALIDATION,
|
|
127
|
+
ErrorSeverity.MEDIUM,
|
|
128
|
+
"Invalid input parameters",
|
|
129
|
+
{
|
|
130
|
+
operation: "input_validation",
|
|
131
|
+
component: "MCPServer.handleRecommend",
|
|
132
|
+
requestId: "req_123",
|
|
133
|
+
input: userInput
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// Wrap operation with error handling
|
|
138
|
+
const result = await ErrorHandler.withErrorHandling(
|
|
139
|
+
async () => {
|
|
140
|
+
return await riskyOperation();
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
operation: "recommend_tools",
|
|
144
|
+
component: "MCPServer",
|
|
145
|
+
requestId: requestId
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
convertToMcp: true,
|
|
149
|
+
retryCount: 2
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Structured Logging
|
|
155
|
+
|
|
156
|
+
### ConsoleLogger Class
|
|
157
|
+
|
|
158
|
+
The `ConsoleLogger` provides structured logging with:
|
|
159
|
+
- **Log Levels**: DEBUG, INFO, WARN, ERROR, FATAL
|
|
160
|
+
- **Component-based Filtering**: Filter logs by component
|
|
161
|
+
- **Structured Output**: JSON-formatted log data
|
|
162
|
+
- **Error Serialization**: Proper serialization of AppError and native Error objects
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const logger = new ConsoleLogger('MCPServer', LogLevel.INFO);
|
|
166
|
+
|
|
167
|
+
logger.info('Processing request', { requestId, operation });
|
|
168
|
+
logger.error('Operation failed', error, { context: 'additional data' });
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Log Format
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
[2025-06-30T15:20:44.553Z] ERROR [MCPServer] Operation failed {
|
|
175
|
+
"error": {
|
|
176
|
+
"id": "err_1751296844532_3e1vhzmsm",
|
|
177
|
+
"code": "VALIDATION_M_844553_tr5",
|
|
178
|
+
"category": "validation",
|
|
179
|
+
"severity": "medium",
|
|
180
|
+
"message": "Invalid input parameters"
|
|
181
|
+
},
|
|
182
|
+
"requestId": "req_123",
|
|
183
|
+
"operation": "recommend_tools"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## MCP Integration
|
|
188
|
+
|
|
189
|
+
### Error Code Mapping
|
|
190
|
+
|
|
191
|
+
AppError categories are mapped to MCP ErrorCodes:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const mcpErrorMapping = {
|
|
195
|
+
VALIDATION: ErrorCode.InvalidParams,
|
|
196
|
+
AUTHENTICATION: ErrorCode.InvalidParams,
|
|
197
|
+
AUTHORIZATION: ErrorCode.InvalidParams,
|
|
198
|
+
MCP_PROTOCOL: ErrorCode.MethodNotFound,
|
|
199
|
+
OPERATION: ErrorCode.InvalidRequest,
|
|
200
|
+
CLI_INTERFACE: ErrorCode.InvalidRequest,
|
|
201
|
+
// Default: ErrorCode.InternalError
|
|
202
|
+
};
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### MCP Tool Integration
|
|
206
|
+
|
|
207
|
+
MCP tools use error handling patterns:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
private async handleRecommend(args: any, requestId: string) {
|
|
211
|
+
return await ErrorHandler.withErrorHandling(async () => {
|
|
212
|
+
// Validate input
|
|
213
|
+
SchemaValidator.validateToolInput('recommend', args, schema);
|
|
214
|
+
|
|
215
|
+
// Process request
|
|
216
|
+
const result = await this.processRecommendation(args);
|
|
217
|
+
|
|
218
|
+
// Validate output
|
|
219
|
+
SchemaValidator.validateToolOutput('recommend', result, outputSchema);
|
|
220
|
+
|
|
221
|
+
return result;
|
|
222
|
+
}, {
|
|
223
|
+
operation: 'recommend_tool',
|
|
224
|
+
component: 'MCPServer',
|
|
225
|
+
requestId
|
|
226
|
+
}, {
|
|
227
|
+
convertToMcp: true,
|
|
228
|
+
retryCount: 1
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Retry Logic
|
|
234
|
+
|
|
235
|
+
### Automatic Retry Configuration
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const options = {
|
|
239
|
+
retryCount: 3, // Maximum retry attempts
|
|
240
|
+
convertToMcp: true, // Convert final error to MCP format
|
|
241
|
+
logLevel: LogLevel.WARN // Log level for retry attempts
|
|
242
|
+
};
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Retry Decision Logic
|
|
246
|
+
|
|
247
|
+
- Errors are retryable by default unless explicitly marked as non-retryable
|
|
248
|
+
- Authentication and validation errors are typically non-retryable
|
|
249
|
+
- Network and AI service errors are usually retryable
|
|
250
|
+
- Context-specific retry flags override defaults
|
|
251
|
+
|
|
252
|
+
## Best Practices
|
|
253
|
+
|
|
254
|
+
### 1. Error Creation
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// Good: Comprehensive error with context
|
|
258
|
+
const error = ErrorHandler.createError(
|
|
259
|
+
ErrorCategory.AI_SERVICE,
|
|
260
|
+
ErrorSeverity.HIGH,
|
|
261
|
+
"API key validation failed",
|
|
262
|
+
{
|
|
263
|
+
operation: "api_key_check",
|
|
264
|
+
component: "MCPServer.handleEnhanceSolution",
|
|
265
|
+
requestId,
|
|
266
|
+
suggestedActions: [
|
|
267
|
+
"Set ANTHROPIC_API_KEY environment variable",
|
|
268
|
+
"Verify the API key is valid and active",
|
|
269
|
+
"Check that the API key has sufficient credits"
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
// Bad: Generic error without context
|
|
275
|
+
throw new Error("API key failed");
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### 2. Operation Wrapping
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// Good: Wrapped with error handling
|
|
282
|
+
return await ErrorHandler.withErrorHandling(
|
|
283
|
+
async () => await operation(),
|
|
284
|
+
{ operation: 'specific_task', component: 'ComponentName', requestId },
|
|
285
|
+
{ convertToMcp: true, retryCount: 2 }
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
// Bad: Raw operation without handling
|
|
289
|
+
return await operation();
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 3. Error Propagation
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// Good: Handle and re-throw with context
|
|
296
|
+
try {
|
|
297
|
+
await riskyOperation();
|
|
298
|
+
} catch (error) {
|
|
299
|
+
const appError = ErrorHandler.handleError(error, context);
|
|
300
|
+
throw appError;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Bad: Silent failure or generic re-throw
|
|
304
|
+
try {
|
|
305
|
+
await riskyOperation();
|
|
306
|
+
} catch (error) {
|
|
307
|
+
console.log('Something went wrong');
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 4. Logging Levels
|
|
313
|
+
|
|
314
|
+
- **DEBUG**: Detailed trace information for debugging
|
|
315
|
+
- **INFO**: General operational information
|
|
316
|
+
- **WARN**: Warning conditions, retry attempts
|
|
317
|
+
- **ERROR**: Error conditions requiring attention
|
|
318
|
+
- **FATAL**: Critical errors causing system failure
|
|
319
|
+
|
|
320
|
+
### 5. User-Friendly Messages
|
|
321
|
+
|
|
322
|
+
Always provide clear, actionable user messages:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
getUserFriendlyMessage(ErrorCategory.KUBERNETES) {
|
|
326
|
+
return 'Unable to connect to Kubernetes cluster. Please check your kubeconfig and cluster connectivity.';
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Error Code Generation
|
|
331
|
+
|
|
332
|
+
Error codes follow the pattern: `{CATEGORY}_{SEVERITY}_{TIMESTAMP}_{RANDOM}`
|
|
333
|
+
|
|
334
|
+
Example: `VALIDATION_M_844553_tr5`
|
|
335
|
+
- VALIDATION: Error category
|
|
336
|
+
- M: Medium severity (L/M/H/C)
|
|
337
|
+
- 844553: Last 6 digits of timestamp
|
|
338
|
+
- tr5: 3-character random suffix
|
|
339
|
+
|
|
340
|
+
## Testing Error Handling
|
|
341
|
+
|
|
342
|
+
### Unit Tests
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
test('should create comprehensive AppError', () => {
|
|
346
|
+
const error = ErrorHandler.createError(
|
|
347
|
+
ErrorCategory.VALIDATION,
|
|
348
|
+
ErrorSeverity.MEDIUM,
|
|
349
|
+
'Test error',
|
|
350
|
+
{ operation: 'test', component: 'Test' }
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
expect(error.category).toBe(ErrorCategory.VALIDATION);
|
|
354
|
+
expect(error.severity).toBe(ErrorSeverity.MEDIUM);
|
|
355
|
+
expect(error.id).toBeDefined();
|
|
356
|
+
expect(error.code).toMatch(/VALIDATION_M_\d+_\w+/);
|
|
357
|
+
});
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Integration Tests
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
test('should handle MCP tool errors correctly', async () => {
|
|
364
|
+
const result = await mcpServer.handleRecommend({}, 'test-request');
|
|
365
|
+
|
|
366
|
+
expect(result.error).toBeInstanceOf(McpError);
|
|
367
|
+
expect(result.error.code).toBe(ErrorCode.InvalidParams);
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Monitoring and Observability
|
|
372
|
+
|
|
373
|
+
### Error Metrics
|
|
374
|
+
|
|
375
|
+
Track key error metrics:
|
|
376
|
+
- Error rate by category and severity
|
|
377
|
+
- Retry success/failure rates
|
|
378
|
+
- Component-specific error patterns
|
|
379
|
+
- User-impacting error frequency
|
|
380
|
+
|
|
381
|
+
### Alerting
|
|
382
|
+
|
|
383
|
+
Set up alerts for:
|
|
384
|
+
- CRITICAL severity errors (immediate)
|
|
385
|
+
- HIGH severity error rate increases
|
|
386
|
+
- Retry failure patterns
|
|
387
|
+
- Authentication/authorization failures
|
|
388
|
+
|
|
389
|
+
## Migration Guide
|
|
390
|
+
|
|
391
|
+
### Converting Existing Error Handling
|
|
392
|
+
|
|
393
|
+
1. **Replace Generic Errors**:
|
|
394
|
+
```typescript
|
|
395
|
+
// Before
|
|
396
|
+
throw new Error('Something went wrong');
|
|
397
|
+
|
|
398
|
+
// After
|
|
399
|
+
throw ErrorHandler.createError(
|
|
400
|
+
ErrorCategory.OPERATION,
|
|
401
|
+
ErrorSeverity.MEDIUM,
|
|
402
|
+
'Specific operation failed',
|
|
403
|
+
context
|
|
404
|
+
);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
2. **Add Error Wrapping**:
|
|
408
|
+
```typescript
|
|
409
|
+
// Before
|
|
410
|
+
const result = await operation();
|
|
411
|
+
|
|
412
|
+
// After
|
|
413
|
+
const result = await ErrorHandler.withErrorHandling(
|
|
414
|
+
() => operation(),
|
|
415
|
+
context,
|
|
416
|
+
options
|
|
417
|
+
);
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
3. **Enhance Logging**:
|
|
421
|
+
```typescript
|
|
422
|
+
// Before
|
|
423
|
+
console.error('Error:', error);
|
|
424
|
+
|
|
425
|
+
// After
|
|
426
|
+
logger.error('Operation failed', error, additionalContext);
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
This comprehensive error handling system ensures robust, maintainable, and observable error management throughout the DevOps AI Toolkit MCP server.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# MCP Tool Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The DevOps AI Toolkit implements a clean, direct MCP tool architecture using the official MCP SDK patterns. Tools are registered directly with the MCP server using `McpServer.tool()` method, providing type safety and simplicity.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
### Core Components
|
|
10
|
+
|
|
11
|
+
1. **Direct Tool Handlers** (`src/tools/`)
|
|
12
|
+
- Direct handler functions (e.g., `handleRecommendTool`)
|
|
13
|
+
- Tool metadata constants (e.g., `RECOMMEND_TOOL_NAME`, `RECOMMEND_TOOL_DESCRIPTION`)
|
|
14
|
+
- Zod schemas for MCP registration and validation
|
|
15
|
+
|
|
16
|
+
2. **MCP Server Integration** (`src/interfaces/mcp.ts`)
|
|
17
|
+
- Uses `McpServer.tool()` for direct tool registration
|
|
18
|
+
- No custom registry abstractions
|
|
19
|
+
- Follows official MCP SDK patterns
|
|
20
|
+
|
|
21
|
+
3. **Session Management** (`src/core/session-utils.ts`)
|
|
22
|
+
- Environment-based configuration using `DOT_AI_SESSION_DIR`
|
|
23
|
+
- Consistent session directory resolution across all tools
|
|
24
|
+
|
|
25
|
+
## Tool Structure
|
|
26
|
+
|
|
27
|
+
### Tool Module Pattern
|
|
28
|
+
|
|
29
|
+
Each tool exports:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
// Tool metadata
|
|
33
|
+
export const RECOMMEND_TOOL_NAME = 'recommend';
|
|
34
|
+
export const RECOMMEND_TOOL_DESCRIPTION = 'Deploy, create, run, or setup applications on Kubernetes with AI-powered recommendations';
|
|
35
|
+
|
|
36
|
+
// Zod schema for MCP validation
|
|
37
|
+
export const RECOMMEND_TOOL_INPUT_SCHEMA = {
|
|
38
|
+
intent: z.string().min(1).max(1000).describe('What the user wants to deploy...')
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Direct handler function
|
|
42
|
+
export async function handleRecommendTool(
|
|
43
|
+
args: { intent: string },
|
|
44
|
+
dotAI: DotAI,
|
|
45
|
+
logger: Logger,
|
|
46
|
+
requestId: string
|
|
47
|
+
): Promise<{ content: { type: 'text'; text: string }[] }> {
|
|
48
|
+
// Tool implementation
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### MCP Registration
|
|
53
|
+
|
|
54
|
+
Tools are registered directly with the MCP server:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// src/interfaces/mcp.ts
|
|
58
|
+
this.server.tool(
|
|
59
|
+
RECOMMEND_TOOL_NAME,
|
|
60
|
+
RECOMMEND_TOOL_DESCRIPTION,
|
|
61
|
+
RECOMMEND_TOOL_INPUT_SCHEMA,
|
|
62
|
+
async (args: any) => {
|
|
63
|
+
const requestId = this.generateRequestId();
|
|
64
|
+
return await handleRecommendTool(args, this.dotAI, this.logger, requestId);
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Available Tools
|
|
70
|
+
|
|
71
|
+
1. **recommend** - AI-powered deployment recommendations
|
|
72
|
+
2. **chooseSolution** - Select a solution and return configuration questions
|
|
73
|
+
3. **answerQuestion** - Process user answers and manage configuration stages
|
|
74
|
+
4. **generateManifests** - Generate Kubernetes manifests from completed solutions
|
|
75
|
+
5. **deployManifests** - Deploy manifests with readiness checking
|
|
76
|
+
|
|
77
|
+
## Configuration
|
|
78
|
+
|
|
79
|
+
### Environment Variables
|
|
80
|
+
|
|
81
|
+
- `DOT_AI_SESSION_DIR` - Directory for storing solution files
|
|
82
|
+
- `ANTHROPIC_API_KEY` - Required for AI-powered features
|
|
83
|
+
|
|
84
|
+
### CLI Parameters
|
|
85
|
+
|
|
86
|
+
- `--session-dir <path>` - Override session directory (takes precedence over env var)
|
|
87
|
+
- `--kubeconfig <path>` - Custom kubeconfig path
|
|
88
|
+
|
|
89
|
+
## Usage Patterns
|
|
90
|
+
|
|
91
|
+
### MCP Mode
|
|
92
|
+
Tools automatically use `DOT_AI_SESSION_DIR` environment variable:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
export DOT_AI_SESSION_DIR=/path/to/sessions
|
|
96
|
+
# Tools will automatically use this directory
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### CLI Mode
|
|
100
|
+
CLI sets the environment variable before calling tools:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
dot-ai recommend --intent "deploy a web app" --session-dir /custom/path
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Error Handling
|
|
107
|
+
|
|
108
|
+
All tools use the unified error handling system:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
return await ErrorHandler.withErrorHandling(
|
|
112
|
+
async () => {
|
|
113
|
+
// Tool logic
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
operation: 'tool_operation',
|
|
117
|
+
component: 'ToolName',
|
|
118
|
+
requestId,
|
|
119
|
+
input: args
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
Tests use direct handler functions:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const result = await handleRecommendTool(
|
|
130
|
+
{ intent: 'deploy web app' },
|
|
131
|
+
mockDotAI,
|
|
132
|
+
mockLogger,
|
|
133
|
+
'test-request-id'
|
|
134
|
+
);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Best Practices
|
|
138
|
+
|
|
139
|
+
1. **Type Safety**: Use TypeScript interfaces for tool arguments
|
|
140
|
+
2. **Schema Validation**: Define comprehensive Zod schemas
|
|
141
|
+
3. **Error Context**: Provide detailed error context and suggested actions
|
|
142
|
+
4. **Environment Config**: Use environment variables for session management
|
|
143
|
+
5. **Direct Handlers**: Keep tools as pure functions without registry abstractions
|
|
144
|
+
|
|
145
|
+
## Migration Benefits
|
|
146
|
+
|
|
147
|
+
The new architecture provides:
|
|
148
|
+
|
|
149
|
+
- **Simplicity**: No custom registry abstractions
|
|
150
|
+
- **Type Safety**: Direct TypeScript types, no `any` types
|
|
151
|
+
- **Official Patterns**: Uses MCP SDK best practices
|
|
152
|
+
- **Better Testing**: Tests verify actual functionality, not abstractions
|
|
153
|
+
- **Reduced Complexity**: Eliminated 400+ lines of registry code
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
*This architecture provides a clean, maintainable foundation for MCP tool development using official SDK patterns.*
|