hawkeye-mcp-server 1.0.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/CHANGELOG.md +123 -0
- package/INSTALLATION.md +734 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/SPECIFICATION.md +1073 -0
- package/USAGE.md +849 -0
- package/build/config/config.d.ts +58 -0
- package/build/config/config.js +100 -0
- package/build/config/config.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.js +138 -0
- package/build/index.js.map +1 -0
- package/build/services/auth.service.d.ts +34 -0
- package/build/services/auth.service.js +96 -0
- package/build/services/auth.service.js.map +1 -0
- package/build/services/project.service.d.ts +50 -0
- package/build/services/project.service.js +136 -0
- package/build/services/project.service.js.map +1 -0
- package/build/services/session.service.d.ts +68 -0
- package/build/services/session.service.js +357 -0
- package/build/services/session.service.js.map +1 -0
- package/build/tools/continue-investigation.d.ts +10 -0
- package/build/tools/continue-investigation.js +84 -0
- package/build/tools/continue-investigation.js.map +1 -0
- package/build/tools/get-incident-report.d.ts +10 -0
- package/build/tools/get-incident-report.js +62 -0
- package/build/tools/get-incident-report.js.map +1 -0
- package/build/tools/get-session-report.d.ts +25 -0
- package/build/tools/get-session-report.js +46 -0
- package/build/tools/get-session-report.js.map +1 -0
- package/build/tools/get-session-summary.d.ts +22 -0
- package/build/tools/get-session-summary.js +41 -0
- package/build/tools/get-session-summary.js.map +1 -0
- package/build/tools/get-status.d.ts +10 -0
- package/build/tools/get-status.js +129 -0
- package/build/tools/get-status.js.map +1 -0
- package/build/tools/index.d.ts +29 -0
- package/build/tools/index.js +349 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/inspect-session.d.ts +28 -0
- package/build/tools/inspect-session.js +51 -0
- package/build/tools/inspect-session.js.map +1 -0
- package/build/tools/investigate-alert.d.ts +10 -0
- package/build/tools/investigate-alert.js +122 -0
- package/build/tools/investigate-alert.js.map +1 -0
- package/build/tools/list-sessions.d.ts +49 -0
- package/build/tools/list-sessions.js +79 -0
- package/build/tools/list-sessions.js.map +1 -0
- package/build/types/errors.d.ts +61 -0
- package/build/types/errors.js +76 -0
- package/build/types/errors.js.map +1 -0
- package/build/types/hawkeye.d.ts +238 -0
- package/build/types/hawkeye.js +8 -0
- package/build/types/hawkeye.js.map +1 -0
- package/build/types/mcp.d.ts +125 -0
- package/build/types/mcp.js +6 -0
- package/build/types/mcp.js.map +1 -0
- package/build/utils/errors.d.ts +20 -0
- package/build/utils/errors.js +125 -0
- package/build/utils/errors.js.map +1 -0
- package/build/utils/http-client.d.ts +51 -0
- package/build/utils/http-client.js +133 -0
- package/build/utils/http-client.js.map +1 -0
- package/build/utils/logger.d.ts +35 -0
- package/build/utils/logger.js +77 -0
- package/build/utils/logger.js.map +1 -0
- package/build/utils/validation.d.ts +134 -0
- package/build/utils/validation.js +68 -0
- package/build/utils/validation.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for Hawkeye API requests and responses
|
|
3
|
+
* Based on Hawkeye API documentation and reference code
|
|
4
|
+
*/
|
|
5
|
+
export interface LoginRequest {
|
|
6
|
+
email: string;
|
|
7
|
+
password: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LoginResponse {
|
|
10
|
+
access_token: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Project {
|
|
13
|
+
uuid: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
state: string;
|
|
17
|
+
sync_state: string;
|
|
18
|
+
training_state: string;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
organization_uuid: string;
|
|
22
|
+
gendb_spec?: {
|
|
23
|
+
uuid: string;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface ListProjectsResponse {
|
|
28
|
+
specs: Project[];
|
|
29
|
+
}
|
|
30
|
+
export interface Session {
|
|
31
|
+
uuid?: string;
|
|
32
|
+
session_uuid?: string;
|
|
33
|
+
name: string;
|
|
34
|
+
created_at?: string;
|
|
35
|
+
updated_at?: string;
|
|
36
|
+
create_time?: string;
|
|
37
|
+
last_update?: string;
|
|
38
|
+
project_uuid?: string;
|
|
39
|
+
organization_uuid?: string;
|
|
40
|
+
prompt_cycle_count?: number;
|
|
41
|
+
prompt_cycle_ids?: string[];
|
|
42
|
+
incident_info?: {
|
|
43
|
+
id: string;
|
|
44
|
+
title?: string;
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
};
|
|
47
|
+
[key: string]: any;
|
|
48
|
+
}
|
|
49
|
+
export interface CreateSessionRequest {
|
|
50
|
+
filter_chain: null;
|
|
51
|
+
gendb_spec: {
|
|
52
|
+
uuid: string;
|
|
53
|
+
};
|
|
54
|
+
organization_uuid: string;
|
|
55
|
+
project_uuid: string;
|
|
56
|
+
request: {
|
|
57
|
+
request_id: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface CreateSessionResponse {
|
|
61
|
+
uuid: string;
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
}
|
|
64
|
+
export interface PaginationFilter {
|
|
65
|
+
field: string;
|
|
66
|
+
operator: string;
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
export interface PaginationOptions {
|
|
70
|
+
limit: number;
|
|
71
|
+
sort: null | string;
|
|
72
|
+
start: number;
|
|
73
|
+
filters?: PaginationFilter[];
|
|
74
|
+
}
|
|
75
|
+
export interface ListSessionsRequest {
|
|
76
|
+
request: {
|
|
77
|
+
id?: string;
|
|
78
|
+
request_id?: string;
|
|
79
|
+
};
|
|
80
|
+
project_uuid: string;
|
|
81
|
+
organization_uuid: string;
|
|
82
|
+
pagination?: PaginationOptions | {
|
|
83
|
+
filters?: Array<{
|
|
84
|
+
key: string;
|
|
85
|
+
value: string;
|
|
86
|
+
operator: string;
|
|
87
|
+
}>;
|
|
88
|
+
page_size?: number;
|
|
89
|
+
page_token?: string;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export interface ListSessionsResponse {
|
|
93
|
+
sessions: Session[];
|
|
94
|
+
next_page_token?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface InspectSessionRequest {
|
|
97
|
+
request: {
|
|
98
|
+
id: string;
|
|
99
|
+
};
|
|
100
|
+
session_uuid: string;
|
|
101
|
+
project_uuid: string;
|
|
102
|
+
organization_uuid: string;
|
|
103
|
+
}
|
|
104
|
+
export interface ChainOfThought {
|
|
105
|
+
description: string;
|
|
106
|
+
investigation?: string;
|
|
107
|
+
sources?: any[];
|
|
108
|
+
[key: string]: any;
|
|
109
|
+
}
|
|
110
|
+
export interface PromptCycle {
|
|
111
|
+
id: string;
|
|
112
|
+
status: string;
|
|
113
|
+
request: {
|
|
114
|
+
messages: Array<{
|
|
115
|
+
content: {
|
|
116
|
+
content_type: string;
|
|
117
|
+
parts: string[];
|
|
118
|
+
};
|
|
119
|
+
}>;
|
|
120
|
+
};
|
|
121
|
+
final_answer?: string;
|
|
122
|
+
chain_of_thoughts: ChainOfThought[];
|
|
123
|
+
sources: any[];
|
|
124
|
+
follow_up_suggestions?: string[];
|
|
125
|
+
[key: string]: any;
|
|
126
|
+
}
|
|
127
|
+
export interface InspectSessionResponse {
|
|
128
|
+
uuid?: string;
|
|
129
|
+
session_uuid?: string;
|
|
130
|
+
name?: string;
|
|
131
|
+
created_at?: string;
|
|
132
|
+
updated_at?: string;
|
|
133
|
+
create_time?: string;
|
|
134
|
+
last_update?: string;
|
|
135
|
+
project_uuid?: string;
|
|
136
|
+
organization_uuid?: string;
|
|
137
|
+
prompt_cycle_count?: number;
|
|
138
|
+
state?: string;
|
|
139
|
+
final_answer?: string;
|
|
140
|
+
chain_of_thoughts?: ChainOfThought[];
|
|
141
|
+
sources?: any[];
|
|
142
|
+
incident_info?: {
|
|
143
|
+
id: string;
|
|
144
|
+
[key: string]: any;
|
|
145
|
+
};
|
|
146
|
+
session_info?: {
|
|
147
|
+
session_uuid: string;
|
|
148
|
+
name: string;
|
|
149
|
+
create_time: string;
|
|
150
|
+
last_update: string;
|
|
151
|
+
};
|
|
152
|
+
prompt_cycle?: PromptCycle[];
|
|
153
|
+
[key: string]: any;
|
|
154
|
+
}
|
|
155
|
+
export interface SessionReport {
|
|
156
|
+
create_time: string;
|
|
157
|
+
prompt: string;
|
|
158
|
+
session_link: string;
|
|
159
|
+
summary: string;
|
|
160
|
+
time_saved: number;
|
|
161
|
+
}
|
|
162
|
+
export interface SessionSummary {
|
|
163
|
+
analysis_score?: {
|
|
164
|
+
accuracy: {
|
|
165
|
+
root_cause_correct: 'Yes' | 'No' | 'Partial';
|
|
166
|
+
impact_analysis_correct: 'Yes' | 'No' | 'Partial';
|
|
167
|
+
timeline_accurate: 'Yes' | 'No' | 'Partial';
|
|
168
|
+
overall_score: number;
|
|
169
|
+
};
|
|
170
|
+
completeness: {
|
|
171
|
+
data_sources: number;
|
|
172
|
+
remediation_steps: number;
|
|
173
|
+
prevention_measures: number;
|
|
174
|
+
business_impact: number;
|
|
175
|
+
overall_score: number;
|
|
176
|
+
};
|
|
177
|
+
qualitative: {
|
|
178
|
+
trust_without_review: 'Yes' | 'No' | 'Maybe';
|
|
179
|
+
missing_elements: string;
|
|
180
|
+
additional_notes: string;
|
|
181
|
+
improvement_suggestions: string;
|
|
182
|
+
};
|
|
183
|
+
scored_by: string;
|
|
184
|
+
scored_during_call: boolean;
|
|
185
|
+
call_recording_url: string | null;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export interface PriorityReport {
|
|
189
|
+
avg_investigation_time_minutes: number;
|
|
190
|
+
avg_mttr: number;
|
|
191
|
+
avg_time_saved_minutes: number;
|
|
192
|
+
investigated_incidents: number;
|
|
193
|
+
percent_grouped: number;
|
|
194
|
+
priority: string;
|
|
195
|
+
total_incidents: number;
|
|
196
|
+
}
|
|
197
|
+
export interface IncidentTypeReport {
|
|
198
|
+
incident_type: string;
|
|
199
|
+
priority_reports: PriorityReport[];
|
|
200
|
+
}
|
|
201
|
+
export interface IncidentReport {
|
|
202
|
+
avg_investigation_time_saved_minutes: number;
|
|
203
|
+
avg_mttr: number;
|
|
204
|
+
end_time: string;
|
|
205
|
+
start_time: string;
|
|
206
|
+
incident_type_reports: IncidentTypeReport[];
|
|
207
|
+
noise_reduction: number;
|
|
208
|
+
total_incidents: number;
|
|
209
|
+
total_investigation_time_saved_hours: number;
|
|
210
|
+
total_investigations: number;
|
|
211
|
+
}
|
|
212
|
+
export interface SendPromptRequest {
|
|
213
|
+
action: 'ACTION_NEXT';
|
|
214
|
+
session_uuid: string;
|
|
215
|
+
project_uuid: string;
|
|
216
|
+
messages: Array<{
|
|
217
|
+
content: {
|
|
218
|
+
content_type: 'CONTENT_TYPE_CHAT_PROMPT';
|
|
219
|
+
parts: string[];
|
|
220
|
+
};
|
|
221
|
+
}>;
|
|
222
|
+
request: {
|
|
223
|
+
request_id: string;
|
|
224
|
+
};
|
|
225
|
+
prompt_options: {
|
|
226
|
+
disable_replay: boolean;
|
|
227
|
+
source_focus_categories: string[];
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
export interface SendPromptResponse {
|
|
231
|
+
status: string;
|
|
232
|
+
[key: string]: any;
|
|
233
|
+
}
|
|
234
|
+
export interface RequestMetadata {
|
|
235
|
+
id?: string;
|
|
236
|
+
request_id?: string;
|
|
237
|
+
}
|
|
238
|
+
export declare function generateRequestId(): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for Hawkeye API requests and responses
|
|
3
|
+
* Based on Hawkeye API documentation and reference code
|
|
4
|
+
*/
|
|
5
|
+
export function generateRequestId() {
|
|
6
|
+
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=hawkeye.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hawkeye.js","sourceRoot":"","sources":["../../src/types/hawkeye.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2RH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for MCP tool inputs and outputs
|
|
3
|
+
* Based on specification in SPECIFICATION.md
|
|
4
|
+
*/
|
|
5
|
+
import { ChainOfThought } from './hawkeye.js';
|
|
6
|
+
export interface InvestigateAlertInput {
|
|
7
|
+
alert_id: string;
|
|
8
|
+
project_uuid?: string;
|
|
9
|
+
wait_for_completion?: boolean;
|
|
10
|
+
max_wait_seconds?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CreateInvestigationInput {
|
|
13
|
+
prompt: string;
|
|
14
|
+
timeframe?: string;
|
|
15
|
+
start_time?: string;
|
|
16
|
+
end_time?: string;
|
|
17
|
+
project_uuid?: string;
|
|
18
|
+
wait_for_completion?: boolean;
|
|
19
|
+
max_wait_seconds?: number;
|
|
20
|
+
stream_updates?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface GetInvestigationStatusInput {
|
|
23
|
+
session_uuid: string;
|
|
24
|
+
project_uuid?: string;
|
|
25
|
+
include_full_details?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface ContinueInvestigationInput {
|
|
28
|
+
session_uuid: string;
|
|
29
|
+
follow_up_prompt: string;
|
|
30
|
+
project_uuid?: string;
|
|
31
|
+
wait_for_completion?: boolean;
|
|
32
|
+
max_wait_seconds?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ListProjectsInput {
|
|
35
|
+
include_inactive?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ListRecentInvestigationsInput {
|
|
38
|
+
project_uuid?: string;
|
|
39
|
+
limit?: number;
|
|
40
|
+
filter_by_alert_id?: string;
|
|
41
|
+
filter_by_status?: 'completed' | 'in_progress' | 'failed';
|
|
42
|
+
}
|
|
43
|
+
export interface ConfigureDefaultsInput {
|
|
44
|
+
default_project_uuid?: string;
|
|
45
|
+
default_organization_uuid?: string;
|
|
46
|
+
default_timeframe?: string;
|
|
47
|
+
enable_streaming?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface InvestigationResults {
|
|
50
|
+
final_answer?: string;
|
|
51
|
+
chain_of_thoughts?: ChainOfThought[];
|
|
52
|
+
sources?: any[];
|
|
53
|
+
follow_up_suggestions?: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface InvestigateAlertOutput {
|
|
56
|
+
status: 'found_existing' | 'new_investigation' | 'in_progress' | 'completed';
|
|
57
|
+
session_uuid: string;
|
|
58
|
+
investigation_results?: InvestigationResults;
|
|
59
|
+
message: string;
|
|
60
|
+
}
|
|
61
|
+
export interface ParsedTimeframe {
|
|
62
|
+
start: string;
|
|
63
|
+
end: string;
|
|
64
|
+
description: string;
|
|
65
|
+
}
|
|
66
|
+
export interface CreateInvestigationOutput {
|
|
67
|
+
session_uuid: string;
|
|
68
|
+
status: 'created' | 'in_progress' | 'completed';
|
|
69
|
+
enhanced_prompt: string;
|
|
70
|
+
timeframe_parsed?: ParsedTimeframe;
|
|
71
|
+
investigation_results?: InvestigationResults;
|
|
72
|
+
}
|
|
73
|
+
export interface GetInvestigationStatusOutput {
|
|
74
|
+
session_uuid: string;
|
|
75
|
+
status: 'in_progress' | 'completed' | 'failed' | 'unknown';
|
|
76
|
+
progress_percentage?: number;
|
|
77
|
+
current_step?: string;
|
|
78
|
+
investigation_results?: InvestigationResults;
|
|
79
|
+
created_at: string;
|
|
80
|
+
updated_at: string;
|
|
81
|
+
}
|
|
82
|
+
export interface ContinueInvestigationOutput {
|
|
83
|
+
session_uuid: string;
|
|
84
|
+
status: 'created' | 'in_progress' | 'completed';
|
|
85
|
+
investigation_results?: InvestigationResults;
|
|
86
|
+
message: string;
|
|
87
|
+
}
|
|
88
|
+
export interface ProjectInfo {
|
|
89
|
+
uuid: string;
|
|
90
|
+
name: string;
|
|
91
|
+
description: string;
|
|
92
|
+
state: string;
|
|
93
|
+
sync_state: string;
|
|
94
|
+
training_state: string;
|
|
95
|
+
created_at: string;
|
|
96
|
+
updated_at: string;
|
|
97
|
+
}
|
|
98
|
+
export interface ListProjectsOutput {
|
|
99
|
+
projects: ProjectInfo[];
|
|
100
|
+
default_project?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface InvestigationSummary {
|
|
103
|
+
session_uuid: string;
|
|
104
|
+
name: string;
|
|
105
|
+
created_at: string;
|
|
106
|
+
updated_at: string;
|
|
107
|
+
status: string;
|
|
108
|
+
prompt_summary: string;
|
|
109
|
+
alert_id?: string;
|
|
110
|
+
prompt_cycle_count: number;
|
|
111
|
+
}
|
|
112
|
+
export interface ListRecentInvestigationsOutput {
|
|
113
|
+
investigations: InvestigationSummary[];
|
|
114
|
+
total_count: number;
|
|
115
|
+
}
|
|
116
|
+
export interface CurrentDefaults {
|
|
117
|
+
project_uuid?: string;
|
|
118
|
+
organization_uuid: string;
|
|
119
|
+
timeframe: string;
|
|
120
|
+
streaming_enabled: boolean;
|
|
121
|
+
}
|
|
122
|
+
export interface ConfigureDefaultsOutput {
|
|
123
|
+
status: 'configured';
|
|
124
|
+
current_defaults: CurrentDefaults;
|
|
125
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/types/mcp.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for Hawkeye MCP Server
|
|
3
|
+
*/
|
|
4
|
+
import { HawkeyeError, ErrorResponse } from '../types/errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Convert any error into a HawkeyeError
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeError(error: unknown): HawkeyeError;
|
|
9
|
+
/**
|
|
10
|
+
* Format error for MCP tool response
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatErrorForMCP(error: unknown): ErrorResponse;
|
|
13
|
+
/**
|
|
14
|
+
* Create a user-friendly error message
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatErrorMessage(error: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* Check if error is retryable
|
|
19
|
+
*/
|
|
20
|
+
export declare function isRetryableError(error: unknown): boolean;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for Hawkeye MCP Server
|
|
3
|
+
*/
|
|
4
|
+
import { HawkeyeError, AuthenticationError, ApiError, ValidationError, } from '../types/errors.js';
|
|
5
|
+
import { logger } from './logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Convert any error into a HawkeyeError
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeError(error) {
|
|
10
|
+
// Already a HawkeyeError
|
|
11
|
+
if (error instanceof HawkeyeError) {
|
|
12
|
+
return error;
|
|
13
|
+
}
|
|
14
|
+
// Axios error
|
|
15
|
+
if (isAxiosError(error)) {
|
|
16
|
+
return handleAxiosError(error);
|
|
17
|
+
}
|
|
18
|
+
// Standard Error
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return new HawkeyeError('unknown', error.message, { originalError: error.name });
|
|
21
|
+
}
|
|
22
|
+
// Unknown error type
|
|
23
|
+
return new HawkeyeError('unknown', String(error));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Type guard for Axios errors
|
|
27
|
+
*/
|
|
28
|
+
function isAxiosError(error) {
|
|
29
|
+
return error.isAxiosError === true;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert Axios error to appropriate HawkeyeError
|
|
33
|
+
*/
|
|
34
|
+
function handleAxiosError(error) {
|
|
35
|
+
const statusCode = error.response?.status;
|
|
36
|
+
const responseData = error.response?.data;
|
|
37
|
+
// Authentication errors (401, 403)
|
|
38
|
+
if (statusCode === 401 || statusCode === 403) {
|
|
39
|
+
return new AuthenticationError('Authentication failed', { statusCode, response: responseData }, [
|
|
40
|
+
'Check your HAWKEYE_EMAIL and HAWKEYE_PASSWORD environment variables',
|
|
41
|
+
'Verify your credentials are correct',
|
|
42
|
+
'Ensure your account is not locked or expired',
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
// Validation errors (400)
|
|
46
|
+
if (statusCode === 400) {
|
|
47
|
+
return new ValidationError('Invalid request', { statusCode, response: responseData }, [
|
|
48
|
+
'Check the input parameters for the tool',
|
|
49
|
+
'Ensure all required fields are provided',
|
|
50
|
+
'Verify data formats match the expected schema',
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
// Not found (404)
|
|
54
|
+
if (statusCode === 404) {
|
|
55
|
+
return new ApiError('Resource not found', statusCode, responseData, [
|
|
56
|
+
'Verify the resource UUID is correct',
|
|
57
|
+
'Check if the resource has been deleted',
|
|
58
|
+
'Ensure you have access to this resource',
|
|
59
|
+
]);
|
|
60
|
+
}
|
|
61
|
+
// Rate limiting (429)
|
|
62
|
+
if (statusCode === 429) {
|
|
63
|
+
return new ApiError('Rate limit exceeded', statusCode, responseData, [
|
|
64
|
+
'Wait a few moments before retrying',
|
|
65
|
+
'Consider implementing exponential backoff',
|
|
66
|
+
'Contact support if the issue persists',
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
// Server errors (500+)
|
|
70
|
+
if (statusCode && statusCode >= 500) {
|
|
71
|
+
return new ApiError('Hawkeye API server error', statusCode, responseData, [
|
|
72
|
+
'Retry the request after a short delay',
|
|
73
|
+
'Check Hawkeye API status',
|
|
74
|
+
'Contact support if the issue persists',
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
// Network error (no response)
|
|
78
|
+
if (error.request && !error.response) {
|
|
79
|
+
return new ApiError('Network error - unable to reach Hawkeye API', undefined, { code: error.code, message: error.message }, [
|
|
80
|
+
'Check your internet connection',
|
|
81
|
+
'Verify HAWKEYE_BASE_URL is correct',
|
|
82
|
+
'Check if the Hawkeye API is accessible',
|
|
83
|
+
'Verify firewall settings',
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
// Generic API error
|
|
87
|
+
return new ApiError(error.message || 'API request failed', statusCode, responseData);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format error for MCP tool response
|
|
91
|
+
*/
|
|
92
|
+
export function formatErrorForMCP(error) {
|
|
93
|
+
const normalizedError = normalizeError(error);
|
|
94
|
+
// Log the error
|
|
95
|
+
logger.error('Error occurred', normalizedError);
|
|
96
|
+
return normalizedError.toJSON();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a user-friendly error message
|
|
100
|
+
*/
|
|
101
|
+
export function formatErrorMessage(error) {
|
|
102
|
+
const normalizedError = normalizeError(error);
|
|
103
|
+
let message = `Error: ${normalizedError.message}`;
|
|
104
|
+
if (normalizedError.recoverySuggestions && normalizedError.recoverySuggestions.length > 0) {
|
|
105
|
+
message += '\n\nSuggestions:\n';
|
|
106
|
+
message += normalizedError.recoverySuggestions.map((s, i) => ` ${i + 1}. ${s}`).join('\n');
|
|
107
|
+
}
|
|
108
|
+
return message;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if error is retryable
|
|
112
|
+
*/
|
|
113
|
+
export function isRetryableError(error) {
|
|
114
|
+
const normalizedError = normalizeError(error);
|
|
115
|
+
if (normalizedError instanceof ApiError) {
|
|
116
|
+
const statusCode = normalizedError.statusCode;
|
|
117
|
+
// Retry on network errors, rate limiting, and server errors
|
|
118
|
+
return (!statusCode || // Network error
|
|
119
|
+
statusCode === 429 || // Rate limit
|
|
120
|
+
statusCode >= 500 // Server error
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client wrapper with retry logic and better error handling
|
|
3
|
+
* Wraps axios with exponential backoff and standardized error handling
|
|
4
|
+
*/
|
|
5
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
6
|
+
/**
|
|
7
|
+
* HTTP client with retry logic
|
|
8
|
+
*/
|
|
9
|
+
export declare class HttpClient {
|
|
10
|
+
private client;
|
|
11
|
+
private maxRetries;
|
|
12
|
+
private baseDelay;
|
|
13
|
+
private backoffMultiplier;
|
|
14
|
+
constructor(baseURL: string, defaultTimeout?: number);
|
|
15
|
+
/**
|
|
16
|
+
* Set authorization header
|
|
17
|
+
*/
|
|
18
|
+
setAuthToken(token: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Clear authorization header
|
|
21
|
+
*/
|
|
22
|
+
clearAuthToken(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Execute request with retry logic
|
|
25
|
+
*/
|
|
26
|
+
private executeWithRetry;
|
|
27
|
+
/**
|
|
28
|
+
* GET request
|
|
29
|
+
*/
|
|
30
|
+
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
|
|
31
|
+
/**
|
|
32
|
+
* POST request
|
|
33
|
+
*/
|
|
34
|
+
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
|
|
35
|
+
/**
|
|
36
|
+
* PUT request
|
|
37
|
+
*/
|
|
38
|
+
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
|
|
39
|
+
/**
|
|
40
|
+
* DELETE request
|
|
41
|
+
*/
|
|
42
|
+
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
|
|
43
|
+
/**
|
|
44
|
+
* PATCH request
|
|
45
|
+
*/
|
|
46
|
+
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
|
|
47
|
+
/**
|
|
48
|
+
* Get the underlying Axios instance for advanced usage
|
|
49
|
+
*/
|
|
50
|
+
getAxiosInstance(): AxiosInstance;
|
|
51
|
+
}
|