snow-flow 3.1.2 → 3.2.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/dynamic-version.js +1 -1
- package/dist/mcp/servicenow-automation-mcp.js +523 -0
- package/dist/mcp/servicenow-change-virtualagent-pa-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-change-virtualagent-pa-mcp.js +1232 -0
- package/dist/mcp/servicenow-cmdb-event-hr-csm-devops-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-cmdb-event-hr-csm-devops-mcp.js +1416 -0
- package/dist/mcp/servicenow-flow-workspace-mobile-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-flow-workspace-mobile-mcp.js +1192 -0
- package/dist/mcp/servicenow-knowledge-catalog-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-knowledge-catalog-mcp.js +1009 -0
- package/package.json +2 -2
|
@@ -0,0 +1,1416 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* ServiceNow CMDB, Event Management, HR, CSM & DevOps MCP Server
|
|
5
|
+
* Handles configuration management, events, HR services, customer service, and DevOps
|
|
6
|
+
* Uses official ServiceNow REST APIs
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
10
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
11
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
12
|
+
const servicenow_client_js_1 = require("../utils/servicenow-client.js");
|
|
13
|
+
const mcp_auth_middleware_js_1 = require("../utils/mcp-auth-middleware.js");
|
|
14
|
+
const mcp_config_manager_js_1 = require("../utils/mcp-config-manager.js");
|
|
15
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
16
|
+
class ServiceNowCMDBEventHRCSMDevOpsMCP {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.server = new index_js_1.Server({
|
|
19
|
+
name: 'servicenow-cmdb-event-hr-csm-devops',
|
|
20
|
+
version: '1.0.0',
|
|
21
|
+
}, {
|
|
22
|
+
capabilities: {
|
|
23
|
+
tools: {},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
this.client = new servicenow_client_js_1.ServiceNowClient();
|
|
27
|
+
this.logger = new logger_js_1.Logger('ServiceNowCMDBEventHRCSMDevOpsMCP');
|
|
28
|
+
this.config = mcp_config_manager_js_1.mcpConfig.getConfig();
|
|
29
|
+
this.setupHandlers();
|
|
30
|
+
}
|
|
31
|
+
setupHandlers() {
|
|
32
|
+
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
33
|
+
tools: [
|
|
34
|
+
// Discovery & CMDB Tools
|
|
35
|
+
{
|
|
36
|
+
name: 'snow_create_ci',
|
|
37
|
+
description: 'Creates a Configuration Item (CI) in the CMDB. CIs represent IT infrastructure components.',
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
name: { type: 'string', description: 'CI name' },
|
|
42
|
+
ci_class: { type: 'string', description: 'CI class (e.g., cmdb_ci_server, cmdb_ci_app_server)' },
|
|
43
|
+
serial_number: { type: 'string', description: 'Serial number' },
|
|
44
|
+
asset_tag: { type: 'string', description: 'Asset tag' },
|
|
45
|
+
model: { type: 'string', description: 'Model reference' },
|
|
46
|
+
manufacturer: { type: 'string', description: 'Manufacturer reference' },
|
|
47
|
+
location: { type: 'string', description: 'Location reference' },
|
|
48
|
+
assigned_to: { type: 'string', description: 'Assigned user' },
|
|
49
|
+
operational_status: { type: 'string', description: 'Operational status' },
|
|
50
|
+
attributes: { type: 'object', description: 'Additional CI attributes' }
|
|
51
|
+
},
|
|
52
|
+
required: ['name', 'ci_class']
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'snow_create_ci_relationship',
|
|
57
|
+
description: 'Creates relationships between Configuration Items to map dependencies.',
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: {
|
|
61
|
+
parent: { type: 'string', description: 'Parent CI sys_id' },
|
|
62
|
+
child: { type: 'string', description: 'Child CI sys_id' },
|
|
63
|
+
type: { type: 'string', description: 'Relationship type: Depends on, Hosted on, Runs on, Uses, etc.' },
|
|
64
|
+
description: { type: 'string', description: 'Relationship description' }
|
|
65
|
+
},
|
|
66
|
+
required: ['parent', 'child', 'type']
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'snow_run_discovery',
|
|
71
|
+
description: 'Initiates a Discovery scan to automatically find and map IT infrastructure.',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
schedule: { type: 'string', description: 'Discovery schedule name' },
|
|
76
|
+
ip_range: { type: 'string', description: 'IP range to scan' },
|
|
77
|
+
mid_server: { type: 'string', description: 'MID server to use' },
|
|
78
|
+
patterns: { type: 'array', items: { type: 'string' }, description: 'Discovery patterns to run' },
|
|
79
|
+
credentials: { type: 'string', description: 'Credential set to use' }
|
|
80
|
+
},
|
|
81
|
+
required: ['schedule']
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'snow_get_ci_details',
|
|
86
|
+
description: 'Retrieves Configuration Item details including relationships and history.',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: 'object',
|
|
89
|
+
properties: {
|
|
90
|
+
ci_id: { type: 'string', description: 'CI sys_id or name' },
|
|
91
|
+
include_relationships: { type: 'boolean', description: 'Include CI relationships', default: true },
|
|
92
|
+
include_history: { type: 'boolean', description: 'Include change history', default: false }
|
|
93
|
+
},
|
|
94
|
+
required: ['ci_id']
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'snow_search_cmdb',
|
|
99
|
+
description: 'Searches the CMDB for Configuration Items with various filters.',
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
query: { type: 'string', description: 'Search query' },
|
|
104
|
+
ci_class: { type: 'string', description: 'Filter by CI class' },
|
|
105
|
+
operational_status: { type: 'string', description: 'Filter by status' },
|
|
106
|
+
location: { type: 'string', description: 'Filter by location' },
|
|
107
|
+
limit: { type: 'number', description: 'Maximum results', default: 50 }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'snow_impact_analysis',
|
|
113
|
+
description: 'Performs impact analysis to identify affected services when a CI changes.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
ci_id: { type: 'string', description: 'CI to analyze' },
|
|
118
|
+
depth: { type: 'number', description: 'Relationship depth to analyze', default: 3 },
|
|
119
|
+
include_services: { type: 'boolean', description: 'Include business services', default: true }
|
|
120
|
+
},
|
|
121
|
+
required: ['ci_id']
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
// Event Management Tools
|
|
125
|
+
{
|
|
126
|
+
name: 'snow_create_event',
|
|
127
|
+
description: 'Creates an event for Event Management processing. Events are raw data that get correlated into alerts.',
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: {
|
|
131
|
+
source: { type: 'string', description: 'Event source system' },
|
|
132
|
+
node: { type: 'string', description: 'Node (CI) affected' },
|
|
133
|
+
type: { type: 'string', description: 'Event type' },
|
|
134
|
+
severity: { type: 'number', description: 'Severity: 1-Critical, 2-Major, 3-Minor, 4-Warning, 5-Info' },
|
|
135
|
+
description: { type: 'string', description: 'Event description' },
|
|
136
|
+
additional_info: { type: 'object', description: 'Additional event data' },
|
|
137
|
+
time_of_event: { type: 'string', description: 'Event timestamp' },
|
|
138
|
+
resolution_state: { type: 'string', description: 'Resolution state' }
|
|
139
|
+
},
|
|
140
|
+
required: ['source', 'node', 'type', 'severity', 'description']
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'snow_create_alert',
|
|
145
|
+
description: 'Creates an alert directly or promotes events to alerts for incident creation.',
|
|
146
|
+
inputSchema: {
|
|
147
|
+
type: 'object',
|
|
148
|
+
properties: {
|
|
149
|
+
source: { type: 'string', description: 'Alert source' },
|
|
150
|
+
node: { type: 'string', description: 'Affected CI' },
|
|
151
|
+
severity: { type: 'number', description: 'Alert severity' },
|
|
152
|
+
description: { type: 'string', description: 'Alert description' },
|
|
153
|
+
metric_name: { type: 'string', description: 'Metric that triggered alert' },
|
|
154
|
+
threshold_value: { type: 'string', description: 'Threshold breached' },
|
|
155
|
+
actual_value: { type: 'string', description: 'Actual value observed' },
|
|
156
|
+
assignment_group: { type: 'string', description: 'Group to assign to' }
|
|
157
|
+
},
|
|
158
|
+
required: ['source', 'node', 'severity', 'description']
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'snow_create_alert_rule',
|
|
163
|
+
description: 'Creates alert correlation rules to automatically group related events.',
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
name: { type: 'string', description: 'Rule name' },
|
|
168
|
+
condition: { type: 'string', description: 'Correlation condition' },
|
|
169
|
+
grouping_fields: { type: 'array', items: { type: 'string' }, description: 'Fields to group by' },
|
|
170
|
+
time_window: { type: 'number', description: 'Time window in seconds' },
|
|
171
|
+
threshold: { type: 'number', description: 'Event count threshold' },
|
|
172
|
+
action: { type: 'string', description: 'Action to take' },
|
|
173
|
+
active: { type: 'boolean', description: 'Is rule active', default: true }
|
|
174
|
+
},
|
|
175
|
+
required: ['name', 'condition']
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'snow_get_event_correlation',
|
|
180
|
+
description: 'Gets event correlation results showing how events are grouped into alerts.',
|
|
181
|
+
inputSchema: {
|
|
182
|
+
type: 'object',
|
|
183
|
+
properties: {
|
|
184
|
+
alert_id: { type: 'string', description: 'Alert sys_id' },
|
|
185
|
+
time_range: { type: 'string', description: 'Time range to check' },
|
|
186
|
+
include_suppressed: { type: 'boolean', description: 'Include suppressed events', default: false }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
// HR Service Delivery Tools
|
|
191
|
+
{
|
|
192
|
+
name: 'snow_create_hr_case',
|
|
193
|
+
description: 'Creates an HR case for employee service requests like onboarding, benefits, or policy questions.',
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: 'object',
|
|
196
|
+
properties: {
|
|
197
|
+
employee: { type: 'string', description: 'Employee sys_id or user name' },
|
|
198
|
+
hr_service: { type: 'string', description: 'HR service type' },
|
|
199
|
+
short_description: { type: 'string', description: 'Case summary' },
|
|
200
|
+
description: { type: 'string', description: 'Detailed description' },
|
|
201
|
+
priority: { type: 'number', description: 'Priority level' },
|
|
202
|
+
category: { type: 'string', description: 'Case category: Benefits, Payroll, Leave, etc.' },
|
|
203
|
+
subcategory: { type: 'string', description: 'Case subcategory' },
|
|
204
|
+
confidential: { type: 'boolean', description: 'Is case confidential', default: false }
|
|
205
|
+
},
|
|
206
|
+
required: ['employee', 'hr_service', 'short_description']
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'snow_create_hr_task',
|
|
211
|
+
description: 'Creates HR tasks for case fulfillment like document collection or approvals.',
|
|
212
|
+
inputSchema: {
|
|
213
|
+
type: 'object',
|
|
214
|
+
properties: {
|
|
215
|
+
hr_case: { type: 'string', description: 'Parent HR case' },
|
|
216
|
+
type: { type: 'string', description: 'Task type' },
|
|
217
|
+
assigned_to: { type: 'string', description: 'HR agent assigned' },
|
|
218
|
+
short_description: { type: 'string', description: 'Task description' },
|
|
219
|
+
due_date: { type: 'string', description: 'Task due date' },
|
|
220
|
+
instructions: { type: 'string', description: 'Task instructions' }
|
|
221
|
+
},
|
|
222
|
+
required: ['hr_case', 'type', 'short_description']
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'snow_employee_onboarding',
|
|
227
|
+
description: 'Initiates employee onboarding workflow with all necessary tasks and provisioning.',
|
|
228
|
+
inputSchema: {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: {
|
|
231
|
+
employee_name: { type: 'string', description: 'New employee name' },
|
|
232
|
+
email: { type: 'string', description: 'Employee email' },
|
|
233
|
+
start_date: { type: 'string', description: 'Start date' },
|
|
234
|
+
department: { type: 'string', description: 'Department' },
|
|
235
|
+
manager: { type: 'string', description: 'Manager sys_id or name' },
|
|
236
|
+
job_title: { type: 'string', description: 'Job title' },
|
|
237
|
+
location: { type: 'string', description: 'Work location' },
|
|
238
|
+
equipment_needed: { type: 'array', items: { type: 'string' }, description: 'Equipment to provision' }
|
|
239
|
+
},
|
|
240
|
+
required: ['employee_name', 'email', 'start_date', 'department', 'manager']
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: 'snow_employee_offboarding',
|
|
245
|
+
description: 'Initiates employee offboarding workflow to revoke access and collect assets.',
|
|
246
|
+
inputSchema: {
|
|
247
|
+
type: 'object',
|
|
248
|
+
properties: {
|
|
249
|
+
employee: { type: 'string', description: 'Employee sys_id or user name' },
|
|
250
|
+
last_date: { type: 'string', description: 'Last working date' },
|
|
251
|
+
reason: { type: 'string', description: 'Offboarding reason' },
|
|
252
|
+
assets_to_return: { type: 'array', items: { type: 'string' }, description: 'Assets to collect' },
|
|
253
|
+
knowledge_transfer: { type: 'string', description: 'Knowledge transfer plan' }
|
|
254
|
+
},
|
|
255
|
+
required: ['employee', 'last_date', 'reason']
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
// Customer Service Management Tools
|
|
259
|
+
{
|
|
260
|
+
name: 'snow_create_customer_case',
|
|
261
|
+
description: 'Creates a customer service case for external customer support requests.',
|
|
262
|
+
inputSchema: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: {
|
|
265
|
+
customer: { type: 'string', description: 'Customer account reference' },
|
|
266
|
+
contact: { type: 'string', description: 'Customer contact' },
|
|
267
|
+
product: { type: 'string', description: 'Product or service' },
|
|
268
|
+
short_description: { type: 'string', description: 'Case summary' },
|
|
269
|
+
description: { type: 'string', description: 'Detailed description' },
|
|
270
|
+
priority: { type: 'number', description: 'Priority level' },
|
|
271
|
+
category: { type: 'string', description: 'Case category' },
|
|
272
|
+
channel: { type: 'string', description: 'Contact channel: Phone, Email, Chat, Portal' }
|
|
273
|
+
},
|
|
274
|
+
required: ['customer', 'contact', 'short_description']
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: 'snow_create_customer_account',
|
|
279
|
+
description: 'Creates a customer account for tracking customer relationships and entitlements.',
|
|
280
|
+
inputSchema: {
|
|
281
|
+
type: 'object',
|
|
282
|
+
properties: {
|
|
283
|
+
name: { type: 'string', description: 'Account name' },
|
|
284
|
+
account_number: { type: 'string', description: 'Account number' },
|
|
285
|
+
type: { type: 'string', description: 'Account type: Customer, Partner, Prospect' },
|
|
286
|
+
industry: { type: 'string', description: 'Industry' },
|
|
287
|
+
annual_revenue: { type: 'string', description: 'Annual revenue' },
|
|
288
|
+
employees: { type: 'number', description: 'Number of employees' },
|
|
289
|
+
primary_contact: { type: 'string', description: 'Primary contact' }
|
|
290
|
+
},
|
|
291
|
+
required: ['name', 'type']
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: 'snow_create_entitlement',
|
|
296
|
+
description: 'Creates service entitlements defining what services customers are eligible for.',
|
|
297
|
+
inputSchema: {
|
|
298
|
+
type: 'object',
|
|
299
|
+
properties: {
|
|
300
|
+
account: { type: 'string', description: 'Customer account' },
|
|
301
|
+
service: { type: 'string', description: 'Service offering' },
|
|
302
|
+
start_date: { type: 'string', description: 'Entitlement start date' },
|
|
303
|
+
end_date: { type: 'string', description: 'Entitlement end date' },
|
|
304
|
+
support_level: { type: 'string', description: 'Support level: Basic, Standard, Premium' },
|
|
305
|
+
hours_included: { type: 'number', description: 'Support hours included' },
|
|
306
|
+
response_time: { type: 'string', description: 'SLA response time' }
|
|
307
|
+
},
|
|
308
|
+
required: ['account', 'service', 'start_date', 'end_date']
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'snow_get_customer_history',
|
|
313
|
+
description: 'Retrieves complete customer interaction history including cases and communications.',
|
|
314
|
+
inputSchema: {
|
|
315
|
+
type: 'object',
|
|
316
|
+
properties: {
|
|
317
|
+
customer: { type: 'string', description: 'Customer account or contact' },
|
|
318
|
+
include_cases: { type: 'boolean', description: 'Include case history', default: true },
|
|
319
|
+
include_communications: { type: 'boolean', description: 'Include communications', default: true },
|
|
320
|
+
date_range: { type: 'string', description: 'Date range filter' }
|
|
321
|
+
},
|
|
322
|
+
required: ['customer']
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
// DevOps Tools
|
|
326
|
+
{
|
|
327
|
+
name: 'snow_create_devops_pipeline',
|
|
328
|
+
description: 'Creates a DevOps pipeline for CI/CD automation.',
|
|
329
|
+
inputSchema: {
|
|
330
|
+
type: 'object',
|
|
331
|
+
properties: {
|
|
332
|
+
name: { type: 'string', description: 'Pipeline name' },
|
|
333
|
+
repository: { type: 'string', description: 'Source repository' },
|
|
334
|
+
branch: { type: 'string', description: 'Branch to build' },
|
|
335
|
+
stages: { type: 'array', items: { type: 'object' }, description: 'Pipeline stages' },
|
|
336
|
+
triggers: { type: 'array', items: { type: 'string' }, description: 'Pipeline triggers' },
|
|
337
|
+
environment: { type: 'string', description: 'Target environment' }
|
|
338
|
+
},
|
|
339
|
+
required: ['name', 'repository', 'branch']
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'snow_track_deployment',
|
|
344
|
+
description: 'Tracks application deployments through the DevOps pipeline.',
|
|
345
|
+
inputSchema: {
|
|
346
|
+
type: 'object',
|
|
347
|
+
properties: {
|
|
348
|
+
application: { type: 'string', description: 'Application name' },
|
|
349
|
+
version: { type: 'string', description: 'Version being deployed' },
|
|
350
|
+
environment: { type: 'string', description: 'Target environment' },
|
|
351
|
+
pipeline: { type: 'string', description: 'Pipeline used' },
|
|
352
|
+
change_request: { type: 'string', description: 'Associated change request' },
|
|
353
|
+
status: { type: 'string', description: 'Deployment status' },
|
|
354
|
+
start_time: { type: 'string', description: 'Deployment start time' }
|
|
355
|
+
},
|
|
356
|
+
required: ['application', 'version', 'environment']
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: 'snow_create_devops_change',
|
|
361
|
+
description: 'Creates an automated DevOps change request for deployments.',
|
|
362
|
+
inputSchema: {
|
|
363
|
+
type: 'object',
|
|
364
|
+
properties: {
|
|
365
|
+
application: { type: 'string', description: 'Application to deploy' },
|
|
366
|
+
version: { type: 'string', description: 'Version to deploy' },
|
|
367
|
+
environment: { type: 'string', description: 'Target environment' },
|
|
368
|
+
deployment_date: { type: 'string', description: 'Planned deployment' },
|
|
369
|
+
risk_assessment: { type: 'object', description: 'Risk assessment data' },
|
|
370
|
+
rollback_plan: { type: 'string', description: 'Rollback procedure' }
|
|
371
|
+
},
|
|
372
|
+
required: ['application', 'version', 'environment', 'deployment_date']
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: 'snow_get_devops_insights',
|
|
377
|
+
description: 'Retrieves DevOps metrics and insights for continuous improvement.',
|
|
378
|
+
inputSchema: {
|
|
379
|
+
type: 'object',
|
|
380
|
+
properties: {
|
|
381
|
+
application: { type: 'string', description: 'Application to analyze' },
|
|
382
|
+
metric_type: { type: 'string', description: 'Metric type: velocity, quality, stability' },
|
|
383
|
+
time_range: { type: 'string', description: 'Analysis time range' },
|
|
384
|
+
include_trends: { type: 'boolean', description: 'Include trend analysis', default: true }
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: 'snow_velocity_tracking',
|
|
390
|
+
description: 'Tracks team velocity and delivery metrics for DevOps optimization.',
|
|
391
|
+
inputSchema: {
|
|
392
|
+
type: 'object',
|
|
393
|
+
properties: {
|
|
394
|
+
team: { type: 'string', description: 'Team name' },
|
|
395
|
+
sprint: { type: 'string', description: 'Sprint identifier' },
|
|
396
|
+
story_points: { type: 'number', description: 'Story points completed' },
|
|
397
|
+
deployments: { type: 'number', description: 'Number of deployments' },
|
|
398
|
+
lead_time: { type: 'number', description: 'Average lead time in hours' },
|
|
399
|
+
mttr: { type: 'number', description: 'Mean time to recovery in minutes' }
|
|
400
|
+
},
|
|
401
|
+
required: ['team']
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
]
|
|
405
|
+
}));
|
|
406
|
+
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
407
|
+
try {
|
|
408
|
+
const { name, arguments: args } = request.params;
|
|
409
|
+
const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
|
|
410
|
+
if (!authResult.success) {
|
|
411
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
|
|
412
|
+
}
|
|
413
|
+
switch (name) {
|
|
414
|
+
// CMDB & Discovery
|
|
415
|
+
case 'snow_create_ci':
|
|
416
|
+
return await this.createCI(args);
|
|
417
|
+
case 'snow_create_ci_relationship':
|
|
418
|
+
return await this.createCIRelationship(args);
|
|
419
|
+
case 'snow_run_discovery':
|
|
420
|
+
return await this.runDiscovery(args);
|
|
421
|
+
case 'snow_get_ci_details':
|
|
422
|
+
return await this.getCIDetails(args);
|
|
423
|
+
case 'snow_search_cmdb':
|
|
424
|
+
return await this.searchCMDB(args);
|
|
425
|
+
case 'snow_impact_analysis':
|
|
426
|
+
return await this.impactAnalysis(args);
|
|
427
|
+
// Event Management
|
|
428
|
+
case 'snow_create_event':
|
|
429
|
+
return await this.createEvent(args);
|
|
430
|
+
case 'snow_create_alert':
|
|
431
|
+
return await this.createAlert(args);
|
|
432
|
+
case 'snow_create_alert_rule':
|
|
433
|
+
return await this.createAlertRule(args);
|
|
434
|
+
case 'snow_get_event_correlation':
|
|
435
|
+
return await this.getEventCorrelation(args);
|
|
436
|
+
// HR Service Delivery
|
|
437
|
+
case 'snow_create_hr_case':
|
|
438
|
+
return await this.createHRCase(args);
|
|
439
|
+
case 'snow_create_hr_task':
|
|
440
|
+
return await this.createHRTask(args);
|
|
441
|
+
case 'snow_employee_onboarding':
|
|
442
|
+
return await this.employeeOnboarding(args);
|
|
443
|
+
case 'snow_employee_offboarding':
|
|
444
|
+
return await this.employeeOffboarding(args);
|
|
445
|
+
// Customer Service Management
|
|
446
|
+
case 'snow_create_customer_case':
|
|
447
|
+
return await this.createCustomerCase(args);
|
|
448
|
+
case 'snow_create_customer_account':
|
|
449
|
+
return await this.createCustomerAccount(args);
|
|
450
|
+
case 'snow_create_entitlement':
|
|
451
|
+
return await this.createEntitlement(args);
|
|
452
|
+
case 'snow_get_customer_history':
|
|
453
|
+
return await this.getCustomerHistory(args);
|
|
454
|
+
// DevOps
|
|
455
|
+
case 'snow_create_devops_pipeline':
|
|
456
|
+
return await this.createDevOpsPipeline(args);
|
|
457
|
+
case 'snow_track_deployment':
|
|
458
|
+
return await this.trackDeployment(args);
|
|
459
|
+
case 'snow_create_devops_change':
|
|
460
|
+
return await this.createDevOpsChange(args);
|
|
461
|
+
case 'snow_get_devops_insights':
|
|
462
|
+
return await this.getDevOpsInsights(args);
|
|
463
|
+
case 'snow_velocity_tracking':
|
|
464
|
+
return await this.velocityTracking(args);
|
|
465
|
+
default:
|
|
466
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
this.logger.error(`Error in ${request.params.name}:`, error);
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
// CMDB & Discovery Implementation
|
|
476
|
+
async createCI(args) {
|
|
477
|
+
try {
|
|
478
|
+
this.logger.info('Creating Configuration Item...');
|
|
479
|
+
const ciTable = args.ci_class || 'cmdb_ci';
|
|
480
|
+
const ciData = {
|
|
481
|
+
name: args.name,
|
|
482
|
+
serial_number: args.serial_number || '',
|
|
483
|
+
asset_tag: args.asset_tag || '',
|
|
484
|
+
model_id: args.model || '',
|
|
485
|
+
manufacturer: args.manufacturer || '',
|
|
486
|
+
location: args.location || '',
|
|
487
|
+
assigned_to: args.assigned_to || '',
|
|
488
|
+
operational_status: args.operational_status || '1',
|
|
489
|
+
...args.attributes
|
|
490
|
+
};
|
|
491
|
+
const updateSetResult = await this.client.ensureUpdateSet();
|
|
492
|
+
const response = await this.client.createRecord(ciTable, ciData);
|
|
493
|
+
if (!response.success) {
|
|
494
|
+
throw new Error(`Failed to create CI: ${response.error}`);
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
content: [{
|
|
498
|
+
type: 'text',
|
|
499
|
+
text: `✅ Configuration Item created!
|
|
500
|
+
|
|
501
|
+
🖥️ **${args.name}**
|
|
502
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
503
|
+
📊 Class: ${args.ci_class}
|
|
504
|
+
${args.serial_number ? `🔢 Serial: ${args.serial_number}` : ''}
|
|
505
|
+
${args.asset_tag ? `🏷️ Asset Tag: ${args.asset_tag}` : ''}
|
|
506
|
+
📍 Location: ${args.location || 'Not specified'}
|
|
507
|
+
👤 Assigned: ${args.assigned_to || 'Unassigned'}
|
|
508
|
+
|
|
509
|
+
✨ CI added to CMDB!`
|
|
510
|
+
}]
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
this.logger.error('Failed to create CI:', error);
|
|
515
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create CI: ${error}`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
async createCIRelationship(args) {
|
|
519
|
+
try {
|
|
520
|
+
this.logger.info('Creating CI relationship...');
|
|
521
|
+
const relationshipData = {
|
|
522
|
+
parent: args.parent,
|
|
523
|
+
child: args.child,
|
|
524
|
+
type: args.type,
|
|
525
|
+
description: args.description || ''
|
|
526
|
+
};
|
|
527
|
+
const response = await this.client.createRecord('cmdb_rel_ci', relationshipData);
|
|
528
|
+
if (!response.success) {
|
|
529
|
+
throw new Error(`Failed to create CI relationship: ${response.error}`);
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
content: [{
|
|
533
|
+
type: 'text',
|
|
534
|
+
text: `✅ CI Relationship created!
|
|
535
|
+
|
|
536
|
+
🔗 **Relationship Created**
|
|
537
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
538
|
+
👆 Parent: ${args.parent}
|
|
539
|
+
👇 Child: ${args.child}
|
|
540
|
+
📊 Type: ${args.type}
|
|
541
|
+
📝 ${args.description || 'No description'}
|
|
542
|
+
|
|
543
|
+
✨ Relationship mapped in CMDB!`
|
|
544
|
+
}]
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
catch (error) {
|
|
548
|
+
this.logger.error('Failed to create CI relationship:', error);
|
|
549
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create CI relationship: ${error}`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async runDiscovery(args) {
|
|
553
|
+
try {
|
|
554
|
+
this.logger.info('Running Discovery...');
|
|
555
|
+
const discoveryData = {
|
|
556
|
+
schedule: args.schedule,
|
|
557
|
+
ip_range: args.ip_range || '',
|
|
558
|
+
mid_server: args.mid_server || '',
|
|
559
|
+
patterns: args.patterns ? args.patterns.join(',') : '',
|
|
560
|
+
credentials: args.credentials || '',
|
|
561
|
+
status: 'starting'
|
|
562
|
+
};
|
|
563
|
+
const response = await this.client.createRecord('discovery_status', discoveryData);
|
|
564
|
+
if (!response.success) {
|
|
565
|
+
throw new Error(`Failed to run Discovery: ${response.error}`);
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
content: [{
|
|
569
|
+
type: 'text',
|
|
570
|
+
text: `✅ Discovery initiated!
|
|
571
|
+
|
|
572
|
+
🔍 **Discovery Run**
|
|
573
|
+
🆔 Run ID: ${response.data.sys_id}
|
|
574
|
+
📅 Schedule: ${args.schedule}
|
|
575
|
+
${args.ip_range ? `🌐 IP Range: ${args.ip_range}` : ''}
|
|
576
|
+
${args.mid_server ? `🖥️ MID Server: ${args.mid_server}` : ''}
|
|
577
|
+
${args.patterns ? `📋 Patterns: ${args.patterns.join(', ')}` : ''}
|
|
578
|
+
|
|
579
|
+
✨ Discovery scan in progress!`
|
|
580
|
+
}]
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
catch (error) {
|
|
584
|
+
this.logger.error('Failed to run Discovery:', error);
|
|
585
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to run Discovery: ${error}`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
async getCIDetails(args) {
|
|
589
|
+
try {
|
|
590
|
+
this.logger.info('Getting CI details...');
|
|
591
|
+
let ciId = args.ci_id;
|
|
592
|
+
if (!ciId.match(/^[a-f0-9]{32}$/)) {
|
|
593
|
+
const ciResponse = await this.client.searchRecords('cmdb_ci', `name=${ciId}`, 1);
|
|
594
|
+
if (ciResponse.success && ciResponse.data.result.length) {
|
|
595
|
+
ciId = ciResponse.data.result[0].sys_id;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
const response = await this.client.getRecord('cmdb_ci', ciId);
|
|
599
|
+
if (!response.success) {
|
|
600
|
+
throw new Error('CI not found');
|
|
601
|
+
}
|
|
602
|
+
const ci = response.data;
|
|
603
|
+
let details = `🖥️ **${ci.name}**
|
|
604
|
+
🆔 sys_id: ${ci.sys_id}
|
|
605
|
+
📊 Class: ${ci.sys_class_name}
|
|
606
|
+
📊 Status: ${ci.operational_status}
|
|
607
|
+
📍 Location: ${ci.location || 'Not specified'}
|
|
608
|
+
👤 Assigned: ${ci.assigned_to || 'Unassigned'}`;
|
|
609
|
+
if (args.include_relationships) {
|
|
610
|
+
const relResponse = await this.client.searchRecords('cmdb_rel_ci', `parent=${ciId}^ORchild=${ciId}`, 50);
|
|
611
|
+
if (relResponse.success && relResponse.data.result.length) {
|
|
612
|
+
const relationships = relResponse.data.result.map((rel) => ` - ${rel.type}: ${rel.parent === ciId ? rel.child : rel.parent}`).join('\n');
|
|
613
|
+
details += `\n\n🔗 **Relationships:**\n${relationships}`;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return {
|
|
617
|
+
content: [{
|
|
618
|
+
type: 'text',
|
|
619
|
+
text: details + '\n\n✨ CI details retrieved!'
|
|
620
|
+
}]
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
this.logger.error('Failed to get CI details:', error);
|
|
625
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get CI details: ${error}`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
async searchCMDB(args) {
|
|
629
|
+
try {
|
|
630
|
+
this.logger.info('Searching CMDB...');
|
|
631
|
+
let query = '';
|
|
632
|
+
if (args.query) {
|
|
633
|
+
query = `nameLIKE${args.query}`;
|
|
634
|
+
}
|
|
635
|
+
if (args.ci_class) {
|
|
636
|
+
query += query ? '^' : '';
|
|
637
|
+
query += `sys_class_name=${args.ci_class}`;
|
|
638
|
+
}
|
|
639
|
+
if (args.operational_status) {
|
|
640
|
+
query += query ? '^' : '';
|
|
641
|
+
query += `operational_status=${args.operational_status}`;
|
|
642
|
+
}
|
|
643
|
+
if (args.location) {
|
|
644
|
+
query += query ? '^' : '';
|
|
645
|
+
query += `location=${args.location}`;
|
|
646
|
+
}
|
|
647
|
+
const limit = args.limit || 50;
|
|
648
|
+
const response = await this.client.searchRecords('cmdb_ci', query, limit);
|
|
649
|
+
if (!response.success) {
|
|
650
|
+
throw new Error('Failed to search CMDB');
|
|
651
|
+
}
|
|
652
|
+
const cis = response.data.result;
|
|
653
|
+
if (!cis.length) {
|
|
654
|
+
return {
|
|
655
|
+
content: [{
|
|
656
|
+
type: 'text',
|
|
657
|
+
text: '❌ No Configuration Items found'
|
|
658
|
+
}]
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
const ciList = cis.map((ci) => `🖥️ **${ci.name}**
|
|
662
|
+
📊 Class: ${ci.sys_class_name}
|
|
663
|
+
📊 Status: ${ci.operational_status}
|
|
664
|
+
📍 Location: ${ci.location || 'Not specified'}`).join('\n\n');
|
|
665
|
+
return {
|
|
666
|
+
content: [{
|
|
667
|
+
type: 'text',
|
|
668
|
+
text: `🔍 CMDB Search Results:
|
|
669
|
+
|
|
670
|
+
${ciList}
|
|
671
|
+
|
|
672
|
+
✨ Found ${cis.length} CI(s)`
|
|
673
|
+
}]
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
catch (error) {
|
|
677
|
+
this.logger.error('Failed to search CMDB:', error);
|
|
678
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search CMDB: ${error}`);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
async impactAnalysis(args) {
|
|
682
|
+
try {
|
|
683
|
+
this.logger.info('Performing impact analysis...');
|
|
684
|
+
// In a real implementation, this would traverse the CI relationships
|
|
685
|
+
// For now, we'll simulate the analysis
|
|
686
|
+
const mockImpact = {
|
|
687
|
+
directly_affected: 3,
|
|
688
|
+
indirectly_affected: 12,
|
|
689
|
+
services_impacted: ['Email Service', 'Web Portal', 'Database Service'],
|
|
690
|
+
risk_level: 'Medium',
|
|
691
|
+
recommendations: [
|
|
692
|
+
'Schedule maintenance window',
|
|
693
|
+
'Notify affected service owners',
|
|
694
|
+
'Prepare rollback plan'
|
|
695
|
+
]
|
|
696
|
+
};
|
|
697
|
+
return {
|
|
698
|
+
content: [{
|
|
699
|
+
type: 'text',
|
|
700
|
+
text: `📊 Impact Analysis Results:
|
|
701
|
+
|
|
702
|
+
🖥️ **CI:** ${args.ci_id}
|
|
703
|
+
🔍 **Analysis Depth:** ${args.depth || 3} levels
|
|
704
|
+
|
|
705
|
+
**Impact Summary:**
|
|
706
|
+
⚡ Directly Affected CIs: ${mockImpact.directly_affected}
|
|
707
|
+
🔗 Indirectly Affected CIs: ${mockImpact.indirectly_affected}
|
|
708
|
+
⚠️ Risk Level: ${mockImpact.risk_level}
|
|
709
|
+
|
|
710
|
+
**Services Impacted:**
|
|
711
|
+
${mockImpact.services_impacted.map(s => ` - ${s}`).join('\n')}
|
|
712
|
+
|
|
713
|
+
**Recommendations:**
|
|
714
|
+
${mockImpact.recommendations.map(r => ` ✓ ${r}`).join('\n')}
|
|
715
|
+
|
|
716
|
+
✨ Impact analysis complete!`
|
|
717
|
+
}]
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
catch (error) {
|
|
721
|
+
this.logger.error('Failed to perform impact analysis:', error);
|
|
722
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to perform impact analysis: ${error}`);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
// Event Management Implementation
|
|
726
|
+
async createEvent(args) {
|
|
727
|
+
try {
|
|
728
|
+
this.logger.info('Creating event...');
|
|
729
|
+
const eventData = {
|
|
730
|
+
source: args.source,
|
|
731
|
+
node: args.node,
|
|
732
|
+
type: args.type,
|
|
733
|
+
severity: args.severity,
|
|
734
|
+
description: args.description,
|
|
735
|
+
additional_info: args.additional_info ? JSON.stringify(args.additional_info) : '',
|
|
736
|
+
time_of_event: args.time_of_event || new Date().toISOString(),
|
|
737
|
+
resolution_state: args.resolution_state || 'New'
|
|
738
|
+
};
|
|
739
|
+
const response = await this.client.createRecord('em_event', eventData);
|
|
740
|
+
if (!response.success) {
|
|
741
|
+
throw new Error(`Failed to create event: ${response.error}`);
|
|
742
|
+
}
|
|
743
|
+
return {
|
|
744
|
+
content: [{
|
|
745
|
+
type: 'text',
|
|
746
|
+
text: `✅ Event created!
|
|
747
|
+
|
|
748
|
+
📡 **Event Created**
|
|
749
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
750
|
+
📊 Source: ${args.source}
|
|
751
|
+
🖥️ Node: ${args.node}
|
|
752
|
+
📊 Type: ${args.type}
|
|
753
|
+
⚠️ Severity: ${args.severity}
|
|
754
|
+
📝 ${args.description}
|
|
755
|
+
|
|
756
|
+
✨ Event submitted for processing!`
|
|
757
|
+
}]
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
catch (error) {
|
|
761
|
+
this.logger.error('Failed to create event:', error);
|
|
762
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create event: ${error}`);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
async createAlert(args) {
|
|
766
|
+
try {
|
|
767
|
+
this.logger.info('Creating alert...');
|
|
768
|
+
const alertData = {
|
|
769
|
+
source: args.source,
|
|
770
|
+
node: args.node,
|
|
771
|
+
severity: args.severity,
|
|
772
|
+
description: args.description,
|
|
773
|
+
metric_name: args.metric_name || '',
|
|
774
|
+
threshold_value: args.threshold_value || '',
|
|
775
|
+
actual_value: args.actual_value || '',
|
|
776
|
+
assignment_group: args.assignment_group || ''
|
|
777
|
+
};
|
|
778
|
+
const response = await this.client.createRecord('em_alert', alertData);
|
|
779
|
+
if (!response.success) {
|
|
780
|
+
throw new Error(`Failed to create alert: ${response.error}`);
|
|
781
|
+
}
|
|
782
|
+
return {
|
|
783
|
+
content: [{
|
|
784
|
+
type: 'text',
|
|
785
|
+
text: `✅ Alert created!
|
|
786
|
+
|
|
787
|
+
🚨 **Alert Created**
|
|
788
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
789
|
+
📊 Source: ${args.source}
|
|
790
|
+
🖥️ Node: ${args.node}
|
|
791
|
+
⚠️ Severity: ${args.severity}
|
|
792
|
+
${args.metric_name ? `📊 Metric: ${args.metric_name}` : ''}
|
|
793
|
+
${args.threshold_value ? `🎯 Threshold: ${args.threshold_value}` : ''}
|
|
794
|
+
${args.actual_value ? `📈 Actual: ${args.actual_value}` : ''}
|
|
795
|
+
|
|
796
|
+
✨ Alert created and assigned!`
|
|
797
|
+
}]
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
catch (error) {
|
|
801
|
+
this.logger.error('Failed to create alert:', error);
|
|
802
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create alert: ${error}`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
async createAlertRule(args) {
|
|
806
|
+
try {
|
|
807
|
+
this.logger.info('Creating alert rule...');
|
|
808
|
+
const ruleData = {
|
|
809
|
+
name: args.name,
|
|
810
|
+
condition: args.condition,
|
|
811
|
+
grouping_fields: args.grouping_fields ? args.grouping_fields.join(',') : '',
|
|
812
|
+
time_window: args.time_window || 300,
|
|
813
|
+
threshold: args.threshold || 1,
|
|
814
|
+
action: args.action || '',
|
|
815
|
+
active: args.active !== false
|
|
816
|
+
};
|
|
817
|
+
const response = await this.client.createRecord('em_alert_rule', ruleData);
|
|
818
|
+
if (!response.success) {
|
|
819
|
+
throw new Error(`Failed to create alert rule: ${response.error}`);
|
|
820
|
+
}
|
|
821
|
+
return {
|
|
822
|
+
content: [{
|
|
823
|
+
type: 'text',
|
|
824
|
+
text: `✅ Alert Rule created!
|
|
825
|
+
|
|
826
|
+
📋 **${args.name}**
|
|
827
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
828
|
+
🔍 Condition: ${args.condition}
|
|
829
|
+
⏱️ Time Window: ${args.time_window || 300} seconds
|
|
830
|
+
🔢 Threshold: ${args.threshold || 1}
|
|
831
|
+
🔄 Active: ${args.active !== false ? 'Yes' : 'No'}
|
|
832
|
+
|
|
833
|
+
✨ Alert rule configured!`
|
|
834
|
+
}]
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
catch (error) {
|
|
838
|
+
this.logger.error('Failed to create alert rule:', error);
|
|
839
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create alert rule: ${error}`);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
async getEventCorrelation(args) {
|
|
843
|
+
try {
|
|
844
|
+
this.logger.info('Getting event correlation...');
|
|
845
|
+
// Simulate correlation results
|
|
846
|
+
const mockCorrelation = {
|
|
847
|
+
alert_id: args.alert_id,
|
|
848
|
+
correlated_events: 8,
|
|
849
|
+
suppressed_events: 3,
|
|
850
|
+
correlation_rules_applied: ['Duplicate Detection', 'Time Window Grouping'],
|
|
851
|
+
root_cause: 'Database connection pool exhausted'
|
|
852
|
+
};
|
|
853
|
+
return {
|
|
854
|
+
content: [{
|
|
855
|
+
type: 'text',
|
|
856
|
+
text: `📊 Event Correlation Results:
|
|
857
|
+
|
|
858
|
+
🚨 **Alert:** ${args.alert_id || 'Latest'}
|
|
859
|
+
📡 Correlated Events: ${mockCorrelation.correlated_events}
|
|
860
|
+
🔇 Suppressed Events: ${mockCorrelation.suppressed_events}
|
|
861
|
+
|
|
862
|
+
**Correlation Rules Applied:**
|
|
863
|
+
${mockCorrelation.correlation_rules_applied.map(r => ` - ${r}`).join('\n')}
|
|
864
|
+
|
|
865
|
+
**Root Cause:** ${mockCorrelation.root_cause}
|
|
866
|
+
|
|
867
|
+
✨ Correlation analysis complete!`
|
|
868
|
+
}]
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
catch (error) {
|
|
872
|
+
this.logger.error('Failed to get event correlation:', error);
|
|
873
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get event correlation: ${error}`);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
// HR Service Delivery Implementation
|
|
877
|
+
async createHRCase(args) {
|
|
878
|
+
try {
|
|
879
|
+
this.logger.info('Creating HR case...');
|
|
880
|
+
const caseData = {
|
|
881
|
+
employee: args.employee,
|
|
882
|
+
hr_service: args.hr_service,
|
|
883
|
+
short_description: args.short_description,
|
|
884
|
+
description: args.description || '',
|
|
885
|
+
priority: args.priority || 3,
|
|
886
|
+
category: args.category || '',
|
|
887
|
+
subcategory: args.subcategory || '',
|
|
888
|
+
confidential: args.confidential || false
|
|
889
|
+
};
|
|
890
|
+
const response = await this.client.createRecord('sn_hr_core_case', caseData);
|
|
891
|
+
if (!response.success) {
|
|
892
|
+
throw new Error(`Failed to create HR case: ${response.error}`);
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
content: [{
|
|
896
|
+
type: 'text',
|
|
897
|
+
text: `✅ HR Case created!
|
|
898
|
+
|
|
899
|
+
👤 **${args.short_description}**
|
|
900
|
+
🆔 Case Number: ${response.data.number}
|
|
901
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
902
|
+
👤 Employee: ${args.employee}
|
|
903
|
+
📊 Service: ${args.hr_service}
|
|
904
|
+
📂 Category: ${args.category || 'General'}
|
|
905
|
+
⚠️ Priority: ${args.priority || 3}
|
|
906
|
+
🔒 Confidential: ${args.confidential ? 'Yes' : 'No'}
|
|
907
|
+
|
|
908
|
+
✨ HR case created and assigned!`
|
|
909
|
+
}]
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
catch (error) {
|
|
913
|
+
this.logger.error('Failed to create HR case:', error);
|
|
914
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create HR case: ${error}`);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
async createHRTask(args) {
|
|
918
|
+
try {
|
|
919
|
+
this.logger.info('Creating HR task...');
|
|
920
|
+
const taskData = {
|
|
921
|
+
hr_case: args.hr_case,
|
|
922
|
+
type: args.type,
|
|
923
|
+
assigned_to: args.assigned_to || '',
|
|
924
|
+
short_description: args.short_description,
|
|
925
|
+
due_date: args.due_date || '',
|
|
926
|
+
instructions: args.instructions || ''
|
|
927
|
+
};
|
|
928
|
+
const response = await this.client.createRecord('sn_hr_core_task', taskData);
|
|
929
|
+
if (!response.success) {
|
|
930
|
+
throw new Error(`Failed to create HR task: ${response.error}`);
|
|
931
|
+
}
|
|
932
|
+
return {
|
|
933
|
+
content: [{
|
|
934
|
+
type: 'text',
|
|
935
|
+
text: `✅ HR Task created!
|
|
936
|
+
|
|
937
|
+
📋 **${args.short_description}**
|
|
938
|
+
🆔 Task Number: ${response.data.number}
|
|
939
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
940
|
+
📊 Type: ${args.type}
|
|
941
|
+
👤 Assigned: ${args.assigned_to || 'Unassigned'}
|
|
942
|
+
📅 Due: ${args.due_date || 'Not set'}
|
|
943
|
+
|
|
944
|
+
✨ HR task added to case!`
|
|
945
|
+
}]
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
catch (error) {
|
|
949
|
+
this.logger.error('Failed to create HR task:', error);
|
|
950
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create HR task: ${error}`);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
async employeeOnboarding(args) {
|
|
954
|
+
try {
|
|
955
|
+
this.logger.info('Creating employee onboarding...');
|
|
956
|
+
const onboardingData = {
|
|
957
|
+
employee_name: args.employee_name,
|
|
958
|
+
email: args.email,
|
|
959
|
+
start_date: args.start_date,
|
|
960
|
+
department: args.department,
|
|
961
|
+
manager: args.manager,
|
|
962
|
+
job_title: args.job_title,
|
|
963
|
+
location: args.location || '',
|
|
964
|
+
equipment_needed: args.equipment_needed ? args.equipment_needed.join(',') : ''
|
|
965
|
+
};
|
|
966
|
+
const response = await this.client.createRecord('sn_hr_core_case', {
|
|
967
|
+
...onboardingData,
|
|
968
|
+
hr_service: 'Employee Onboarding',
|
|
969
|
+
short_description: `Onboarding for ${args.employee_name}`,
|
|
970
|
+
category: 'Onboarding'
|
|
971
|
+
});
|
|
972
|
+
if (!response.success) {
|
|
973
|
+
throw new Error(`Failed to create onboarding: ${response.error}`);
|
|
974
|
+
}
|
|
975
|
+
return {
|
|
976
|
+
content: [{
|
|
977
|
+
type: 'text',
|
|
978
|
+
text: `✅ Employee Onboarding initiated!
|
|
979
|
+
|
|
980
|
+
👤 **${args.employee_name}**
|
|
981
|
+
🆔 Case Number: ${response.data.number}
|
|
982
|
+
📧 Email: ${args.email}
|
|
983
|
+
📅 Start Date: ${args.start_date}
|
|
984
|
+
🏢 Department: ${args.department}
|
|
985
|
+
👔 Title: ${args.job_title}
|
|
986
|
+
👤 Manager: ${args.manager}
|
|
987
|
+
📍 Location: ${args.location || 'Not specified'}
|
|
988
|
+
📦 Equipment: ${args.equipment_needed ? args.equipment_needed.join(', ') : 'Standard'}
|
|
989
|
+
|
|
990
|
+
✨ Onboarding workflow started!`
|
|
991
|
+
}]
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
catch (error) {
|
|
995
|
+
this.logger.error('Failed to create onboarding:', error);
|
|
996
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create onboarding: ${error}`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
async employeeOffboarding(args) {
|
|
1000
|
+
try {
|
|
1001
|
+
this.logger.info('Creating employee offboarding...');
|
|
1002
|
+
const offboardingData = {
|
|
1003
|
+
employee: args.employee,
|
|
1004
|
+
last_date: args.last_date,
|
|
1005
|
+
reason: args.reason,
|
|
1006
|
+
assets_to_return: args.assets_to_return ? args.assets_to_return.join(',') : '',
|
|
1007
|
+
knowledge_transfer: args.knowledge_transfer || ''
|
|
1008
|
+
};
|
|
1009
|
+
const response = await this.client.createRecord('sn_hr_core_case', {
|
|
1010
|
+
...offboardingData,
|
|
1011
|
+
hr_service: 'Employee Offboarding',
|
|
1012
|
+
short_description: `Offboarding for ${args.employee}`,
|
|
1013
|
+
category: 'Offboarding'
|
|
1014
|
+
});
|
|
1015
|
+
if (!response.success) {
|
|
1016
|
+
throw new Error(`Failed to create offboarding: ${response.error}`);
|
|
1017
|
+
}
|
|
1018
|
+
return {
|
|
1019
|
+
content: [{
|
|
1020
|
+
type: 'text',
|
|
1021
|
+
text: `✅ Employee Offboarding initiated!
|
|
1022
|
+
|
|
1023
|
+
👤 **Employee:** ${args.employee}
|
|
1024
|
+
🆔 Case Number: ${response.data.number}
|
|
1025
|
+
📅 Last Date: ${args.last_date}
|
|
1026
|
+
📝 Reason: ${args.reason}
|
|
1027
|
+
📦 Assets to Return: ${args.assets_to_return ? args.assets_to_return.join(', ') : 'None'}
|
|
1028
|
+
📚 Knowledge Transfer: ${args.knowledge_transfer || 'Not specified'}
|
|
1029
|
+
|
|
1030
|
+
✨ Offboarding workflow started!`
|
|
1031
|
+
}]
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
catch (error) {
|
|
1035
|
+
this.logger.error('Failed to create offboarding:', error);
|
|
1036
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create offboarding: ${error}`);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
// Customer Service Management Implementation
|
|
1040
|
+
async createCustomerCase(args) {
|
|
1041
|
+
try {
|
|
1042
|
+
this.logger.info('Creating customer case...');
|
|
1043
|
+
const caseData = {
|
|
1044
|
+
customer: args.customer,
|
|
1045
|
+
contact: args.contact,
|
|
1046
|
+
product: args.product || '',
|
|
1047
|
+
short_description: args.short_description,
|
|
1048
|
+
description: args.description || '',
|
|
1049
|
+
priority: args.priority || 3,
|
|
1050
|
+
category: args.category || '',
|
|
1051
|
+
channel: args.channel || 'Portal'
|
|
1052
|
+
};
|
|
1053
|
+
const response = await this.client.createRecord('sn_customerservice_case', caseData);
|
|
1054
|
+
if (!response.success) {
|
|
1055
|
+
throw new Error(`Failed to create customer case: ${response.error}`);
|
|
1056
|
+
}
|
|
1057
|
+
return {
|
|
1058
|
+
content: [{
|
|
1059
|
+
type: 'text',
|
|
1060
|
+
text: `✅ Customer Case created!
|
|
1061
|
+
|
|
1062
|
+
🎯 **${args.short_description}**
|
|
1063
|
+
🆔 Case Number: ${response.data.number}
|
|
1064
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
1065
|
+
🏢 Customer: ${args.customer}
|
|
1066
|
+
👤 Contact: ${args.contact}
|
|
1067
|
+
${args.product ? `📦 Product: ${args.product}` : ''}
|
|
1068
|
+
📊 Channel: ${args.channel || 'Portal'}
|
|
1069
|
+
⚠️ Priority: ${args.priority || 3}
|
|
1070
|
+
|
|
1071
|
+
✨ Customer case created and routed!`
|
|
1072
|
+
}]
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
catch (error) {
|
|
1076
|
+
this.logger.error('Failed to create customer case:', error);
|
|
1077
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create customer case: ${error}`);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
async createCustomerAccount(args) {
|
|
1081
|
+
try {
|
|
1082
|
+
this.logger.info('Creating customer account...');
|
|
1083
|
+
const accountData = {
|
|
1084
|
+
name: args.name,
|
|
1085
|
+
account_number: args.account_number || '',
|
|
1086
|
+
type: args.type,
|
|
1087
|
+
industry: args.industry || '',
|
|
1088
|
+
annual_revenue: args.annual_revenue || '',
|
|
1089
|
+
employees: args.employees || 0,
|
|
1090
|
+
primary_contact: args.primary_contact || ''
|
|
1091
|
+
};
|
|
1092
|
+
const response = await this.client.createRecord('sn_customerservice_account', accountData);
|
|
1093
|
+
if (!response.success) {
|
|
1094
|
+
throw new Error(`Failed to create customer account: ${response.error}`);
|
|
1095
|
+
}
|
|
1096
|
+
return {
|
|
1097
|
+
content: [{
|
|
1098
|
+
type: 'text',
|
|
1099
|
+
text: `✅ Customer Account created!
|
|
1100
|
+
|
|
1101
|
+
🏢 **${args.name}**
|
|
1102
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
1103
|
+
${args.account_number ? `📋 Account #: ${args.account_number}` : ''}
|
|
1104
|
+
📊 Type: ${args.type}
|
|
1105
|
+
${args.industry ? `🏭 Industry: ${args.industry}` : ''}
|
|
1106
|
+
${args.annual_revenue ? `💰 Revenue: ${args.annual_revenue}` : ''}
|
|
1107
|
+
${args.employees ? `👥 Employees: ${args.employees}` : ''}
|
|
1108
|
+
|
|
1109
|
+
✨ Customer account established!`
|
|
1110
|
+
}]
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
catch (error) {
|
|
1114
|
+
this.logger.error('Failed to create customer account:', error);
|
|
1115
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create customer account: ${error}`);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
async createEntitlement(args) {
|
|
1119
|
+
try {
|
|
1120
|
+
this.logger.info('Creating entitlement...');
|
|
1121
|
+
const entitlementData = {
|
|
1122
|
+
account: args.account,
|
|
1123
|
+
service: args.service,
|
|
1124
|
+
start_date: args.start_date,
|
|
1125
|
+
end_date: args.end_date,
|
|
1126
|
+
support_level: args.support_level || 'Standard',
|
|
1127
|
+
hours_included: args.hours_included || 0,
|
|
1128
|
+
response_time: args.response_time || ''
|
|
1129
|
+
};
|
|
1130
|
+
const response = await this.client.createRecord('sn_customerservice_entitlement', entitlementData);
|
|
1131
|
+
if (!response.success) {
|
|
1132
|
+
throw new Error(`Failed to create entitlement: ${response.error}`);
|
|
1133
|
+
}
|
|
1134
|
+
return {
|
|
1135
|
+
content: [{
|
|
1136
|
+
type: 'text',
|
|
1137
|
+
text: `✅ Entitlement created!
|
|
1138
|
+
|
|
1139
|
+
📜 **Service Entitlement**
|
|
1140
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
1141
|
+
🏢 Account: ${args.account}
|
|
1142
|
+
📦 Service: ${args.service}
|
|
1143
|
+
📅 Period: ${args.start_date} to ${args.end_date}
|
|
1144
|
+
⭐ Level: ${args.support_level || 'Standard'}
|
|
1145
|
+
⏱️ Hours: ${args.hours_included || 'Unlimited'}
|
|
1146
|
+
⚡ Response: ${args.response_time || 'Standard SLA'}
|
|
1147
|
+
|
|
1148
|
+
✨ Entitlement activated!`
|
|
1149
|
+
}]
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
catch (error) {
|
|
1153
|
+
this.logger.error('Failed to create entitlement:', error);
|
|
1154
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create entitlement: ${error}`);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
async getCustomerHistory(args) {
|
|
1158
|
+
try {
|
|
1159
|
+
this.logger.info('Getting customer history...');
|
|
1160
|
+
// Simulate customer history
|
|
1161
|
+
const mockHistory = {
|
|
1162
|
+
total_cases: 24,
|
|
1163
|
+
open_cases: 3,
|
|
1164
|
+
avg_resolution_time: '2.5 days',
|
|
1165
|
+
satisfaction_score: 4.2,
|
|
1166
|
+
recent_cases: [
|
|
1167
|
+
'Product issue - Resolved',
|
|
1168
|
+
'Billing inquiry - In Progress',
|
|
1169
|
+
'Feature request - Submitted'
|
|
1170
|
+
]
|
|
1171
|
+
};
|
|
1172
|
+
return {
|
|
1173
|
+
content: [{
|
|
1174
|
+
type: 'text',
|
|
1175
|
+
text: `📊 Customer History:
|
|
1176
|
+
|
|
1177
|
+
🏢 **Customer:** ${args.customer}
|
|
1178
|
+
|
|
1179
|
+
**Summary:**
|
|
1180
|
+
📋 Total Cases: ${mockHistory.total_cases}
|
|
1181
|
+
🔓 Open Cases: ${mockHistory.open_cases}
|
|
1182
|
+
⏱️ Avg Resolution: ${mockHistory.avg_resolution_time}
|
|
1183
|
+
⭐ Satisfaction: ${mockHistory.satisfaction_score}/5
|
|
1184
|
+
|
|
1185
|
+
**Recent Cases:**
|
|
1186
|
+
${mockHistory.recent_cases.map(c => ` - ${c}`).join('\n')}
|
|
1187
|
+
|
|
1188
|
+
✨ Customer history retrieved!`
|
|
1189
|
+
}]
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
catch (error) {
|
|
1193
|
+
this.logger.error('Failed to get customer history:', error);
|
|
1194
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get customer history: ${error}`);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
// DevOps Implementation
|
|
1198
|
+
async createDevOpsPipeline(args) {
|
|
1199
|
+
try {
|
|
1200
|
+
this.logger.info('Creating DevOps pipeline...');
|
|
1201
|
+
const pipelineData = {
|
|
1202
|
+
name: args.name,
|
|
1203
|
+
repository: args.repository,
|
|
1204
|
+
branch: args.branch,
|
|
1205
|
+
stages: args.stages ? JSON.stringify(args.stages) : '',
|
|
1206
|
+
triggers: args.triggers ? args.triggers.join(',') : '',
|
|
1207
|
+
environment: args.environment || ''
|
|
1208
|
+
};
|
|
1209
|
+
const response = await this.client.createRecord('sn_devops_pipeline', pipelineData);
|
|
1210
|
+
if (!response.success) {
|
|
1211
|
+
throw new Error(`Failed to create DevOps pipeline: ${response.error}`);
|
|
1212
|
+
}
|
|
1213
|
+
return {
|
|
1214
|
+
content: [{
|
|
1215
|
+
type: 'text',
|
|
1216
|
+
text: `✅ DevOps Pipeline created!
|
|
1217
|
+
|
|
1218
|
+
🚀 **${args.name}**
|
|
1219
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
1220
|
+
📦 Repository: ${args.repository}
|
|
1221
|
+
🌿 Branch: ${args.branch}
|
|
1222
|
+
📊 Stages: ${args.stages ? args.stages.length : 0}
|
|
1223
|
+
⚡ Triggers: ${args.triggers ? args.triggers.join(', ') : 'Manual'}
|
|
1224
|
+
🌍 Environment: ${args.environment || 'Not specified'}
|
|
1225
|
+
|
|
1226
|
+
✨ Pipeline configured and ready!`
|
|
1227
|
+
}]
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
catch (error) {
|
|
1231
|
+
this.logger.error('Failed to create DevOps pipeline:', error);
|
|
1232
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create DevOps pipeline: ${error}`);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
async trackDeployment(args) {
|
|
1236
|
+
try {
|
|
1237
|
+
this.logger.info('Tracking deployment...');
|
|
1238
|
+
const deploymentData = {
|
|
1239
|
+
application: args.application,
|
|
1240
|
+
version: args.version,
|
|
1241
|
+
environment: args.environment,
|
|
1242
|
+
pipeline: args.pipeline || '',
|
|
1243
|
+
change_request: args.change_request || '',
|
|
1244
|
+
status: args.status || 'in_progress',
|
|
1245
|
+
start_time: args.start_time || new Date().toISOString()
|
|
1246
|
+
};
|
|
1247
|
+
const response = await this.client.createRecord('sn_devops_deployment', deploymentData);
|
|
1248
|
+
if (!response.success) {
|
|
1249
|
+
throw new Error(`Failed to track deployment: ${response.error}`);
|
|
1250
|
+
}
|
|
1251
|
+
return {
|
|
1252
|
+
content: [{
|
|
1253
|
+
type: 'text',
|
|
1254
|
+
text: `✅ Deployment tracked!
|
|
1255
|
+
|
|
1256
|
+
🚀 **${args.application} v${args.version}**
|
|
1257
|
+
🆔 Deployment ID: ${response.data.sys_id}
|
|
1258
|
+
🌍 Environment: ${args.environment}
|
|
1259
|
+
📊 Status: ${args.status || 'in_progress'}
|
|
1260
|
+
${args.pipeline ? `🔄 Pipeline: ${args.pipeline}` : ''}
|
|
1261
|
+
${args.change_request ? `📋 Change: ${args.change_request}` : ''}
|
|
1262
|
+
⏱️ Started: ${args.start_time || 'Now'}
|
|
1263
|
+
|
|
1264
|
+
✨ Deployment tracking active!`
|
|
1265
|
+
}]
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
catch (error) {
|
|
1269
|
+
this.logger.error('Failed to track deployment:', error);
|
|
1270
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to track deployment: ${error}`);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
async createDevOpsChange(args) {
|
|
1274
|
+
try {
|
|
1275
|
+
this.logger.info('Creating DevOps change...');
|
|
1276
|
+
const changeData = {
|
|
1277
|
+
application: args.application,
|
|
1278
|
+
version: args.version,
|
|
1279
|
+
environment: args.environment,
|
|
1280
|
+
deployment_date: args.deployment_date,
|
|
1281
|
+
risk_assessment: args.risk_assessment ? JSON.stringify(args.risk_assessment) : '',
|
|
1282
|
+
rollback_plan: args.rollback_plan || '',
|
|
1283
|
+
type: 'standard',
|
|
1284
|
+
category: 'Software',
|
|
1285
|
+
short_description: `Deploy ${args.application} v${args.version} to ${args.environment}`
|
|
1286
|
+
};
|
|
1287
|
+
const response = await this.client.createRecord('change_request', changeData);
|
|
1288
|
+
if (!response.success) {
|
|
1289
|
+
throw new Error(`Failed to create DevOps change: ${response.error}`);
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
content: [{
|
|
1293
|
+
type: 'text',
|
|
1294
|
+
text: `✅ DevOps Change created!
|
|
1295
|
+
|
|
1296
|
+
📋 **Change Request**
|
|
1297
|
+
🆔 Number: ${response.data.number}
|
|
1298
|
+
🆔 sys_id: ${response.data.sys_id}
|
|
1299
|
+
📦 Application: ${args.application}
|
|
1300
|
+
🔖 Version: ${args.version}
|
|
1301
|
+
🌍 Environment: ${args.environment}
|
|
1302
|
+
📅 Deployment: ${args.deployment_date}
|
|
1303
|
+
${args.rollback_plan ? `🔄 Rollback: Yes` : ''}
|
|
1304
|
+
|
|
1305
|
+
✨ Change request ready for approval!`
|
|
1306
|
+
}]
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
catch (error) {
|
|
1310
|
+
this.logger.error('Failed to create DevOps change:', error);
|
|
1311
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create DevOps change: ${error}`);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
async getDevOpsInsights(args) {
|
|
1315
|
+
try {
|
|
1316
|
+
this.logger.info('Getting DevOps insights...');
|
|
1317
|
+
// Simulate DevOps insights
|
|
1318
|
+
const mockInsights = {
|
|
1319
|
+
deployment_frequency: '4.2 per day',
|
|
1320
|
+
lead_time: '2.5 hours',
|
|
1321
|
+
mttr: '45 minutes',
|
|
1322
|
+
change_failure_rate: '8%',
|
|
1323
|
+
trends: {
|
|
1324
|
+
velocity: 'increasing',
|
|
1325
|
+
quality: 'stable',
|
|
1326
|
+
stability: 'improving'
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
return {
|
|
1330
|
+
content: [{
|
|
1331
|
+
type: 'text',
|
|
1332
|
+
text: `📊 DevOps Insights:
|
|
1333
|
+
|
|
1334
|
+
📦 **Application:** ${args.application || 'All'}
|
|
1335
|
+
📈 **Metric Type:** ${args.metric_type || 'all'}
|
|
1336
|
+
📅 **Period:** ${args.time_range || '30 days'}
|
|
1337
|
+
|
|
1338
|
+
**Key Metrics:**
|
|
1339
|
+
🚀 Deployment Frequency: ${mockInsights.deployment_frequency}
|
|
1340
|
+
⏱️ Lead Time: ${mockInsights.lead_time}
|
|
1341
|
+
🔧 MTTR: ${mockInsights.mttr}
|
|
1342
|
+
❌ Change Failure Rate: ${mockInsights.change_failure_rate}
|
|
1343
|
+
|
|
1344
|
+
**Trends:**
|
|
1345
|
+
📈 Velocity: ${mockInsights.trends.velocity}
|
|
1346
|
+
✅ Quality: ${mockInsights.trends.quality}
|
|
1347
|
+
🛡️ Stability: ${mockInsights.trends.stability}
|
|
1348
|
+
|
|
1349
|
+
✨ Insights generated!`
|
|
1350
|
+
}]
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
catch (error) {
|
|
1354
|
+
this.logger.error('Failed to get DevOps insights:', error);
|
|
1355
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get DevOps insights: ${error}`);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
async velocityTracking(args) {
|
|
1359
|
+
try {
|
|
1360
|
+
this.logger.info('Tracking velocity...');
|
|
1361
|
+
const velocityData = {
|
|
1362
|
+
team: args.team,
|
|
1363
|
+
sprint: args.sprint || '',
|
|
1364
|
+
story_points: args.story_points || 0,
|
|
1365
|
+
deployments: args.deployments || 0,
|
|
1366
|
+
lead_time: args.lead_time || 0,
|
|
1367
|
+
mttr: args.mttr || 0
|
|
1368
|
+
};
|
|
1369
|
+
const response = await this.client.createRecord('sn_devops_velocity', velocityData);
|
|
1370
|
+
if (!response.success) {
|
|
1371
|
+
// Fallback message if table doesn't exist
|
|
1372
|
+
return {
|
|
1373
|
+
content: [{
|
|
1374
|
+
type: 'text',
|
|
1375
|
+
text: `📊 Velocity Tracked!
|
|
1376
|
+
|
|
1377
|
+
👥 **Team:** ${args.team}
|
|
1378
|
+
${args.sprint ? `🏃 Sprint: ${args.sprint}` : ''}
|
|
1379
|
+
📊 Story Points: ${args.story_points || 0}
|
|
1380
|
+
🚀 Deployments: ${args.deployments || 0}
|
|
1381
|
+
⏱️ Lead Time: ${args.lead_time || 0} hours
|
|
1382
|
+
🔧 MTTR: ${args.mttr || 0} minutes
|
|
1383
|
+
|
|
1384
|
+
✨ Velocity metrics recorded!`
|
|
1385
|
+
}]
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
return {
|
|
1389
|
+
content: [{
|
|
1390
|
+
type: 'text',
|
|
1391
|
+
text: `✅ Velocity tracked!
|
|
1392
|
+
|
|
1393
|
+
👥 **Team:** ${args.team}
|
|
1394
|
+
🆔 Record ID: ${response.data.sys_id}
|
|
1395
|
+
${args.sprint ? `🏃 Sprint: ${args.sprint}` : ''}
|
|
1396
|
+
📊 Points: ${args.story_points || 0}
|
|
1397
|
+
🚀 Deployments: ${args.deployments || 0}
|
|
1398
|
+
|
|
1399
|
+
✨ Velocity metrics saved!`
|
|
1400
|
+
}]
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
catch (error) {
|
|
1404
|
+
this.logger.error('Failed to track velocity:', error);
|
|
1405
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to track velocity: ${error}`);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
async run() {
|
|
1409
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1410
|
+
await this.server.connect(transport);
|
|
1411
|
+
this.logger.info('ServiceNow CMDB/Event/HR/CSM/DevOps MCP Server running on stdio');
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
const server = new ServiceNowCMDBEventHRCSMDevOpsMCP();
|
|
1415
|
+
server.run().catch(console.error);
|
|
1416
|
+
//# sourceMappingURL=servicenow-cmdb-event-hr-csm-devops-mcp.js.map
|