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,977 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ServiceNow Intelligent MCP Server - Agent-Integrated Version
|
|
4
|
-
* Smart discovery and memory-aware operations for the agent ecosystem
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
-
import {
|
|
9
|
-
CallToolRequestSchema,
|
|
10
|
-
ListToolsRequestSchema,
|
|
11
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
-
import { BaseMCPServer, MCPToolResult } from './shared/base-mcp-server.js';
|
|
13
|
-
import { AgentContext } from './shared/mcp-memory-manager.js';
|
|
14
|
-
import * as crypto from 'crypto';
|
|
15
|
-
|
|
16
|
-
interface SearchResult {
|
|
17
|
-
sys_id: string;
|
|
18
|
-
name: string;
|
|
19
|
-
type: string;
|
|
20
|
-
table: string;
|
|
21
|
-
description?: string;
|
|
22
|
-
relevance_score?: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class ServiceNowIntelligentMCP extends BaseMCPServer {
|
|
26
|
-
private searchCache: Map<string, { results: SearchResult[], timestamp: number }>;
|
|
27
|
-
private cacheTimeout = 5 * 60 * 1000; // 5 minutes
|
|
28
|
-
|
|
29
|
-
constructor() {
|
|
30
|
-
super('servicenow-intelligent', '2.0.0');
|
|
31
|
-
this.searchCache = new Map();
|
|
32
|
-
this.setupHandlers();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private setupHandlers() {
|
|
36
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
37
|
-
tools: [
|
|
38
|
-
{
|
|
39
|
-
name: 'snow_find_artifact',
|
|
40
|
-
description: 'AUTONOMOUS artifact discovery - finds ServiceNow artifacts using natural language, searches memory first, then ServiceNow. NO MANUAL SEARCH NEEDED.',
|
|
41
|
-
inputSchema: {
|
|
42
|
-
type: 'object',
|
|
43
|
-
properties: {
|
|
44
|
-
query: {
|
|
45
|
-
type: 'string',
|
|
46
|
-
description: 'Natural language query (e.g., "the widget that shows incidents on homepage")'
|
|
47
|
-
},
|
|
48
|
-
type: {
|
|
49
|
-
type: 'string',
|
|
50
|
-
enum: ['widget', 'flow', 'script', 'application', 'any'],
|
|
51
|
-
description: 'Artifact type filter'
|
|
52
|
-
},
|
|
53
|
-
// Agent context
|
|
54
|
-
session_id: { type: 'string', description: 'Agent session ID' },
|
|
55
|
-
agent_id: { type: 'string', description: 'Searching agent ID' },
|
|
56
|
-
agent_type: { type: 'string', description: 'Type of agent' },
|
|
57
|
-
use_cache: { type: 'boolean', default: true, description: 'Use cached results if available' }
|
|
58
|
-
},
|
|
59
|
-
required: ['query']
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: 'snow_analyze_artifact',
|
|
64
|
-
description: 'AUTONOMOUS deep _analysis - intelligently indexes artifacts for optimal Claude understanding, stores in memory for future use. SELF-LEARNING SYSTEM.',
|
|
65
|
-
inputSchema: {
|
|
66
|
-
type: 'object',
|
|
67
|
-
properties: {
|
|
68
|
-
sys_id: { type: 'string', description: 'System ID of the artifact' },
|
|
69
|
-
table: { type: 'string', description: 'ServiceNow table name' },
|
|
70
|
-
session_id: { type: 'string' },
|
|
71
|
-
agent_id: { type: 'string' },
|
|
72
|
-
agent_type: { type: 'string' },
|
|
73
|
-
deep__analysis: { type: 'boolean', default: true, description: 'Perform deep _analysis' }
|
|
74
|
-
},
|
|
75
|
-
required: ['sys_id', 'table']
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: 'snow_memory_search',
|
|
80
|
-
description: 'Search indexed ServiceNow artifacts in memory',
|
|
81
|
-
inputSchema: {
|
|
82
|
-
type: 'object',
|
|
83
|
-
properties: {
|
|
84
|
-
query: { type: 'string', description: 'Search query' },
|
|
85
|
-
type: {
|
|
86
|
-
type: 'string',
|
|
87
|
-
enum: ['widget', 'flow', 'script', 'application'],
|
|
88
|
-
description: 'Artifact type'
|
|
89
|
-
},
|
|
90
|
-
session_id: { type: 'string' },
|
|
91
|
-
agent_id: { type: 'string' }
|
|
92
|
-
},
|
|
93
|
-
required: ['query']
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'snow_comprehensive_search',
|
|
98
|
-
description: 'COMPREHENSIVE multi-table search - searches across all relevant ServiceNow tables for artifacts. Perfect for finding hard-to-locate items.',
|
|
99
|
-
inputSchema: {
|
|
100
|
-
type: 'object',
|
|
101
|
-
properties: {
|
|
102
|
-
query: { type: 'string', description: 'Natural language search query' },
|
|
103
|
-
include_inactive: { type: 'boolean', default: false, description: 'Include inactive records' },
|
|
104
|
-
session_id: { type: 'string' },
|
|
105
|
-
agent_id: { type: 'string' },
|
|
106
|
-
agent_type: { type: 'string' },
|
|
107
|
-
max_results: { type: 'number', default: 50, description: 'Maximum results to return' }
|
|
108
|
-
},
|
|
109
|
-
required: ['query']
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: 'memory_store',
|
|
114
|
-
description: 'Store data in persistent memory for multi-agent coordination',
|
|
115
|
-
inputSchema: {
|
|
116
|
-
type: 'object',
|
|
117
|
-
properties: {
|
|
118
|
-
key: { type: 'string', description: 'Unique key for the data' },
|
|
119
|
-
value: { description: 'Data to store (any JSON-serializable value)' },
|
|
120
|
-
ttl: { type: 'number', description: 'Time to live in milliseconds (optional)' },
|
|
121
|
-
namespace: { type: 'string', description: 'Namespace for organizing data (optional)', default: 'default' }
|
|
122
|
-
},
|
|
123
|
-
required: ['key', 'value']
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
name: 'memory_get',
|
|
128
|
-
description: 'Retrieve data from persistent memory',
|
|
129
|
-
inputSchema: {
|
|
130
|
-
type: 'object',
|
|
131
|
-
properties: {
|
|
132
|
-
key: { type: 'string', description: 'Key to retrieve' },
|
|
133
|
-
namespace: { type: 'string', description: 'Namespace to search in (optional)', default: 'default' }
|
|
134
|
-
},
|
|
135
|
-
required: ['key']
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: 'memory_list',
|
|
140
|
-
description: 'List all keys in memory',
|
|
141
|
-
inputSchema: {
|
|
142
|
-
type: 'object',
|
|
143
|
-
properties: {
|
|
144
|
-
namespace: { type: 'string', description: 'Namespace to list (optional)', default: 'default' },
|
|
145
|
-
pattern: { type: 'string', description: 'Pattern to filter keys (optional)' }
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
name: 'todo_write',
|
|
151
|
-
description: 'Create or update todo items for task coordination',
|
|
152
|
-
inputSchema: {
|
|
153
|
-
type: 'object',
|
|
154
|
-
properties: {
|
|
155
|
-
todos: {
|
|
156
|
-
type: 'array',
|
|
157
|
-
description: 'Array of todo items',
|
|
158
|
-
items: {
|
|
159
|
-
type: 'object',
|
|
160
|
-
properties: {
|
|
161
|
-
id: { type: 'string', description: 'Unique ID for the todo' },
|
|
162
|
-
content: { type: 'string', description: 'Todo description' },
|
|
163
|
-
status: { type: 'string', enum: ['pending', 'in_progress', 'completed'], description: 'Todo status' },
|
|
164
|
-
priority: { type: 'string', enum: ['high', 'medium', 'low'], description: 'Todo priority' }
|
|
165
|
-
},
|
|
166
|
-
required: ['id', 'content', 'status', 'priority']
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
required: ['todos']
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
name: 'todo_read',
|
|
175
|
-
description: 'Read current todo list',
|
|
176
|
-
inputSchema: {
|
|
177
|
-
type: 'object',
|
|
178
|
-
properties: {
|
|
179
|
-
status: { type: 'string', enum: ['all', 'pending', 'in_progress', 'completed'], description: 'Filter by status', default: 'all' }
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
}));
|
|
185
|
-
|
|
186
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
187
|
-
const { name, arguments: args } = request.params;
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
switch (name) {
|
|
191
|
-
case 'snow_find_artifact':
|
|
192
|
-
return await this.findArtifactWithMemory(args);
|
|
193
|
-
case 'snow_analyze_artifact':
|
|
194
|
-
return await this.analyzeArtifactWithMemory(args);
|
|
195
|
-
case 'snow_memory_search':
|
|
196
|
-
return await this.searchMemory(args);
|
|
197
|
-
case 'snow_comprehensive_search':
|
|
198
|
-
return await this.comprehensiveSearch(args);
|
|
199
|
-
case 'memory_store':
|
|
200
|
-
return await this.handleMemoryStore(args);
|
|
201
|
-
case 'memory_get':
|
|
202
|
-
return await this.handleMemoryGet(args);
|
|
203
|
-
case 'memory_list':
|
|
204
|
-
return await this.handleMemoryList(args);
|
|
205
|
-
case 'todo_write':
|
|
206
|
-
return await this.handleTodoWrite(args);
|
|
207
|
-
case 'todo_read':
|
|
208
|
-
return await this.handleTodoRead(args);
|
|
209
|
-
default:
|
|
210
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
211
|
-
}
|
|
212
|
-
} catch (error) {
|
|
213
|
-
return this.createErrorResponse(
|
|
214
|
-
`Tool execution failed: ${name}`,
|
|
215
|
-
error
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Find artifact with memory-first approach
|
|
223
|
-
*/
|
|
224
|
-
private async findArtifactWithMemory(args: any): Promise<MCPToolResult> {
|
|
225
|
-
return await this.executeWithAgentContext(
|
|
226
|
-
'snow_find_artifact',
|
|
227
|
-
args,
|
|
228
|
-
async (context) => {
|
|
229
|
-
const { query, type, use_cache } = args;
|
|
230
|
-
|
|
231
|
-
// Check authentication
|
|
232
|
-
// 🔧 MANDATORY ServiceNow connection validation
|
|
233
|
-
const connectionResult = await this.validateServiceNowConnection();
|
|
234
|
-
if (!connectionResult.success) {
|
|
235
|
-
return this.createAuthenticationError(connectionResult.error);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
this.assertNoMockData('artifact search');
|
|
239
|
-
|
|
240
|
-
// Progress: Starting search
|
|
241
|
-
await this.reportProgress(context, 10, 'Starting artifact search');
|
|
242
|
-
|
|
243
|
-
// Step 1: Check memory first
|
|
244
|
-
const memoryResults = await this.searchMemoryForArtifacts(query, type, context);
|
|
245
|
-
|
|
246
|
-
if (memoryResults.length > 0) {
|
|
247
|
-
await this.reportProgress(context, 30, 'Found artifacts in memory');
|
|
248
|
-
|
|
249
|
-
// Store search in context for other agents
|
|
250
|
-
await this.updateSearchContext(context, query, memoryResults);
|
|
251
|
-
|
|
252
|
-
return this.createSuccessResponse(
|
|
253
|
-
`Found ${memoryResults.length} artifacts in memory`,
|
|
254
|
-
{ results: memoryResults, source: 'memory' }
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Step 2: Check cache if enabled
|
|
259
|
-
if (use_cache) {
|
|
260
|
-
const cachedResults = this.getCachedResults(query, type);
|
|
261
|
-
if (cachedResults) {
|
|
262
|
-
await this.reportProgress(context, 40, 'Using cached results');
|
|
263
|
-
return this.createSuccessResponse(
|
|
264
|
-
`Found ${cachedResults.length} artifacts (cached)`,
|
|
265
|
-
{ results: cachedResults, source: 'cache' }
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Step 3: Search ServiceNow
|
|
271
|
-
await this.reportProgress(context, 50, 'Searching ServiceNow instance');
|
|
272
|
-
|
|
273
|
-
const searchResults = await this.searchServiceNow(query, type, context);
|
|
274
|
-
|
|
275
|
-
// Step 4: Store results in memory and cache
|
|
276
|
-
await this.reportProgress(context, 80, 'Indexing results');
|
|
277
|
-
|
|
278
|
-
for (const result of searchResults) {
|
|
279
|
-
await this.storeArtifact(context, {
|
|
280
|
-
sys_id: result.sys_id,
|
|
281
|
-
type: result.type,
|
|
282
|
-
name: result.name,
|
|
283
|
-
description: result.description
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Cache results
|
|
288
|
-
this.cacheResults(query, type, searchResults);
|
|
289
|
-
|
|
290
|
-
// Update search context
|
|
291
|
-
await this.updateSearchContext(context, query, searchResults);
|
|
292
|
-
|
|
293
|
-
await this.reportProgress(context, 100, 'Search complete');
|
|
294
|
-
|
|
295
|
-
return this.createSuccessResponse(
|
|
296
|
-
`Found ${searchResults.length} artifacts in ServiceNow`,
|
|
297
|
-
{
|
|
298
|
-
results: searchResults,
|
|
299
|
-
source: 'servicenow',
|
|
300
|
-
indexed: true
|
|
301
|
-
}
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Analyze artifact with deep learning
|
|
309
|
-
*/
|
|
310
|
-
private async analyzeArtifactWithMemory(args: any): Promise<MCPToolResult> {
|
|
311
|
-
return await this.executeWithAgentContext(
|
|
312
|
-
'snow_analyze_artifact',
|
|
313
|
-
args,
|
|
314
|
-
async (context) => {
|
|
315
|
-
const { sys_id, table, deep__analysis } = args;
|
|
316
|
-
|
|
317
|
-
// 🔧 MANDATORY ServiceNow connection validation
|
|
318
|
-
const connectionResult = await this.validateServiceNowConnection();
|
|
319
|
-
if (!connectionResult.success) {
|
|
320
|
-
return this.createAuthenticationError(connectionResult.error);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
this.assertNoMockData('artifact _analysis');
|
|
324
|
-
|
|
325
|
-
await this.reportProgress(context, 10, 'Fetching artifact details');
|
|
326
|
-
|
|
327
|
-
// Fetch artifact from ServiceNow
|
|
328
|
-
const artifact = await this.client.getRecord(table, sys_id);
|
|
329
|
-
|
|
330
|
-
if (!artifact.success || !artifact.result) {
|
|
331
|
-
throw new Error(`Artifact ${sys_id} not found in table ${table}`);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
await this.reportProgress(context, 30, 'Analyzing artifact structure');
|
|
335
|
-
|
|
336
|
-
// Perform deep analysis
|
|
337
|
-
const _analysis = await this.performDeepAnalysis(artifact.result, table, deep__analysis);
|
|
338
|
-
|
|
339
|
-
// Store _analysis in memory
|
|
340
|
-
await this.memory.updateSharedContext({
|
|
341
|
-
session_id: context.session_id,
|
|
342
|
-
context_key: `artifact_analysis_${sys_id}`,
|
|
343
|
-
context_value: JSON.stringify(_analysis),
|
|
344
|
-
created_by_agent: context.agent_id
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// Store enhanced artifact info
|
|
348
|
-
await this.storeArtifact(context, {
|
|
349
|
-
sys_id: sys_id,
|
|
350
|
-
type: this.getArtifactType(table),
|
|
351
|
-
name: artifact.result.name || artifact.result.id || sys_id,
|
|
352
|
-
description: artifact.result.description,
|
|
353
|
-
config: _analysis.config
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
await this.reportProgress(context, 70, 'Identifying relationships');
|
|
357
|
-
|
|
358
|
-
// Find related artifacts
|
|
359
|
-
const relationships = await this.findRelationships(artifact.result, table, context);
|
|
360
|
-
|
|
361
|
-
// Notify relevant agents based on artifact type
|
|
362
|
-
if (_analysis.requires_ui_work && this.getArtifactType(table) === 'widget') {
|
|
363
|
-
await this.notifyHandoff(context, 'ui_specialist', {
|
|
364
|
-
type: 'widget',
|
|
365
|
-
sys_id: sys_id,
|
|
366
|
-
next_steps: _analysis.suggested_improvements || []
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
await this.reportProgress(context, 100, 'Analysis complete');
|
|
371
|
-
|
|
372
|
-
return this.createSuccessResponse(
|
|
373
|
-
`Deep _analysis completed for ${artifact.result.name || sys_id}`,
|
|
374
|
-
{
|
|
375
|
-
artifact: {
|
|
376
|
-
sys_id: sys_id,
|
|
377
|
-
name: artifact.result.name,
|
|
378
|
-
type: this.getArtifactType(table),
|
|
379
|
-
table: table
|
|
380
|
-
},
|
|
381
|
-
_analysis: _analysis,
|
|
382
|
-
relationships: relationships,
|
|
383
|
-
indexed: true
|
|
384
|
-
}
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Search memory for artifacts
|
|
392
|
-
*/
|
|
393
|
-
private async searchMemory(args: any): Promise<MCPToolResult> {
|
|
394
|
-
return await this.executeWithAgentContext(
|
|
395
|
-
'snow_memory_search',
|
|
396
|
-
args,
|
|
397
|
-
async (context) => {
|
|
398
|
-
const { query, type } = args;
|
|
399
|
-
|
|
400
|
-
const artifacts = await this.memory.getSessionArtifacts(context.session_id);
|
|
401
|
-
|
|
402
|
-
const results = artifacts.filter(artifact => {
|
|
403
|
-
const matchesType = !type || artifact.artifact_type === type;
|
|
404
|
-
const matchesQuery =
|
|
405
|
-
artifact.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
406
|
-
(artifact.description && artifact.description.toLowerCase().includes(query.toLowerCase()));
|
|
407
|
-
|
|
408
|
-
return matchesType && matchesQuery;
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
return this.createSuccessResponse(
|
|
412
|
-
`Found ${results.length} artifacts in memory`,
|
|
413
|
-
{ results }
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Comprehensive search across all tables
|
|
421
|
-
*/
|
|
422
|
-
private async comprehensiveSearch(args: any): Promise<MCPToolResult> {
|
|
423
|
-
return await this.executeWithAgentContext(
|
|
424
|
-
'snow_comprehensive_search',
|
|
425
|
-
args,
|
|
426
|
-
async (context) => {
|
|
427
|
-
const { query, include_inactive, max_results } = args;
|
|
428
|
-
|
|
429
|
-
// 🔧 MANDATORY ServiceNow connection validation
|
|
430
|
-
const connectionResult = await this.validateServiceNowConnection();
|
|
431
|
-
if (!connectionResult.success) {
|
|
432
|
-
return this.createAuthenticationError(connectionResult.error);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
this.assertNoMockData('comprehensive search');
|
|
436
|
-
|
|
437
|
-
// Define tables to search
|
|
438
|
-
const searchTables = [
|
|
439
|
-
{ table: 'sp_widget', type: 'widget', nameField: 'name' },
|
|
440
|
-
{ table: 'sys_hub_flow', type: 'flow', nameField: 'name' },
|
|
441
|
-
{ table: 'sys_script_include', type: 'script', nameField: 'name' },
|
|
442
|
-
{ table: 'sys_app', type: 'application', nameField: 'name' },
|
|
443
|
-
{ table: 'sc_cat_item', type: 'catalog_item', nameField: 'name' },
|
|
444
|
-
{ table: 'sys_script', type: 'business_rule', nameField: 'name' }
|
|
445
|
-
];
|
|
446
|
-
|
|
447
|
-
const allResults: SearchResult[] = [];
|
|
448
|
-
let tablesSearched = 0;
|
|
449
|
-
|
|
450
|
-
for (const searchConfig of searchTables) {
|
|
451
|
-
await this.reportProgress(
|
|
452
|
-
context,
|
|
453
|
-
10 + (80 * tablesSearched / searchTables.length),
|
|
454
|
-
`Searching ${searchConfig.type} records`
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
try {
|
|
458
|
-
const results = await this.searchTable(
|
|
459
|
-
searchConfig.table,
|
|
460
|
-
searchConfig.nameField,
|
|
461
|
-
query,
|
|
462
|
-
searchConfig.type,
|
|
463
|
-
include_inactive,
|
|
464
|
-
Math.floor(max_results / searchTables.length)
|
|
465
|
-
);
|
|
466
|
-
|
|
467
|
-
allResults.push(...results);
|
|
468
|
-
tablesSearched++;
|
|
469
|
-
|
|
470
|
-
// Store found artifacts
|
|
471
|
-
for (const result of results) {
|
|
472
|
-
await this.storeArtifact(context, {
|
|
473
|
-
sys_id: result.sys_id,
|
|
474
|
-
type: result.type,
|
|
475
|
-
name: result.name,
|
|
476
|
-
description: result.description
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
} catch (error) {
|
|
480
|
-
this.logger.warn(`Failed to search ${searchConfig.table}`, error);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Sort by relevance
|
|
485
|
-
allResults.sort((a, b) => (b.relevance_score || 0) - (a.relevance_score || 0));
|
|
486
|
-
|
|
487
|
-
// Limit results
|
|
488
|
-
const finalResults = allResults.slice(0, max_results);
|
|
489
|
-
|
|
490
|
-
await this.reportProgress(context, 100, 'Search complete');
|
|
491
|
-
|
|
492
|
-
return this.createSuccessResponse(
|
|
493
|
-
`Comprehensive search found ${finalResults.length} artifacts across ${tablesSearched} tables`,
|
|
494
|
-
{
|
|
495
|
-
results: finalResults,
|
|
496
|
-
tables_searched: tablesSearched,
|
|
497
|
-
total_found: allResults.length,
|
|
498
|
-
limited_to: max_results
|
|
499
|
-
}
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// Helper methods
|
|
506
|
-
|
|
507
|
-
private async searchMemoryForArtifacts(
|
|
508
|
-
query: string,
|
|
509
|
-
type: string | undefined,
|
|
510
|
-
context: AgentContext
|
|
511
|
-
): Promise<SearchResult[]> {
|
|
512
|
-
const artifacts = await this.memory.getSessionArtifacts(context.session_id);
|
|
513
|
-
|
|
514
|
-
return artifacts
|
|
515
|
-
.filter(artifact => {
|
|
516
|
-
const matchesType = !type || type === 'any' || artifact.artifact_type === type;
|
|
517
|
-
const queryLower = query.toLowerCase();
|
|
518
|
-
const matchesQuery =
|
|
519
|
-
artifact.name.toLowerCase().includes(queryLower) ||
|
|
520
|
-
(artifact.description && artifact.description.toLowerCase().includes(queryLower));
|
|
521
|
-
|
|
522
|
-
return matchesType && matchesQuery;
|
|
523
|
-
})
|
|
524
|
-
.map(artifact => ({
|
|
525
|
-
sys_id: artifact.sys_id,
|
|
526
|
-
name: artifact.name,
|
|
527
|
-
type: artifact.artifact_type,
|
|
528
|
-
table: this.getTableForType(artifact.artifact_type),
|
|
529
|
-
description: artifact.description,
|
|
530
|
-
relevance_score: this.calculateRelevance(artifact.name, query)
|
|
531
|
-
}));
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
private async searchServiceNow(
|
|
535
|
-
query: string,
|
|
536
|
-
type: string | undefined,
|
|
537
|
-
context: AgentContext
|
|
538
|
-
): Promise<SearchResult[]> {
|
|
539
|
-
const results: SearchResult[] = [];
|
|
540
|
-
|
|
541
|
-
// Determine which tables to search
|
|
542
|
-
const tablesToSearch = type && type !== 'any'
|
|
543
|
-
? [this.getSearchConfigForType(type)]
|
|
544
|
-
: this.getAllSearchConfigs();
|
|
545
|
-
|
|
546
|
-
for (const config of tablesToSearch) {
|
|
547
|
-
try {
|
|
548
|
-
const tableResults = await this.searchTable(
|
|
549
|
-
config.table,
|
|
550
|
-
config.nameField,
|
|
551
|
-
query,
|
|
552
|
-
config.type,
|
|
553
|
-
false,
|
|
554
|
-
10
|
|
555
|
-
);
|
|
556
|
-
results.push(...tableResults);
|
|
557
|
-
} catch (error) {
|
|
558
|
-
this.logger.warn(`Search failed for table ${config.table}`, error);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
return results;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
private async searchTable(
|
|
566
|
-
table: string,
|
|
567
|
-
nameField: string,
|
|
568
|
-
query: string,
|
|
569
|
-
type: string,
|
|
570
|
-
includeInactive: boolean,
|
|
571
|
-
limit: number
|
|
572
|
-
): Promise<SearchResult[]> {
|
|
573
|
-
const encodedQuery = `${nameField}LIKE${query}${includeInactive ? '' : '^active=true'}`;
|
|
574
|
-
|
|
575
|
-
const response = await this.client.getRecords(table, {
|
|
576
|
-
sysparm_query: encodedQuery,
|
|
577
|
-
sysparm_limit: limit,
|
|
578
|
-
sysparm_fields: `sys_id,${nameField},description,active`
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
if (!response.success || !response.result) {
|
|
582
|
-
return [];
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
return response.result.map((record: any) => ({
|
|
586
|
-
sys_id: record.sys_id,
|
|
587
|
-
name: record[nameField] || 'Unnamed',
|
|
588
|
-
type: type,
|
|
589
|
-
table: table,
|
|
590
|
-
description: record.description,
|
|
591
|
-
relevance_score: this.calculateRelevance(record[nameField] || '', query)
|
|
592
|
-
}));
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
private async performDeepAnalysis(
|
|
596
|
-
artifact: any,
|
|
597
|
-
table: string,
|
|
598
|
-
deep: boolean
|
|
599
|
-
): Promise<any> {
|
|
600
|
-
const _analysis: any = {
|
|
601
|
-
structure: {},
|
|
602
|
-
dependencies: [],
|
|
603
|
-
config: {},
|
|
604
|
-
suggested_improvements: []
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
// Analyze based on artifact type
|
|
608
|
-
const artifactType = this.getArtifactType(table);
|
|
609
|
-
|
|
610
|
-
switch (artifactType) {
|
|
611
|
-
case 'widget':
|
|
612
|
-
_analysis.structure = {
|
|
613
|
-
has_template: !!artifact.template,
|
|
614
|
-
has_css: !!artifact.css,
|
|
615
|
-
has_client_script: !!artifact.client_script,
|
|
616
|
-
has_server_script: !!artifact.server_script,
|
|
617
|
-
uses_options: !!artifact.option_schema
|
|
618
|
-
};
|
|
619
|
-
|
|
620
|
-
if (deep) {
|
|
621
|
-
// Check for common patterns
|
|
622
|
-
if (artifact.template && !artifact.template.includes('ng-')) {
|
|
623
|
-
_analysis.suggested_improvements.push('Consider using Angular directives');
|
|
624
|
-
}
|
|
625
|
-
if (!artifact.css || artifact.css.length < 50) {
|
|
626
|
-
_analysis.suggested_improvements.push('Add responsive CSS styling');
|
|
627
|
-
_analysis.requires_ui_work = true;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
_analysis.config = {
|
|
632
|
-
name: artifact.name,
|
|
633
|
-
template_size: artifact.template?.length || 0,
|
|
634
|
-
css_size: artifact.css?.length || 0,
|
|
635
|
-
requires_data: artifact.server_script?.includes('data.') || false
|
|
636
|
-
};
|
|
637
|
-
break;
|
|
638
|
-
|
|
639
|
-
case 'flow':
|
|
640
|
-
_analysis.structure = {
|
|
641
|
-
trigger_type: artifact.trigger_type,
|
|
642
|
-
table: artifact.table_name,
|
|
643
|
-
active: artifact.active,
|
|
644
|
-
has_conditions: !!artifact.condition
|
|
645
|
-
};
|
|
646
|
-
|
|
647
|
-
_analysis.config = {
|
|
648
|
-
name: artifact.name,
|
|
649
|
-
complexity: 'medium' // Would need to analyze flow definition
|
|
650
|
-
};
|
|
651
|
-
break;
|
|
652
|
-
|
|
653
|
-
case 'script':
|
|
654
|
-
_analysis.structure = {
|
|
655
|
-
api_name: artifact.api_name,
|
|
656
|
-
client_callable: artifact.client_callable,
|
|
657
|
-
active: artifact.active
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
if (deep && artifact.script) {
|
|
661
|
-
// Simple dependency detection
|
|
662
|
-
const scriptDeps = [];
|
|
663
|
-
if (artifact.script.includes('GlideRecord')) scriptDeps.push('GlideRecord API');
|
|
664
|
-
if (artifact.script.includes('GlideAjax')) scriptDeps.push('GlideAjax');
|
|
665
|
-
if (artifact.script.includes('gs.')) scriptDeps.push('GlideSystem API');
|
|
666
|
-
|
|
667
|
-
_analysis.dependencies = scriptDeps;
|
|
668
|
-
}
|
|
669
|
-
break;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
return _analysis;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
private async findRelationships(
|
|
676
|
-
artifact: any,
|
|
677
|
-
table: string,
|
|
678
|
-
context: AgentContext
|
|
679
|
-
): Promise<any[]> {
|
|
680
|
-
const relationships = [];
|
|
681
|
-
|
|
682
|
-
// Find references in the artifact
|
|
683
|
-
if (table === 'sp_widget' && artifact.server_script) {
|
|
684
|
-
// Look for script includes
|
|
685
|
-
const scriptMatches = artifact.server_script.match(/new\s+(\w+)\(/g);
|
|
686
|
-
if (scriptMatches) {
|
|
687
|
-
for (const match of scriptMatches) {
|
|
688
|
-
const scriptName = match.replace(/new\s+/, '').replace(/\(/, '');
|
|
689
|
-
relationships.push({
|
|
690
|
-
type: 'uses_script',
|
|
691
|
-
name: scriptName,
|
|
692
|
-
table: 'sys_script_include'
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
return relationships;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
private async updateSearchContext(
|
|
702
|
-
context: AgentContext,
|
|
703
|
-
query: string,
|
|
704
|
-
results: SearchResult[]
|
|
705
|
-
): Promise<void> {
|
|
706
|
-
await this.memory.updateSharedContext({
|
|
707
|
-
session_id: context.session_id,
|
|
708
|
-
context_key: `search_${this.hashQuery(query)}`,
|
|
709
|
-
context_value: JSON.stringify({
|
|
710
|
-
query,
|
|
711
|
-
results: results.map(r => ({
|
|
712
|
-
sys_id: r.sys_id,
|
|
713
|
-
name: r.name,
|
|
714
|
-
type: r.type
|
|
715
|
-
})),
|
|
716
|
-
timestamp: new Date().toISOString(),
|
|
717
|
-
found_count: results.length
|
|
718
|
-
}),
|
|
719
|
-
created_by_agent: context.agent_id
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
private getCachedResults(query: string, type?: string): SearchResult[] | null {
|
|
724
|
-
const cacheKey = `${query}_${type || 'any'}`;
|
|
725
|
-
const cached = this.searchCache.get(cacheKey);
|
|
726
|
-
|
|
727
|
-
if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
|
|
728
|
-
return cached.results;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
return null;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
private cacheResults(query: string, type: string | undefined, results: SearchResult[]): void {
|
|
735
|
-
const cacheKey = `${query}_${type || 'any'}`;
|
|
736
|
-
this.searchCache.set(cacheKey, {
|
|
737
|
-
results,
|
|
738
|
-
timestamp: Date.now()
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
private calculateRelevance(name: string, query: string): number {
|
|
743
|
-
const nameLower = name.toLowerCase();
|
|
744
|
-
const queryLower = query.toLowerCase();
|
|
745
|
-
|
|
746
|
-
// Exact match
|
|
747
|
-
if (nameLower === queryLower) return 1.0;
|
|
748
|
-
|
|
749
|
-
// Starts with query
|
|
750
|
-
if (nameLower.startsWith(queryLower)) return 0.9;
|
|
751
|
-
|
|
752
|
-
// Contains query
|
|
753
|
-
if (nameLower.includes(queryLower)) return 0.7;
|
|
754
|
-
|
|
755
|
-
// Fuzzy match (simple)
|
|
756
|
-
const queryWords = queryLower.split(/\s+/);
|
|
757
|
-
const matchedWords = queryWords.filter(word => nameLower.includes(word));
|
|
758
|
-
return matchedWords.length / queryWords.length * 0.5;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
private getArtifactType(table: string): string {
|
|
762
|
-
const typeMap: Record<string, string> = {
|
|
763
|
-
'sp_widget': 'widget',
|
|
764
|
-
'sys_hub_flow': 'flow',
|
|
765
|
-
'sys_script_include': 'script',
|
|
766
|
-
'sys_app': 'application',
|
|
767
|
-
'sc_cat_item': 'catalog_item',
|
|
768
|
-
'sys_script': 'business_rule'
|
|
769
|
-
};
|
|
770
|
-
|
|
771
|
-
return typeMap[table] || 'unknown';
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
protected getTableForType(type: string): string {
|
|
775
|
-
const tableMap: Record<string, string> = {
|
|
776
|
-
'widget': 'sp_widget',
|
|
777
|
-
'flow': 'sys_hub_flow',
|
|
778
|
-
'script': 'sys_script_include',
|
|
779
|
-
'application': 'sys_app',
|
|
780
|
-
'catalog_item': 'sc_cat_item',
|
|
781
|
-
'business_rule': 'sys_script'
|
|
782
|
-
};
|
|
783
|
-
|
|
784
|
-
return tableMap[type] || 'sys_metadata';
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
private getSearchConfigForType(type: string): any {
|
|
788
|
-
const configs: Record<string, any> = {
|
|
789
|
-
'widget': { table: 'sp_widget', type: 'widget', nameField: 'name' },
|
|
790
|
-
'flow': { table: 'sys_hub_flow', type: 'flow', nameField: 'name' },
|
|
791
|
-
'script': { table: 'sys_script_include', type: 'script', nameField: 'name' },
|
|
792
|
-
'application': { table: 'sys_app', type: 'application', nameField: 'name' }
|
|
793
|
-
};
|
|
794
|
-
|
|
795
|
-
return configs[type] || configs['widget'];
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
private getAllSearchConfigs(): any[] {
|
|
799
|
-
return [
|
|
800
|
-
{ table: 'sp_widget', type: 'widget', nameField: 'name' },
|
|
801
|
-
{ table: 'sys_hub_flow', type: 'flow', nameField: 'name' },
|
|
802
|
-
{ table: 'sys_script_include', type: 'script', nameField: 'name' },
|
|
803
|
-
{ table: 'sys_app', type: 'application', nameField: 'name' }
|
|
804
|
-
];
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
private hashQuery(query: string): string {
|
|
808
|
-
return crypto.createHash('md5').update(query).digest('hex').substring(0, 8);
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* Memory store handler
|
|
813
|
-
*/
|
|
814
|
-
private async handleMemoryStore(args: any): Promise<MCPToolResult> {
|
|
815
|
-
const { key, value, ttl, namespace = 'default' } = args;
|
|
816
|
-
|
|
817
|
-
try {
|
|
818
|
-
// Store in shared context
|
|
819
|
-
await this.memory.updateSharedContext({
|
|
820
|
-
session_id: 'global',
|
|
821
|
-
context_key: `${namespace}:${key}`,
|
|
822
|
-
context_value: JSON.stringify(value),
|
|
823
|
-
created_by_agent: 'intelligent_mcp'
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
return this.createSuccessResponse(
|
|
827
|
-
`Data stored successfully with key: ${namespace}:${key}`,
|
|
828
|
-
{ key: `${namespace}:${key}`, namespace }
|
|
829
|
-
);
|
|
830
|
-
} catch (error) {
|
|
831
|
-
return this.createErrorResponse('Failed to store in memory', error);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
/**
|
|
836
|
-
* Memory get handler
|
|
837
|
-
*/
|
|
838
|
-
private async handleMemoryGet(args: any): Promise<MCPToolResult> {
|
|
839
|
-
const { key, namespace = 'default' } = args;
|
|
840
|
-
|
|
841
|
-
try {
|
|
842
|
-
// Get from session context
|
|
843
|
-
const sessionContext = await this.memory.getSessionContext('global');
|
|
844
|
-
const fullKey = `${namespace}:${key}`;
|
|
845
|
-
|
|
846
|
-
if (!sessionContext || !sessionContext[fullKey]) {
|
|
847
|
-
return this.createSuccessResponse(
|
|
848
|
-
`Key not found: ${namespace}:${key}`,
|
|
849
|
-
{ value: null, found: false }
|
|
850
|
-
);
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
return this.createSuccessResponse(
|
|
854
|
-
`Data retrieved successfully`,
|
|
855
|
-
{
|
|
856
|
-
key: `${namespace}:${key}`,
|
|
857
|
-
namespace,
|
|
858
|
-
value: JSON.parse(sessionContext[fullKey]),
|
|
859
|
-
found: true
|
|
860
|
-
}
|
|
861
|
-
);
|
|
862
|
-
} catch (error) {
|
|
863
|
-
return this.createErrorResponse('Failed to retrieve from memory', error);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
/**
|
|
868
|
-
* Memory list handler
|
|
869
|
-
*/
|
|
870
|
-
private async handleMemoryList(args: any): Promise<MCPToolResult> {
|
|
871
|
-
const { namespace = 'default', pattern } = args;
|
|
872
|
-
|
|
873
|
-
try {
|
|
874
|
-
// Get all contexts for global session
|
|
875
|
-
const sessionContext = await this.memory.getSessionContext('global');
|
|
876
|
-
|
|
877
|
-
if (!sessionContext) {
|
|
878
|
-
return this.createSuccessResponse(
|
|
879
|
-
`No keys found in namespace ${namespace}`,
|
|
880
|
-
{ namespace, count: 0, keys: [] }
|
|
881
|
-
);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
// Filter by namespace
|
|
885
|
-
let keys = Object.keys(sessionContext)
|
|
886
|
-
.filter(k => k.startsWith(`${namespace}:`))
|
|
887
|
-
.map(k => k.replace(`${namespace}:`, ''));
|
|
888
|
-
|
|
889
|
-
// Apply pattern filter if provided
|
|
890
|
-
if (pattern) {
|
|
891
|
-
const regex = new RegExp(pattern);
|
|
892
|
-
keys = keys.filter(k => regex.test(k));
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
return this.createSuccessResponse(
|
|
896
|
-
`Found ${keys.length} keys in namespace ${namespace}`,
|
|
897
|
-
{ namespace, count: keys.length, keys }
|
|
898
|
-
);
|
|
899
|
-
} catch (error) {
|
|
900
|
-
return this.createErrorResponse('Failed to list memory keys', error);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
/**
|
|
905
|
-
* Todo write handler
|
|
906
|
-
*/
|
|
907
|
-
private async handleTodoWrite(args: any): Promise<MCPToolResult> {
|
|
908
|
-
const { todos } = args;
|
|
909
|
-
|
|
910
|
-
try {
|
|
911
|
-
// Store todos in shared context
|
|
912
|
-
await this.memory.updateSharedContext({
|
|
913
|
-
session_id: 'global',
|
|
914
|
-
context_key: 'todos:current',
|
|
915
|
-
context_value: JSON.stringify(todos),
|
|
916
|
-
created_by_agent: 'intelligent_mcp'
|
|
917
|
-
});
|
|
918
|
-
|
|
919
|
-
// Update individual todo items for quick access
|
|
920
|
-
for (const todo of todos) {
|
|
921
|
-
await this.memory.updateSharedContext({
|
|
922
|
-
session_id: 'global',
|
|
923
|
-
context_key: `todos:item:${todo.id}`,
|
|
924
|
-
context_value: JSON.stringify(todo),
|
|
925
|
-
created_by_agent: 'intelligent_mcp'
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
return this.createSuccessResponse(
|
|
930
|
-
`Updated ${todos.length} todo items`,
|
|
931
|
-
{ todos, count: todos.length }
|
|
932
|
-
);
|
|
933
|
-
} catch (error) {
|
|
934
|
-
return this.createErrorResponse('Failed to write todos', error);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
/**
|
|
939
|
-
* Todo read handler
|
|
940
|
-
*/
|
|
941
|
-
private async handleTodoRead(args: any): Promise<MCPToolResult> {
|
|
942
|
-
const { status = 'all' } = args;
|
|
943
|
-
|
|
944
|
-
try {
|
|
945
|
-
// Get current todos from session context
|
|
946
|
-
const sessionContext = await this.memory.getSessionContext('global');
|
|
947
|
-
const todosKey = 'todos:current';
|
|
948
|
-
|
|
949
|
-
if (!sessionContext || !sessionContext[todosKey]) {
|
|
950
|
-
return this.createSuccessResponse(
|
|
951
|
-
'No todos found',
|
|
952
|
-
{ todos: [], count: 0 }
|
|
953
|
-
);
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
let todos = JSON.parse(sessionContext[todosKey]);
|
|
957
|
-
|
|
958
|
-
// Filter by status if not 'all'
|
|
959
|
-
if (status !== 'all') {
|
|
960
|
-
todos = todos.filter((t: any) => t.status === status);
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
return this.createSuccessResponse(
|
|
964
|
-
`Found ${todos.length} todos`,
|
|
965
|
-
{ todos, count: todos.length }
|
|
966
|
-
);
|
|
967
|
-
} catch (error) {
|
|
968
|
-
return this.createErrorResponse('Failed to read todos', error);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
// Start the server
|
|
974
|
-
// if (import.meta.url === `file://${process.argv[1]}`) {
|
|
975
|
-
// const server = new ServiceNowIntelligentMCP();
|
|
976
|
-
// server.start().catch(console.error);
|
|
977
|
-
// }
|