snow-flow 2.0.2 → 2.0.3
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/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +6 -0
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,728 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ServiceNow MCP Server
|
|
4
|
-
* Provides Claude Code with direct access to ServiceNow APIs via MCP protocol
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
-
import {
|
|
10
|
-
CallToolRequestSchema,
|
|
11
|
-
ListToolsRequestSchema,
|
|
12
|
-
Tool,
|
|
13
|
-
CallToolResult,
|
|
14
|
-
TextContent,
|
|
15
|
-
ImageContent,
|
|
16
|
-
EmbeddedResource
|
|
17
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
18
|
-
import { ServiceNowClient } from '../utils/servicenow-client.js';
|
|
19
|
-
import { ServiceNowOAuth } from '../utils/snow-oauth.js';
|
|
20
|
-
|
|
21
|
-
interface ServiceNowMCPConfig {
|
|
22
|
-
name: string;
|
|
23
|
-
version: string;
|
|
24
|
-
oauth?: {
|
|
25
|
-
instance: string;
|
|
26
|
-
clientId: string;
|
|
27
|
-
clientSecret: string;
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
class ServiceNowMCPServer {
|
|
32
|
-
private server: Server;
|
|
33
|
-
private snowClient: ServiceNowClient;
|
|
34
|
-
private oauth: ServiceNowOAuth;
|
|
35
|
-
private config: ServiceNowMCPConfig;
|
|
36
|
-
private isAuthenticated: boolean = false;
|
|
37
|
-
|
|
38
|
-
constructor(config: ServiceNowMCPConfig) {
|
|
39
|
-
this.config = config;
|
|
40
|
-
this.oauth = new ServiceNowOAuth();
|
|
41
|
-
this.snowClient = new ServiceNowClient();
|
|
42
|
-
|
|
43
|
-
this.server = new Server(
|
|
44
|
-
{
|
|
45
|
-
name: config.name,
|
|
46
|
-
version: config.version,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
capabilities: {
|
|
50
|
-
tools: {}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
this.setupToolHandlers();
|
|
56
|
-
this.setupRequestHandlers();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private async checkAuthentication(): Promise<boolean> {
|
|
60
|
-
try {
|
|
61
|
-
this.isAuthenticated = await this.oauth.isAuthenticated();
|
|
62
|
-
return this.isAuthenticated;
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.error('Authentication check failed:', error);
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private setupRequestHandlers(): void {
|
|
70
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
71
|
-
const isAuth = await this.checkAuthentication();
|
|
72
|
-
|
|
73
|
-
const tools: Tool[] = [
|
|
74
|
-
{
|
|
75
|
-
name: "snow_auth_status",
|
|
76
|
-
description: "Check ServiceNow authentication status",
|
|
77
|
-
inputSchema: {
|
|
78
|
-
type: "object",
|
|
79
|
-
properties: {},
|
|
80
|
-
required: []
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
];
|
|
84
|
-
|
|
85
|
-
if (isAuth) {
|
|
86
|
-
tools.push(
|
|
87
|
-
{
|
|
88
|
-
name: "snow_create_widget",
|
|
89
|
-
description: "Create a new ServiceNow Service Portal widget",
|
|
90
|
-
inputSchema: {
|
|
91
|
-
type: "object",
|
|
92
|
-
properties: {
|
|
93
|
-
name: {
|
|
94
|
-
type: "string",
|
|
95
|
-
description: "Widget name"
|
|
96
|
-
},
|
|
97
|
-
id: {
|
|
98
|
-
type: "string",
|
|
99
|
-
description: "Widget ID (unique identifier)"
|
|
100
|
-
},
|
|
101
|
-
title: {
|
|
102
|
-
type: "string",
|
|
103
|
-
description: "Widget display title"
|
|
104
|
-
},
|
|
105
|
-
description: {
|
|
106
|
-
type: "string",
|
|
107
|
-
description: "Widget description"
|
|
108
|
-
},
|
|
109
|
-
template: {
|
|
110
|
-
type: "string",
|
|
111
|
-
description: "HTML template for the widget"
|
|
112
|
-
},
|
|
113
|
-
css: {
|
|
114
|
-
type: "string",
|
|
115
|
-
description: "CSS styling for the widget"
|
|
116
|
-
},
|
|
117
|
-
client_script: {
|
|
118
|
-
type: "string",
|
|
119
|
-
description: "Client-side AngularJS script"
|
|
120
|
-
},
|
|
121
|
-
server_script: {
|
|
122
|
-
type: "string",
|
|
123
|
-
description: "Server-side script"
|
|
124
|
-
},
|
|
125
|
-
category: {
|
|
126
|
-
type: "string",
|
|
127
|
-
description: "Widget category (e.g., 'incident', 'custom')"
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
required: ["name", "id", "title", "description", "template", "css", "client_script", "server_script"]
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
name: "snow_update_widget",
|
|
135
|
-
description: "Update an existing ServiceNow widget",
|
|
136
|
-
inputSchema: {
|
|
137
|
-
type: "object",
|
|
138
|
-
properties: {
|
|
139
|
-
sys_id: {
|
|
140
|
-
type: "string",
|
|
141
|
-
description: "System ID of the widget to update"
|
|
142
|
-
},
|
|
143
|
-
updates: {
|
|
144
|
-
type: "object",
|
|
145
|
-
description: "Object containing fields to update",
|
|
146
|
-
properties: {
|
|
147
|
-
name: { type: "string" },
|
|
148
|
-
title: { type: "string" },
|
|
149
|
-
description: { type: "string" },
|
|
150
|
-
template: { type: "string" },
|
|
151
|
-
css: { type: "string" },
|
|
152
|
-
client_script: { type: "string" },
|
|
153
|
-
server_script: { type: "string" }
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
required: ["sys_id", "updates"]
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
name: "snow_get_widget",
|
|
162
|
-
description: "Get details of a ServiceNow widget by ID",
|
|
163
|
-
inputSchema: {
|
|
164
|
-
type: "object",
|
|
165
|
-
properties: {
|
|
166
|
-
widget_id: {
|
|
167
|
-
type: "string",
|
|
168
|
-
description: "Widget ID to retrieve"
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
required: ["widget_id"]
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
name: "snow_list_widgets",
|
|
176
|
-
description: "List all ServiceNow widgets",
|
|
177
|
-
inputSchema: {
|
|
178
|
-
type: "object",
|
|
179
|
-
properties: {
|
|
180
|
-
limit: {
|
|
181
|
-
type: "number",
|
|
182
|
-
description: "Maximum number of widgets to return (default: 50)"
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
required: []
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
name: "snow_create_workflow",
|
|
190
|
-
description: "Create a new ServiceNow workflow",
|
|
191
|
-
inputSchema: {
|
|
192
|
-
type: "object",
|
|
193
|
-
properties: {
|
|
194
|
-
name: {
|
|
195
|
-
type: "string",
|
|
196
|
-
description: "Workflow name"
|
|
197
|
-
},
|
|
198
|
-
description: {
|
|
199
|
-
type: "string",
|
|
200
|
-
description: "Workflow description"
|
|
201
|
-
},
|
|
202
|
-
active: {
|
|
203
|
-
type: "boolean",
|
|
204
|
-
description: "Whether workflow is active"
|
|
205
|
-
},
|
|
206
|
-
workflow_version: {
|
|
207
|
-
type: "string",
|
|
208
|
-
description: "Workflow version"
|
|
209
|
-
},
|
|
210
|
-
table: {
|
|
211
|
-
type: "string",
|
|
212
|
-
description: "Table this workflow applies to"
|
|
213
|
-
},
|
|
214
|
-
condition: {
|
|
215
|
-
type: "string",
|
|
216
|
-
description: "Workflow activation condition"
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
required: ["name", "description", "active", "workflow_version"]
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
name: "snow_execute_script",
|
|
224
|
-
description: "Execute a server-side script in ServiceNow",
|
|
225
|
-
inputSchema: {
|
|
226
|
-
type: "object",
|
|
227
|
-
properties: {
|
|
228
|
-
script: {
|
|
229
|
-
type: "string",
|
|
230
|
-
description: "JavaScript code to execute"
|
|
231
|
-
},
|
|
232
|
-
description: {
|
|
233
|
-
type: "string",
|
|
234
|
-
description: "Description of what the script does"
|
|
235
|
-
}
|
|
236
|
-
},
|
|
237
|
-
required: ["script"]
|
|
238
|
-
}
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
name: "snow_test_connection",
|
|
242
|
-
description: "Test connection to ServiceNow and get current user info",
|
|
243
|
-
inputSchema: {
|
|
244
|
-
type: "object",
|
|
245
|
-
properties: {},
|
|
246
|
-
required: []
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
name: "snow_get_instance_info",
|
|
251
|
-
description: "Get ServiceNow instance information",
|
|
252
|
-
inputSchema: {
|
|
253
|
-
type: "object",
|
|
254
|
-
properties: {},
|
|
255
|
-
required: []
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return { tools };
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
private setupToolHandlers(): void {
|
|
266
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
267
|
-
const { name, arguments: args } = request.params;
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
switch (name) {
|
|
271
|
-
case "snow_auth_status":
|
|
272
|
-
return await this.handleAuthStatus();
|
|
273
|
-
|
|
274
|
-
case "snow_create_widget":
|
|
275
|
-
return await this.handleCreateWidget(args);
|
|
276
|
-
|
|
277
|
-
case "snow_update_widget":
|
|
278
|
-
return await this.handleUpdateWidget(args);
|
|
279
|
-
|
|
280
|
-
case "snow_get_widget":
|
|
281
|
-
return await this.handleGetWidget(args);
|
|
282
|
-
|
|
283
|
-
case "snow_list_widgets":
|
|
284
|
-
return await this.handleListWidgets(args);
|
|
285
|
-
|
|
286
|
-
case "snow_create_workflow":
|
|
287
|
-
return await this.handleCreateWorkflow(args);
|
|
288
|
-
|
|
289
|
-
case "snow_execute_script":
|
|
290
|
-
return await this.handleExecuteScript(args);
|
|
291
|
-
|
|
292
|
-
case "snow_test_connection":
|
|
293
|
-
return await this.handleTestConnection();
|
|
294
|
-
|
|
295
|
-
case "snow_get_instance_info":
|
|
296
|
-
return await this.handleGetInstanceInfo();
|
|
297
|
-
|
|
298
|
-
default:
|
|
299
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
300
|
-
}
|
|
301
|
-
} catch (error) {
|
|
302
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
303
|
-
return {
|
|
304
|
-
content: [
|
|
305
|
-
{
|
|
306
|
-
type: "text",
|
|
307
|
-
text: `Error executing ${name}: ${errorMessage}`
|
|
308
|
-
} as TextContent
|
|
309
|
-
]
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
private async handleAuthStatus(): Promise<CallToolResult> {
|
|
316
|
-
const isAuth = await this.checkAuthentication();
|
|
317
|
-
const credentials = await this.oauth.loadCredentials();
|
|
318
|
-
|
|
319
|
-
let statusText = "🔐 ServiceNow Authentication Status:\n\n";
|
|
320
|
-
|
|
321
|
-
if (isAuth && credentials) {
|
|
322
|
-
statusText += `✅ Status: Authenticated\n`;
|
|
323
|
-
statusText += `🏢 Instance: ${credentials.instance}\n`;
|
|
324
|
-
statusText += `🔑 Client ID: ${credentials.clientId}\n`;
|
|
325
|
-
statusText += `📅 Expires: ${credentials.expiresAt ? new Date(credentials.expiresAt).toLocaleString() : 'Unknown'}\n`;
|
|
326
|
-
} else {
|
|
327
|
-
statusText += `❌ Status: Not authenticated\n`;
|
|
328
|
-
statusText += `💡 Run "snow-flow auth login" to authenticate\n`;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return {
|
|
332
|
-
content: [
|
|
333
|
-
{
|
|
334
|
-
type: "text",
|
|
335
|
-
text: statusText
|
|
336
|
-
} as TextContent
|
|
337
|
-
]
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
private async handleCreateWidget(args: any): Promise<CallToolResult> {
|
|
342
|
-
if (!await this.checkAuthentication()) {
|
|
343
|
-
return {
|
|
344
|
-
content: [
|
|
345
|
-
{
|
|
346
|
-
type: "text",
|
|
347
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
348
|
-
} as TextContent
|
|
349
|
-
]
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const result = await this.snowClient.createWidget({
|
|
354
|
-
name: args.name,
|
|
355
|
-
id: args.id,
|
|
356
|
-
title: args.title,
|
|
357
|
-
description: args.description,
|
|
358
|
-
template: args.template,
|
|
359
|
-
css: args.css,
|
|
360
|
-
client_script: args.client_script,
|
|
361
|
-
server_script: args.server_script,
|
|
362
|
-
category: args.category || 'custom'
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
if (result.success) {
|
|
366
|
-
const credentials = await this.oauth.loadCredentials();
|
|
367
|
-
const instanceUrl = `https://${credentials?.instance}`;
|
|
368
|
-
const widgetUrl = `${instanceUrl}/sp_config/?id=widget_editor&widget_id=${result.data?.sys_id}`;
|
|
369
|
-
|
|
370
|
-
return {
|
|
371
|
-
content: [
|
|
372
|
-
{
|
|
373
|
-
type: "text",
|
|
374
|
-
text: `✅ Widget created successfully!\n\n` +
|
|
375
|
-
`🆔 Widget ID: ${result.data?.sys_id}\n` +
|
|
376
|
-
`📛 Name: ${result.data?.name}\n` +
|
|
377
|
-
`🔗 Edit Widget: ${widgetUrl}\n` +
|
|
378
|
-
`🌐 Instance: ${instanceUrl}\n\n` +
|
|
379
|
-
`The widget has been created in your ServiceNow instance and is ready for testing!`
|
|
380
|
-
} as TextContent
|
|
381
|
-
]
|
|
382
|
-
};
|
|
383
|
-
} else {
|
|
384
|
-
return {
|
|
385
|
-
content: [
|
|
386
|
-
{
|
|
387
|
-
type: "text",
|
|
388
|
-
text: `❌ Failed to create widget: ${result.error}`
|
|
389
|
-
} as TextContent
|
|
390
|
-
]
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
private async handleUpdateWidget(args: any): Promise<CallToolResult> {
|
|
396
|
-
if (!await this.checkAuthentication()) {
|
|
397
|
-
return {
|
|
398
|
-
content: [
|
|
399
|
-
{
|
|
400
|
-
type: "text",
|
|
401
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
402
|
-
} as TextContent
|
|
403
|
-
]
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
const result = await this.snowClient.updateWidget(args.sys_id, args.updates);
|
|
408
|
-
|
|
409
|
-
if (result.success) {
|
|
410
|
-
const credentials = await this.oauth.loadCredentials();
|
|
411
|
-
const instanceUrl = `https://${credentials?.instance}`;
|
|
412
|
-
const widgetUrl = `${instanceUrl}/sp_config/?id=widget_editor&widget_id=${args.sys_id}`;
|
|
413
|
-
|
|
414
|
-
return {
|
|
415
|
-
content: [
|
|
416
|
-
{
|
|
417
|
-
type: "text",
|
|
418
|
-
text: `✅ Widget updated successfully!\n\n` +
|
|
419
|
-
`🆔 Widget ID: ${args.sys_id}\n` +
|
|
420
|
-
`🔗 Edit Widget: ${widgetUrl}\n` +
|
|
421
|
-
`🌐 Instance: ${instanceUrl}\n\n` +
|
|
422
|
-
`The widget has been updated in your ServiceNow instance!`
|
|
423
|
-
} as TextContent
|
|
424
|
-
]
|
|
425
|
-
};
|
|
426
|
-
} else {
|
|
427
|
-
return {
|
|
428
|
-
content: [
|
|
429
|
-
{
|
|
430
|
-
type: "text",
|
|
431
|
-
text: `❌ Failed to update widget: ${result.error}`
|
|
432
|
-
} as TextContent
|
|
433
|
-
]
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
private async handleGetWidget(args: any): Promise<CallToolResult> {
|
|
439
|
-
if (!await this.checkAuthentication()) {
|
|
440
|
-
return {
|
|
441
|
-
content: [
|
|
442
|
-
{
|
|
443
|
-
type: "text",
|
|
444
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
445
|
-
} as TextContent
|
|
446
|
-
]
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
const result = await this.snowClient.getWidget(args.widget_id);
|
|
451
|
-
|
|
452
|
-
if (result.success) {
|
|
453
|
-
return {
|
|
454
|
-
content: [
|
|
455
|
-
{
|
|
456
|
-
type: "text",
|
|
457
|
-
text: `✅ Widget found!\n\n` +
|
|
458
|
-
`🆔 System ID: ${result.data?.sys_id}\n` +
|
|
459
|
-
`📛 Name: ${result.data?.name}\n` +
|
|
460
|
-
`🏷️ ID: ${result.data?.id}\n` +
|
|
461
|
-
`📝 Title: ${result.data?.title}\n` +
|
|
462
|
-
`📄 Description: ${result.data?.description}\n` +
|
|
463
|
-
`🏷️ Category: ${result.data?.category}\n\n` +
|
|
464
|
-
`Template:\n${result.data?.template}\n\n` +
|
|
465
|
-
`CSS:\n${result.data?.css}\n\n` +
|
|
466
|
-
`Client Script:\n${result.data?.client_script}\n\n` +
|
|
467
|
-
`Server Script:\n${result.data?.server_script}`
|
|
468
|
-
} as TextContent
|
|
469
|
-
]
|
|
470
|
-
};
|
|
471
|
-
} else {
|
|
472
|
-
return {
|
|
473
|
-
content: [
|
|
474
|
-
{
|
|
475
|
-
type: "text",
|
|
476
|
-
text: `❌ Widget not found: ${result.error}`
|
|
477
|
-
} as TextContent
|
|
478
|
-
]
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
private async handleListWidgets(args: any): Promise<CallToolResult> {
|
|
484
|
-
if (!await this.checkAuthentication()) {
|
|
485
|
-
return {
|
|
486
|
-
content: [
|
|
487
|
-
{
|
|
488
|
-
type: "text",
|
|
489
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
490
|
-
} as TextContent
|
|
491
|
-
]
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const result = await this.snowClient.getWidgets();
|
|
496
|
-
|
|
497
|
-
if (result.success && result.result) {
|
|
498
|
-
const widgets = result.result.slice(0, args.limit || 50);
|
|
499
|
-
|
|
500
|
-
let widgetList = `✅ Found ${widgets.length} widgets:\n\n`;
|
|
501
|
-
widgets.forEach((widget: any, index: number) => {
|
|
502
|
-
widgetList += `${index + 1}. ${widget.name} (${widget.id})\n`;
|
|
503
|
-
widgetList += ` 🆔 System ID: ${widget.sys_id}\n`;
|
|
504
|
-
widgetList += ` 📝 Title: ${widget.title}\n`;
|
|
505
|
-
widgetList += ` 📄 Description: ${widget.description}\n`;
|
|
506
|
-
widgetList += ` 🏷️ Category: ${widget.category}\n\n`;
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
return {
|
|
510
|
-
content: [
|
|
511
|
-
{
|
|
512
|
-
type: "text",
|
|
513
|
-
text: widgetList
|
|
514
|
-
} as TextContent
|
|
515
|
-
]
|
|
516
|
-
};
|
|
517
|
-
} else {
|
|
518
|
-
return {
|
|
519
|
-
content: [
|
|
520
|
-
{
|
|
521
|
-
type: "text",
|
|
522
|
-
text: `❌ Failed to list widgets: ${result.error}`
|
|
523
|
-
} as TextContent
|
|
524
|
-
]
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
private async handleCreateWorkflow(args: any): Promise<CallToolResult> {
|
|
530
|
-
if (!await this.checkAuthentication()) {
|
|
531
|
-
return {
|
|
532
|
-
content: [
|
|
533
|
-
{
|
|
534
|
-
type: "text",
|
|
535
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
536
|
-
} as TextContent
|
|
537
|
-
]
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
const result = await this.snowClient.createWorkflow({
|
|
542
|
-
name: args.name,
|
|
543
|
-
description: args.description,
|
|
544
|
-
active: args.active,
|
|
545
|
-
workflow_version: args.workflow_version,
|
|
546
|
-
table: args.table,
|
|
547
|
-
condition: args.condition
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
if (result.success) {
|
|
551
|
-
const credentials = await this.oauth.loadCredentials();
|
|
552
|
-
const instanceUrl = `https://${credentials?.instance}`;
|
|
553
|
-
|
|
554
|
-
return {
|
|
555
|
-
content: [
|
|
556
|
-
{
|
|
557
|
-
type: "text",
|
|
558
|
-
text: `✅ Workflow created successfully!\n\n` +
|
|
559
|
-
`🆔 Workflow ID: ${result.data?.sys_id}\n` +
|
|
560
|
-
`📛 Name: ${result.data?.name}\n` +
|
|
561
|
-
`🌐 Instance: ${instanceUrl}\n\n` +
|
|
562
|
-
`The workflow has been created in your ServiceNow instance!`
|
|
563
|
-
} as TextContent
|
|
564
|
-
]
|
|
565
|
-
};
|
|
566
|
-
} else {
|
|
567
|
-
return {
|
|
568
|
-
content: [
|
|
569
|
-
{
|
|
570
|
-
type: "text",
|
|
571
|
-
text: `❌ Failed to create workflow: ${result.error}`
|
|
572
|
-
} as TextContent
|
|
573
|
-
]
|
|
574
|
-
};
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
private async handleExecuteScript(args: any): Promise<CallToolResult> {
|
|
579
|
-
if (!await this.checkAuthentication()) {
|
|
580
|
-
return {
|
|
581
|
-
content: [
|
|
582
|
-
{
|
|
583
|
-
type: "text",
|
|
584
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
585
|
-
} as TextContent
|
|
586
|
-
]
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
const result = await this.snowClient.executeScript(args.script);
|
|
591
|
-
|
|
592
|
-
if (result.success) {
|
|
593
|
-
return {
|
|
594
|
-
content: [
|
|
595
|
-
{
|
|
596
|
-
type: "text",
|
|
597
|
-
text: `✅ Script executed successfully!\n\n` +
|
|
598
|
-
`📄 Description: ${args.description || 'No description provided'}\n` +
|
|
599
|
-
`⚡ Script:\n${args.script}\n\n` +
|
|
600
|
-
`📊 Result:\n${JSON.stringify(result.data, null, 2)}`
|
|
601
|
-
} as TextContent
|
|
602
|
-
]
|
|
603
|
-
};
|
|
604
|
-
} else {
|
|
605
|
-
return {
|
|
606
|
-
content: [
|
|
607
|
-
{
|
|
608
|
-
type: "text",
|
|
609
|
-
text: `❌ Failed to execute script: ${result.error}`
|
|
610
|
-
} as TextContent
|
|
611
|
-
]
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
private async handleTestConnection(): Promise<CallToolResult> {
|
|
617
|
-
if (!await this.checkAuthentication()) {
|
|
618
|
-
return {
|
|
619
|
-
content: [
|
|
620
|
-
{
|
|
621
|
-
type: "text",
|
|
622
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
623
|
-
} as TextContent
|
|
624
|
-
]
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
const result = await this.snowClient.testConnection();
|
|
629
|
-
|
|
630
|
-
if (result.success) {
|
|
631
|
-
return {
|
|
632
|
-
content: [
|
|
633
|
-
{
|
|
634
|
-
type: "text",
|
|
635
|
-
text: `✅ Connection test successful!\n\n` +
|
|
636
|
-
`👤 User: ${result.data?.name} (${result.data?.user_name})\n` +
|
|
637
|
-
`📧 Email: ${result.data?.email}\n` +
|
|
638
|
-
`🏢 Company: ${result.data?.company?.display_value || 'N/A'}\n` +
|
|
639
|
-
`🎭 Role: ${result.data?.title || 'N/A'}\n` +
|
|
640
|
-
`📅 Last Login: ${result.data?.last_login_time || 'N/A'}\n\n` +
|
|
641
|
-
`ServiceNow connection is working properly!`
|
|
642
|
-
} as TextContent
|
|
643
|
-
]
|
|
644
|
-
};
|
|
645
|
-
} else {
|
|
646
|
-
return {
|
|
647
|
-
content: [
|
|
648
|
-
{
|
|
649
|
-
type: "text",
|
|
650
|
-
text: `❌ Connection test failed: ${result.error}`
|
|
651
|
-
} as TextContent
|
|
652
|
-
]
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
private async handleGetInstanceInfo(): Promise<CallToolResult> {
|
|
658
|
-
if (!await this.checkAuthentication()) {
|
|
659
|
-
return {
|
|
660
|
-
content: [
|
|
661
|
-
{
|
|
662
|
-
type: "text",
|
|
663
|
-
text: "❌ Not authenticated. Please run 'snow-flow auth login' first."
|
|
664
|
-
} as TextContent
|
|
665
|
-
]
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
const result = await this.snowClient.getInstanceInfo();
|
|
670
|
-
|
|
671
|
-
if (result.success) {
|
|
672
|
-
const credentials = await this.oauth.loadCredentials();
|
|
673
|
-
|
|
674
|
-
return {
|
|
675
|
-
content: [
|
|
676
|
-
{
|
|
677
|
-
type: "text",
|
|
678
|
-
text: `✅ Instance information retrieved!\n\n` +
|
|
679
|
-
`🏢 Instance: ${credentials?.instance}\n` +
|
|
680
|
-
`🌐 URL: https://${credentials?.instance}\n` +
|
|
681
|
-
`📊 Property: ${result.data?.name}\n` +
|
|
682
|
-
`💾 Value: ${result.data?.value}\n\n` +
|
|
683
|
-
`Instance is accessible and responding!`
|
|
684
|
-
} as TextContent
|
|
685
|
-
]
|
|
686
|
-
};
|
|
687
|
-
} else {
|
|
688
|
-
return {
|
|
689
|
-
content: [
|
|
690
|
-
{
|
|
691
|
-
type: "text",
|
|
692
|
-
text: `❌ Failed to get instance info: ${result.error}`
|
|
693
|
-
} as TextContent
|
|
694
|
-
]
|
|
695
|
-
};
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
async run(): Promise<void> {
|
|
700
|
-
const transport = new StdioServerTransport();
|
|
701
|
-
await this.server.connect(transport);
|
|
702
|
-
|
|
703
|
-
// Keep the server running
|
|
704
|
-
await new Promise<void>((resolve) => {
|
|
705
|
-
process.on('SIGINT', () => {
|
|
706
|
-
console.log('\nServiceNow MCP Server shutting down...');
|
|
707
|
-
resolve();
|
|
708
|
-
});
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
// CLI entry point
|
|
714
|
-
async function main(): Promise<void> {
|
|
715
|
-
const config: ServiceNowMCPConfig = {
|
|
716
|
-
name: "servicenow-mcp-server",
|
|
717
|
-
version: "1.0.0"
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
const server = new ServiceNowMCPServer(config);
|
|
721
|
-
await server.run();
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
if (require.main === module) {
|
|
725
|
-
main().catch(console.error);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
export { ServiceNowMCPServer };
|