snow-flow 1.1.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/.env.example +49 -0
- package/.mcp.json +106 -0
- package/.mcp.json.template +106 -0
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/bin/snow-flow +4 -0
- package/bin/snow-flow.js +3 -0
- package/claude-flow +79 -0
- package/claude-flow.bat +18 -0
- package/claude-flow.config.json +20 -0
- package/claude-flow.ps1 +24 -0
- package/dist/agents/app-creator.agent.d.ts +55 -0
- package/dist/agents/app-creator.agent.d.ts.map +1 -0
- package/dist/agents/app-creator.agent.js +1292 -0
- package/dist/agents/app-creator.agent.js.map +1 -0
- package/dist/agents/base-snow-agent.d.ts +63 -0
- package/dist/agents/base-snow-agent.d.ts.map +1 -0
- package/dist/agents/base-snow-agent.js +296 -0
- package/dist/agents/base-snow-agent.js.map +1 -0
- package/dist/agents/script-generator.agent.d.ts +32 -0
- package/dist/agents/script-generator.agent.d.ts.map +1 -0
- package/dist/agents/script-generator.agent.js +772 -0
- package/dist/agents/script-generator.agent.js.map +1 -0
- package/dist/agents/ui-builder.agent.d.ts +50 -0
- package/dist/agents/ui-builder.agent.d.ts.map +1 -0
- package/dist/agents/ui-builder.agent.js +1539 -0
- package/dist/agents/ui-builder.agent.js.map +1 -0
- package/dist/agents/widget-builder.agent.d.ts +32 -0
- package/dist/agents/widget-builder.agent.d.ts.map +1 -0
- package/dist/agents/widget-builder.agent.js +439 -0
- package/dist/agents/widget-builder.agent.js.map +1 -0
- package/dist/agents/workflow-designer.agent.d.ts +31 -0
- package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
- package/dist/agents/workflow-designer.agent.js +583 -0
- package/dist/agents/workflow-designer.agent.js.map +1 -0
- package/dist/api/error-handling.d.ts +214 -0
- package/dist/api/error-handling.d.ts.map +1 -0
- package/dist/api/error-handling.js +594 -0
- package/dist/api/error-handling.js.map +1 -0
- package/dist/api/flow-designer-api.d.ts +167 -0
- package/dist/api/flow-designer-api.d.ts.map +1 -0
- package/dist/api/flow-designer-api.js +555 -0
- package/dist/api/flow-designer-api.js.map +1 -0
- package/dist/api/natural-language-mapper.d.ts +126 -0
- package/dist/api/natural-language-mapper.d.ts.map +1 -0
- package/dist/api/natural-language-mapper.js +498 -0
- package/dist/api/natural-language-mapper.js.map +1 -0
- package/dist/api/performance-optimizer.d.ts +240 -0
- package/dist/api/performance-optimizer.d.ts.map +1 -0
- package/dist/api/performance-optimizer.js +701 -0
- package/dist/api/performance-optimizer.js.map +1 -0
- package/dist/api/transaction-manager.d.ts +189 -0
- package/dist/api/transaction-manager.d.ts.map +1 -0
- package/dist/api/transaction-manager.js +576 -0
- package/dist/api/transaction-manager.js.map +1 -0
- package/dist/cli/deploy-artifact.d.ts +7 -0
- package/dist/cli/deploy-artifact.d.ts.map +1 -0
- package/dist/cli/deploy-artifact.js +279 -0
- package/dist/cli/deploy-artifact.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2057 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/scope-manager.d.ts +75 -0
- package/dist/managers/scope-manager.d.ts.map +1 -0
- package/dist/managers/scope-manager.js +448 -0
- package/dist/managers/scope-manager.js.map +1 -0
- package/dist/mcp/mcp-wrapper.d.ts +8 -0
- package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
- package/dist/mcp/mcp-wrapper.js +77 -0
- package/dist/mcp/mcp-wrapper.js.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.js +683 -0
- package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.js +972 -0
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.js +689 -0
- package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
- package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
- package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
- package/dist/mcp/servicenow-mcp-server.js +648 -0
- package/dist/mcp/servicenow-mcp-server.js.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.js +1287 -0
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
- package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.js +320 -0
- package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.js +599 -0
- package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
- package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
- package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
- package/dist/mcp/start-all-mcp-servers.js +65 -0
- package/dist/mcp/start-all-mcp-servers.js.map +1 -0
- package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
- package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
- package/dist/mcp/start-servicenow-mcp.js +64 -0
- package/dist/mcp/start-servicenow-mcp.js.map +1 -0
- package/dist/mcp/test-simple-mcp.d.ts +6 -0
- package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
- package/dist/mcp/test-simple-mcp.js +64 -0
- package/dist/mcp/test-simple-mcp.js.map +1 -0
- package/dist/orchestrator/flow-composer.d.ts +269 -0
- package/dist/orchestrator/flow-composer.d.ts.map +1 -0
- package/dist/orchestrator/flow-composer.js +2221 -0
- package/dist/orchestrator/flow-composer.js.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.js +906 -0
- package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
- package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
- package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-validation-engine.js +663 -0
- package/dist/orchestrator/flow-validation-engine.js.map +1 -0
- package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
- package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/snow-orchestrator.js +235 -0
- package/dist/orchestrator/snow-orchestrator.js.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.js +791 -0
- package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
- package/dist/strategies/global-scope-strategy.d.ts +123 -0
- package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
- package/dist/strategies/global-scope-strategy.js +585 -0
- package/dist/strategies/global-scope-strategy.js.map +1 -0
- package/dist/types/index.d.ts +138 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/servicenow.types.d.ts +260 -0
- package/dist/types/servicenow.types.d.ts.map +1 -0
- package/dist/types/servicenow.types.js +3 -0
- package/dist/types/servicenow.types.js.map +1 -0
- package/dist/types/snow-flow.types.d.ts +114 -0
- package/dist/types/snow-flow.types.d.ts.map +1 -0
- package/dist/types/snow-flow.types.js +3 -0
- package/dist/types/snow-flow.types.js.map +1 -0
- package/dist/utils/action-type-cache.d.ts +66 -0
- package/dist/utils/action-type-cache.d.ts.map +1 -0
- package/dist/utils/action-type-cache.js +237 -0
- package/dist/utils/action-type-cache.js.map +1 -0
- package/dist/utils/agent-detector.d.ts +35 -0
- package/dist/utils/agent-detector.d.ts.map +1 -0
- package/dist/utils/agent-detector.js +353 -0
- package/dist/utils/agent-detector.js.map +1 -0
- package/dist/utils/flow-api-discovery.d.ts +151 -0
- package/dist/utils/flow-api-discovery.d.ts.map +1 -0
- package/dist/utils/flow-api-discovery.js +440 -0
- package/dist/utils/flow-api-discovery.js.map +1 -0
- package/dist/utils/flow-xml-generator.d.ts +41 -0
- package/dist/utils/flow-xml-generator.d.ts.map +1 -0
- package/dist/utils/flow-xml-generator.js +258 -0
- package/dist/utils/flow-xml-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-auth-middleware.d.ts +58 -0
- package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
- package/dist/utils/mcp-auth-middleware.js +227 -0
- package/dist/utils/mcp-auth-middleware.js.map +1 -0
- package/dist/utils/mcp-config-manager.d.ts +126 -0
- package/dist/utils/mcp-config-manager.d.ts.map +1 -0
- package/dist/utils/mcp-config-manager.js +209 -0
- package/dist/utils/mcp-config-manager.js.map +1 -0
- package/dist/utils/mcp-server-manager.d.ts +91 -0
- package/dist/utils/mcp-server-manager.d.ts.map +1 -0
- package/dist/utils/mcp-server-manager.js +338 -0
- package/dist/utils/mcp-server-manager.js.map +1 -0
- package/dist/utils/scope-utils.d.ts +72 -0
- package/dist/utils/scope-utils.d.ts.map +1 -0
- package/dist/utils/scope-utils.js +386 -0
- package/dist/utils/scope-utils.js.map +1 -0
- package/dist/utils/servicenow-client.d.ts +233 -0
- package/dist/utils/servicenow-client.d.ts.map +1 -0
- package/dist/utils/servicenow-client.js +1465 -0
- package/dist/utils/servicenow-client.js.map +1 -0
- package/dist/utils/snow-oauth-old.d.ts +65 -0
- package/dist/utils/snow-oauth-old.d.ts.map +1 -0
- package/dist/utils/snow-oauth-old.js +345 -0
- package/dist/utils/snow-oauth-old.js.map +1 -0
- package/dist/utils/snow-oauth.d.ts +85 -0
- package/dist/utils/snow-oauth.d.ts.map +1 -0
- package/dist/utils/snow-oauth.js +512 -0
- package/dist/utils/snow-oauth.js.map +1 -0
- package/dist/utils/template-engine.d.ts +76 -0
- package/dist/utils/template-engine.d.ts.map +1 -0
- package/dist/utils/template-engine.js +391 -0
- package/dist/utils/template-engine.js.map +1 -0
- package/dist/version.d.ts +35 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +72 -0
- package/dist/version.js.map +1 -0
- package/mcp-wrapper.sh +12 -0
- package/package.json +77 -0
- package/reports/swarm-auto-centralized-1752649029776.json +13 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/setup-mcp.js +89 -0
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* ServiceNow Graph Memory MCP Server
|
|
5
|
+
* Neo4j-based intelligent memory system for ServiceNow artifacts
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
12
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
13
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
14
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
15
|
+
const mcp_config_manager_js_1 = require("../utils/mcp-config-manager.js");
|
|
16
|
+
const neo4j_driver_1 = __importDefault(require("neo4j-driver"));
|
|
17
|
+
class ServiceNowGraphMemoryMCP {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.driver = null;
|
|
20
|
+
this.config = null;
|
|
21
|
+
this.neo4jAvailable = false;
|
|
22
|
+
this.server = new index_js_1.Server({
|
|
23
|
+
name: 'servicenow-graph-memory',
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
}, {
|
|
26
|
+
capabilities: {
|
|
27
|
+
tools: {},
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
this.logger = new logger_js_1.Logger('ServiceNowGraphMemoryMCP');
|
|
31
|
+
const rawConfig = mcp_config_manager_js_1.mcpConfig.getNeo4jConfig();
|
|
32
|
+
// Validate Neo4j configuration - but don't fail if missing
|
|
33
|
+
if (!rawConfig?.uri || !rawConfig?.username || !rawConfig?.password) {
|
|
34
|
+
this.logger.warn('Neo4j configuration missing. Graph Memory MCP will run in fallback mode without Neo4j functionality.');
|
|
35
|
+
this.logger.info('To enable Neo4j: set NEO4J_URI, NEO4J_USERNAME, and NEO4J_PASSWORD environment variables.');
|
|
36
|
+
this.neo4jAvailable = false;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// After validation, we know these are defined
|
|
40
|
+
this.config = {
|
|
41
|
+
uri: rawConfig.uri,
|
|
42
|
+
username: rawConfig.username,
|
|
43
|
+
password: rawConfig.password,
|
|
44
|
+
database: rawConfig.database
|
|
45
|
+
};
|
|
46
|
+
this.neo4jAvailable = true;
|
|
47
|
+
}
|
|
48
|
+
this.setupHandlers();
|
|
49
|
+
}
|
|
50
|
+
createFallbackResponse(toolName) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
message: `${toolName} requires Neo4j database. Please install and configure Neo4j to use graph memory features.`,
|
|
54
|
+
fallback_mode: true,
|
|
55
|
+
instructions: [
|
|
56
|
+
'1. Install Neo4j Community Edition',
|
|
57
|
+
'2. Start Neo4j service',
|
|
58
|
+
'3. Set environment variables: NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD',
|
|
59
|
+
'4. Restart the MCP server'
|
|
60
|
+
]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async connectToNeo4j() {
|
|
64
|
+
if (!this.neo4jAvailable || !this.config) {
|
|
65
|
+
this.logger.warn('Neo4j not available - using fallback mode');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (!this.driver) {
|
|
69
|
+
try {
|
|
70
|
+
this.driver = neo4j_driver_1.default.driver(this.config.uri, neo4j_driver_1.default.auth.basic(this.config.username, this.config.password));
|
|
71
|
+
await this.driver.verifyConnectivity();
|
|
72
|
+
this.logger.info('Connected to Neo4j');
|
|
73
|
+
// Create indexes for better performance
|
|
74
|
+
const session = this.driver.session();
|
|
75
|
+
try {
|
|
76
|
+
await session.run('CREATE INDEX artifact_id IF NOT EXISTS FOR (a:Artifact) ON (a.id)');
|
|
77
|
+
await session.run('CREATE INDEX artifact_type IF NOT EXISTS FOR (a:Artifact) ON (a.type)');
|
|
78
|
+
await session.run('CREATE INDEX artifact_name IF NOT EXISTS FOR (a:Artifact) ON (a.name)');
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await session.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
this.logger.error('Failed to connect to Neo4j', error);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return this.driver;
|
|
90
|
+
}
|
|
91
|
+
setupHandlers() {
|
|
92
|
+
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
93
|
+
tools: [
|
|
94
|
+
{
|
|
95
|
+
name: 'snow_graph_index_artifact',
|
|
96
|
+
description: 'AUTONOMOUS graph indexing - stores ServiceNow artifacts in Neo4j with relationships, enables instant understanding of dependencies and connections',
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
artifact: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
id: { type: 'string', description: 'Unique identifier for the artifact' },
|
|
104
|
+
name: { type: 'string', description: 'Artifact name' },
|
|
105
|
+
type: { type: 'string', enum: ['widget', 'flow', 'script_include', 'business_rule', 'table', 'client_script', 'ui_script'] },
|
|
106
|
+
content: { type: 'string', description: 'Full content/code of the artifact' },
|
|
107
|
+
purpose: { type: 'string', description: 'What this artifact does' },
|
|
108
|
+
},
|
|
109
|
+
required: ['id', 'name', 'type'],
|
|
110
|
+
},
|
|
111
|
+
relationships: {
|
|
112
|
+
type: 'array',
|
|
113
|
+
description: 'Relationships to other artifacts',
|
|
114
|
+
items: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
to: { type: 'string', description: 'Target artifact ID' },
|
|
118
|
+
type: { type: 'string', enum: ['USES', 'REQUIRES', 'TRIGGERS', 'CREATES', 'MODIFIES', 'CALLS', 'EXTENDS'] },
|
|
119
|
+
data_flow: { type: 'string', description: 'How data flows between artifacts' },
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
required: ['artifact'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'snow_graph_find_related',
|
|
129
|
+
description: 'INTELLIGENT relationship discovery - finds all artifacts related to a given artifact, understands dependencies, data flows, and impact analysis',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
artifact_id: { type: 'string', description: 'Artifact ID to find relationships for' },
|
|
134
|
+
depth: { type: 'number', description: 'How many levels of relationships to traverse', default: 2 },
|
|
135
|
+
relationship_types: {
|
|
136
|
+
type: 'array',
|
|
137
|
+
description: 'Filter by relationship types',
|
|
138
|
+
items: { type: 'string', enum: ['USES', 'REQUIRES', 'TRIGGERS', 'CREATES', 'MODIFIES', 'CALLS', 'EXTENDS'] },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
required: ['artifact_id'],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: 'snow_graph_analyze_impact',
|
|
146
|
+
description: 'IMPACT ANALYSIS - shows what will be affected if an artifact is modified, critical for safe deployments',
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
artifact_id: { type: 'string', description: 'Artifact to analyze impact for' },
|
|
151
|
+
change_type: { type: 'string', enum: ['modify', 'delete', 'upgrade'], description: 'Type of change planned' },
|
|
152
|
+
},
|
|
153
|
+
required: ['artifact_id'],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'snow_graph_suggest_artifacts',
|
|
158
|
+
description: 'AI-POWERED suggestions - recommends artifacts based on current context and past successful patterns',
|
|
159
|
+
inputSchema: {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
context: { type: 'string', description: 'Current development context' },
|
|
163
|
+
artifact_type: { type: 'string', description: 'Type of artifact needed' },
|
|
164
|
+
requirements: { type: 'array', items: { type: 'string' }, description: 'Specific requirements' },
|
|
165
|
+
},
|
|
166
|
+
required: ['context'],
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'snow_graph_pattern_analysis',
|
|
171
|
+
description: 'PATTERN RECOGNITION - identifies common patterns, best practices, and reusable components across all artifacts',
|
|
172
|
+
inputSchema: {
|
|
173
|
+
type: 'object',
|
|
174
|
+
properties: {
|
|
175
|
+
pattern_type: { type: 'string', enum: ['architectural', 'coding', 'integration', 'error_handling'], description: 'Type of pattern to analyze' },
|
|
176
|
+
min_occurrences: { type: 'number', description: 'Minimum times pattern must appear', default: 3 },
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'snow_graph_visualize',
|
|
182
|
+
description: 'GRAPH VISUALIZATION - generates Cypher queries for visualizing artifact relationships in Neo4j Browser',
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
focus_artifact: { type: 'string', description: 'Central artifact to visualize around' },
|
|
187
|
+
include_types: { type: 'array', items: { type: 'string' }, description: 'Artifact types to include' },
|
|
188
|
+
max_nodes: { type: 'number', description: 'Maximum nodes to display', default: 50 },
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'snow_graph_export_knowledge',
|
|
194
|
+
description: 'KNOWLEDGE EXPORT - exports learned patterns and relationships for backup or sharing',
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: 'object',
|
|
197
|
+
properties: {
|
|
198
|
+
format: { type: 'string', enum: ['cypher', 'json', 'graphml'], description: 'Export format' },
|
|
199
|
+
include_content: { type: 'boolean', description: 'Include full artifact content', default: false },
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
}));
|
|
205
|
+
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
206
|
+
const { name, arguments: args } = request.params;
|
|
207
|
+
try {
|
|
208
|
+
await this.connectToNeo4j();
|
|
209
|
+
switch (name) {
|
|
210
|
+
case 'snow_graph_index_artifact':
|
|
211
|
+
return await this.indexArtifact(args);
|
|
212
|
+
case 'snow_graph_find_related':
|
|
213
|
+
return await this.findRelatedArtifacts(args);
|
|
214
|
+
case 'snow_graph_analyze_impact':
|
|
215
|
+
return await this.analyzeImpact(args);
|
|
216
|
+
case 'snow_graph_suggest_artifacts':
|
|
217
|
+
return await this.suggestArtifacts(args);
|
|
218
|
+
case 'snow_graph_pattern_analysis':
|
|
219
|
+
return await this.analyzePatterns(args);
|
|
220
|
+
case 'snow_graph_visualize':
|
|
221
|
+
return await this.generateVisualization(args);
|
|
222
|
+
case 'snow_graph_export_knowledge':
|
|
223
|
+
return await this.exportKnowledge(args);
|
|
224
|
+
default:
|
|
225
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
this.logger.error(`Tool execution failed: ${name}`, error);
|
|
230
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, error instanceof Error ? error.message : String(error));
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async indexArtifact(args) {
|
|
235
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
236
|
+
return this.createFallbackResponse('snow_graph_index_artifact');
|
|
237
|
+
}
|
|
238
|
+
const session = this.driver.session();
|
|
239
|
+
try {
|
|
240
|
+
const { artifact, relationships = [] } = args;
|
|
241
|
+
// Create or update the artifact node
|
|
242
|
+
await session.run(`
|
|
243
|
+
MERGE (a:Artifact {id: $id})
|
|
244
|
+
SET a.name = $name,
|
|
245
|
+
a.type = $type,
|
|
246
|
+
a.content = $content,
|
|
247
|
+
a.purpose = $purpose,
|
|
248
|
+
a.last_updated = datetime(),
|
|
249
|
+
a.indexed_at = datetime()
|
|
250
|
+
RETURN a
|
|
251
|
+
`, artifact);
|
|
252
|
+
// Create relationships
|
|
253
|
+
for (const rel of relationships) {
|
|
254
|
+
await session.run(`
|
|
255
|
+
MATCH (a:Artifact {id: $fromId})
|
|
256
|
+
MERGE (b:Artifact {id: $toId})
|
|
257
|
+
MERGE (a)-[r:${rel.type}]->(b)
|
|
258
|
+
SET r.data_flow = $dataFlow,
|
|
259
|
+
r.created_at = datetime()
|
|
260
|
+
`, {
|
|
261
|
+
fromId: artifact.id,
|
|
262
|
+
toId: rel.to,
|
|
263
|
+
dataFlow: rel.data_flow || ''
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
// Analyze artifact content for automatic relationship discovery
|
|
267
|
+
const discoveredRelations = await this.discoverRelationships(artifact);
|
|
268
|
+
return {
|
|
269
|
+
content: [{
|
|
270
|
+
type: 'text',
|
|
271
|
+
text: `✅ Artifact indexed successfully!
|
|
272
|
+
|
|
273
|
+
📊 **Artifact Details:**
|
|
274
|
+
- ID: ${artifact.id}
|
|
275
|
+
- Name: ${artifact.name}
|
|
276
|
+
- Type: ${artifact.type}
|
|
277
|
+
- Relationships: ${relationships.length} explicit, ${discoveredRelations} discovered
|
|
278
|
+
|
|
279
|
+
🔗 **Graph Impact:**
|
|
280
|
+
- Node created/updated in Neo4j
|
|
281
|
+
- Relationships established
|
|
282
|
+
- Available for pattern analysis
|
|
283
|
+
- Ready for impact assessment
|
|
284
|
+
|
|
285
|
+
💡 **Next Steps:**
|
|
286
|
+
- Use snow_graph_find_related to explore connections
|
|
287
|
+
- Use snow_graph_analyze_impact before modifications
|
|
288
|
+
- Use snow_graph_pattern_analysis to find similar artifacts`
|
|
289
|
+
}]
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
await session.close();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async discoverRelationships(artifact) {
|
|
297
|
+
// Analyze artifact content to discover implicit relationships
|
|
298
|
+
const content = artifact.content || '';
|
|
299
|
+
const discoveries = [];
|
|
300
|
+
// Find script includes used
|
|
301
|
+
const scriptIncludeMatches = content.match(/new\s+(\w+)\(/g) || [];
|
|
302
|
+
for (const match of scriptIncludeMatches) {
|
|
303
|
+
const className = match.match(/new\s+(\w+)\(/)?.[1];
|
|
304
|
+
if (className)
|
|
305
|
+
discoveries.push(className);
|
|
306
|
+
}
|
|
307
|
+
// Find table references
|
|
308
|
+
const tableMatches = content.match(/GlideRecord\(['"](\w+)['"]\)/g) || [];
|
|
309
|
+
for (const match of tableMatches) {
|
|
310
|
+
const tableName = match.match(/GlideRecord\(['"](\w+)['"]\)/)?.[1];
|
|
311
|
+
if (tableName)
|
|
312
|
+
discoveries.push(tableName);
|
|
313
|
+
}
|
|
314
|
+
return discoveries.length;
|
|
315
|
+
}
|
|
316
|
+
async findRelatedArtifacts(args) {
|
|
317
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
318
|
+
return this.createFallbackResponse('snow_graph_find_related');
|
|
319
|
+
}
|
|
320
|
+
const session = this.driver.session();
|
|
321
|
+
try {
|
|
322
|
+
const { artifact_id, depth = 2, relationship_types = [] } = args;
|
|
323
|
+
const relFilter = relationship_types.length > 0
|
|
324
|
+
? `WHERE type(r) IN [${relationship_types.map((t) => `'${t}'`).join(', ')}]`
|
|
325
|
+
: '';
|
|
326
|
+
const result = await session.run(`
|
|
327
|
+
MATCH (start:Artifact {id: $artifactId})
|
|
328
|
+
CALL apoc.path.subgraphAll(start, {
|
|
329
|
+
maxLevel: $depth,
|
|
330
|
+
relationshipFilter: "${relFilter}"
|
|
331
|
+
})
|
|
332
|
+
YIELD nodes, relationships
|
|
333
|
+
RETURN nodes, relationships
|
|
334
|
+
`, { artifactId: artifact_id, depth });
|
|
335
|
+
const nodes = result.records[0]?.get('nodes') || [];
|
|
336
|
+
const relationships = result.records[0]?.get('relationships') || [];
|
|
337
|
+
return {
|
|
338
|
+
content: [{
|
|
339
|
+
type: 'text',
|
|
340
|
+
text: `🔗 Related Artifacts Found:
|
|
341
|
+
|
|
342
|
+
📊 **Summary:**
|
|
343
|
+
- Total artifacts: ${nodes.length}
|
|
344
|
+
- Total relationships: ${relationships.length}
|
|
345
|
+
- Search depth: ${depth} levels
|
|
346
|
+
|
|
347
|
+
🗂️ **Artifacts:**
|
|
348
|
+
${nodes.map((n) => `- ${n.properties.type}: ${n.properties.name} (${n.properties.id})`).join('\n')}
|
|
349
|
+
|
|
350
|
+
🔀 **Relationships:**
|
|
351
|
+
${relationships.map((r) => `- ${r.type}: ${r.start} → ${r.end}`).join('\n')}
|
|
352
|
+
|
|
353
|
+
💡 **Insights:**
|
|
354
|
+
- This artifact is part of a ${nodes.length > 10 ? 'complex' : 'simple'} dependency network
|
|
355
|
+
- ${relationships.filter((r) => r.type === 'REQUIRES').length} required dependencies
|
|
356
|
+
- ${relationships.filter((r) => r.type === 'USES').length} usage relationships`
|
|
357
|
+
}]
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
finally {
|
|
361
|
+
await session.close();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
async analyzeImpact(args) {
|
|
365
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
366
|
+
return this.createFallbackResponse('snow_graph_analyze_impact');
|
|
367
|
+
}
|
|
368
|
+
const session = this.driver.session();
|
|
369
|
+
try {
|
|
370
|
+
const { artifact_id, change_type = 'modify' } = args;
|
|
371
|
+
// Find all artifacts that depend on this one
|
|
372
|
+
const result = await session.run(`
|
|
373
|
+
MATCH (target:Artifact {id: $artifactId})
|
|
374
|
+
MATCH (dependent:Artifact)-[:USES|REQUIRES|CALLS]->(target)
|
|
375
|
+
RETURN dependent, count(*) as impact_count
|
|
376
|
+
ORDER BY impact_count DESC
|
|
377
|
+
`, { artifactId: artifact_id });
|
|
378
|
+
const impactedArtifacts = result.records.map((r) => ({
|
|
379
|
+
artifact: r.get('dependent').properties,
|
|
380
|
+
impact: r.get('impact_count').toNumber()
|
|
381
|
+
}));
|
|
382
|
+
const riskLevel = impactedArtifacts.length > 5 ? 'HIGH' :
|
|
383
|
+
impactedArtifacts.length > 2 ? 'MEDIUM' : 'LOW';
|
|
384
|
+
return {
|
|
385
|
+
content: [{
|
|
386
|
+
type: 'text',
|
|
387
|
+
text: `⚠️ Impact Analysis for ${change_type} operation:
|
|
388
|
+
|
|
389
|
+
🎯 **Target Artifact:** ${artifact_id}
|
|
390
|
+
|
|
391
|
+
📊 **Impact Summary:**
|
|
392
|
+
- Affected artifacts: ${impactedArtifacts.length}
|
|
393
|
+
- Risk level: ${riskLevel}
|
|
394
|
+
- Change type: ${change_type}
|
|
395
|
+
|
|
396
|
+
🔗 **Affected Artifacts:**
|
|
397
|
+
${impactedArtifacts.map((a) => `- ${a.artifact.type}: ${a.artifact.name} (Impact: ${a.impact})`).join('\n')}
|
|
398
|
+
|
|
399
|
+
⚡ **Recommendations:**
|
|
400
|
+
${riskLevel === 'HIGH' ? '- Create comprehensive test plan\n- Consider phased deployment\n- Notify all stakeholders' :
|
|
401
|
+
riskLevel === 'MEDIUM' ? '- Test affected components\n- Review integration points' :
|
|
402
|
+
'- Safe to proceed with standard testing'}
|
|
403
|
+
|
|
404
|
+
🛡️ **Safety Measures:**
|
|
405
|
+
- ${change_type === 'delete' ? 'Archive artifact before deletion' : 'Create backup before modification'}
|
|
406
|
+
- Update all dependent artifacts
|
|
407
|
+
- Run integration tests`
|
|
408
|
+
}]
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
finally {
|
|
412
|
+
await session.close();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
async suggestArtifacts(args) {
|
|
416
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
417
|
+
return this.createFallbackResponse('snow_graph_suggest_artifacts');
|
|
418
|
+
}
|
|
419
|
+
const session = this.driver.session();
|
|
420
|
+
try {
|
|
421
|
+
const { context, artifact_type, requirements = [] } = args;
|
|
422
|
+
// Find similar contexts and successful patterns
|
|
423
|
+
const result = await session.run(`
|
|
424
|
+
MATCH (a:Artifact)
|
|
425
|
+
WHERE a.purpose CONTAINS $context
|
|
426
|
+
${artifact_type ? 'AND a.type = $artifactType' : ''}
|
|
427
|
+
WITH a
|
|
428
|
+
MATCH (a)-[r]-(related:Artifact)
|
|
429
|
+
RETURN a, collect(related) as related_artifacts
|
|
430
|
+
ORDER BY a.deployment_count DESC, a.success_rate DESC
|
|
431
|
+
LIMIT 10
|
|
432
|
+
`, { context, artifactType: artifact_type });
|
|
433
|
+
const suggestions = result.records.map((r) => ({
|
|
434
|
+
artifact: r.get('a').properties,
|
|
435
|
+
related: r.get('related_artifacts').map((n) => n.properties)
|
|
436
|
+
}));
|
|
437
|
+
return {
|
|
438
|
+
content: [{
|
|
439
|
+
type: 'text',
|
|
440
|
+
text: `🤖 AI-Powered Artifact Suggestions:
|
|
441
|
+
|
|
442
|
+
📋 **Context:** ${context}
|
|
443
|
+
${artifact_type ? `📦 **Type:** ${artifact_type}` : ''}
|
|
444
|
+
|
|
445
|
+
✨ **Recommended Artifacts:**
|
|
446
|
+
${suggestions.map((s, i) => `
|
|
447
|
+
${i + 1}. **${s.artifact.name}** (${s.artifact.type})
|
|
448
|
+
- Purpose: ${s.artifact.purpose || 'General purpose'}
|
|
449
|
+
- Success rate: ${s.artifact.success_rate || 'Not measured'}%
|
|
450
|
+
- Used with: ${s.related.map((r) => r.name).join(', ')}
|
|
451
|
+
`).join('\n')}
|
|
452
|
+
|
|
453
|
+
🎯 **Pattern Analysis:**
|
|
454
|
+
- Most successful pattern: ${suggestions[0]?.artifact.name || 'No patterns found'}
|
|
455
|
+
- Common dependencies: ${this.findCommonDependencies(suggestions)}
|
|
456
|
+
- Recommended architecture: ${this.suggestArchitecture(suggestions)}
|
|
457
|
+
|
|
458
|
+
💡 **Implementation Tips:**
|
|
459
|
+
- Start with the highest success rate artifact
|
|
460
|
+
- Check compatibility with existing components
|
|
461
|
+
- Consider the related artifacts for complete solution`
|
|
462
|
+
}]
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
finally {
|
|
466
|
+
await session.close();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
findCommonDependencies(suggestions) {
|
|
470
|
+
const deps = new Map();
|
|
471
|
+
suggestions.forEach((s) => {
|
|
472
|
+
s.related.forEach((r) => {
|
|
473
|
+
deps.set(r.name, (deps.get(r.name) || 0) + 1);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
const sorted = Array.from(deps.entries())
|
|
477
|
+
.sort((a, b) => b[1] - a[1])
|
|
478
|
+
.slice(0, 3)
|
|
479
|
+
.map(([name]) => name);
|
|
480
|
+
return sorted.join(', ') || 'None identified';
|
|
481
|
+
}
|
|
482
|
+
suggestArchitecture(suggestions) {
|
|
483
|
+
const types = suggestions.map(s => s.artifact.type);
|
|
484
|
+
if (types.includes('flow') && types.includes('script_include')) {
|
|
485
|
+
return 'Flow-based with script include utilities';
|
|
486
|
+
}
|
|
487
|
+
else if (types.includes('widget') && types.includes('client_script')) {
|
|
488
|
+
return 'UI-centric with client-side logic';
|
|
489
|
+
}
|
|
490
|
+
else if (types.includes('business_rule')) {
|
|
491
|
+
return 'Event-driven with business rules';
|
|
492
|
+
}
|
|
493
|
+
return 'Standard ServiceNow pattern';
|
|
494
|
+
}
|
|
495
|
+
async analyzePatterns(args) {
|
|
496
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
497
|
+
return this.createFallbackResponse('snow_graph_pattern_analysis');
|
|
498
|
+
}
|
|
499
|
+
const session = this.driver.session();
|
|
500
|
+
try {
|
|
501
|
+
const { pattern_type = 'architectural', min_occurrences = 3 } = args;
|
|
502
|
+
// This would be more sophisticated in production
|
|
503
|
+
const query = pattern_type === 'architectural' ? `
|
|
504
|
+
MATCH (a:Artifact)-[r]->(b:Artifact)
|
|
505
|
+
WITH type(r) as relType, a.type as sourceType, b.type as targetType, count(*) as occurrences
|
|
506
|
+
WHERE occurrences >= $minOccurrences
|
|
507
|
+
RETURN sourceType, relType, targetType, occurrences
|
|
508
|
+
ORDER BY occurrences DESC
|
|
509
|
+
` : `
|
|
510
|
+
MATCH (a:Artifact)
|
|
511
|
+
WHERE a.content IS NOT NULL
|
|
512
|
+
RETURN a.type, count(*) as count
|
|
513
|
+
ORDER BY count DESC
|
|
514
|
+
`;
|
|
515
|
+
const result = await session.run(query, { minOccurrences: min_occurrences });
|
|
516
|
+
return {
|
|
517
|
+
content: [{
|
|
518
|
+
type: 'text',
|
|
519
|
+
text: `🔍 Pattern Analysis Results:
|
|
520
|
+
|
|
521
|
+
📊 **Pattern Type:** ${pattern_type}
|
|
522
|
+
🔢 **Minimum Occurrences:** ${min_occurrences}
|
|
523
|
+
|
|
524
|
+
📈 **Discovered Patterns:**
|
|
525
|
+
${result.records.map((r) => {
|
|
526
|
+
if (pattern_type === 'architectural') {
|
|
527
|
+
return `- ${r.get('sourceType')} → ${r.get('relType')} → ${r.get('targetType')} (${r.get('occurrences')} times)`;
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
return `- ${r.get('type')}: ${r.get('count')} artifacts`;
|
|
531
|
+
}
|
|
532
|
+
}).join('\n')}
|
|
533
|
+
|
|
534
|
+
💡 **Insights:**
|
|
535
|
+
- Most common pattern: ${result.records[0] ? this.describePattern(result.records[0], pattern_type) : 'No patterns found'}
|
|
536
|
+
- Recommended approach: Follow the established patterns for consistency
|
|
537
|
+
- Optimization opportunity: Reuse common patterns as templates`
|
|
538
|
+
}]
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
finally {
|
|
542
|
+
await session.close();
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
describePattern(record, patternType) {
|
|
546
|
+
if (patternType === 'architectural') {
|
|
547
|
+
return `${record.get('sourceType')} components typically ${record.get('relType').toLowerCase()} ${record.get('targetType')} components`;
|
|
548
|
+
}
|
|
549
|
+
return `${record.get('type')} is the most common artifact type`;
|
|
550
|
+
}
|
|
551
|
+
async generateVisualization(args) {
|
|
552
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
553
|
+
return this.createFallbackResponse('snow_graph_visualize');
|
|
554
|
+
}
|
|
555
|
+
const { focus_artifact, include_types = [], max_nodes = 50 } = args;
|
|
556
|
+
const typeFilter = include_types.length > 0
|
|
557
|
+
? `WHERE n.type IN [${include_types.map((t) => `'${t}'`).join(', ')}]`
|
|
558
|
+
: '';
|
|
559
|
+
const cypherQuery = focus_artifact ? `
|
|
560
|
+
MATCH (center:Artifact {id: '${focus_artifact}'})
|
|
561
|
+
CALL apoc.path.subgraphAll(center, {
|
|
562
|
+
maxLevel: 3,
|
|
563
|
+
limit: ${max_nodes}
|
|
564
|
+
})
|
|
565
|
+
YIELD nodes, relationships
|
|
566
|
+
${typeFilter}
|
|
567
|
+
RETURN nodes, relationships
|
|
568
|
+
` : `
|
|
569
|
+
MATCH (n:Artifact)
|
|
570
|
+
${typeFilter}
|
|
571
|
+
WITH n LIMIT ${max_nodes}
|
|
572
|
+
MATCH (n)-[r]-(m:Artifact)
|
|
573
|
+
RETURN n, r, m
|
|
574
|
+
`;
|
|
575
|
+
return {
|
|
576
|
+
content: [{
|
|
577
|
+
type: 'text',
|
|
578
|
+
text: `🎨 Graph Visualization Query:
|
|
579
|
+
|
|
580
|
+
\`\`\`cypher
|
|
581
|
+
${cypherQuery}
|
|
582
|
+
\`\`\`
|
|
583
|
+
|
|
584
|
+
📊 **Visualization Settings:**
|
|
585
|
+
- Focus: ${focus_artifact || 'All artifacts'}
|
|
586
|
+
- Types: ${include_types.join(', ') || 'All types'}
|
|
587
|
+
- Max nodes: ${max_nodes}
|
|
588
|
+
|
|
589
|
+
🖥️ **To Visualize:**
|
|
590
|
+
1. Open Neo4j Browser
|
|
591
|
+
2. Paste the query above
|
|
592
|
+
3. Click Run
|
|
593
|
+
4. Use the graph view for interactive exploration
|
|
594
|
+
|
|
595
|
+
🎯 **Visualization Tips:**
|
|
596
|
+
- Click nodes to see properties
|
|
597
|
+
- Drag nodes to rearrange
|
|
598
|
+
- Double-click to expand connections
|
|
599
|
+
- Use filters to focus on specific relationships`
|
|
600
|
+
}]
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
async exportKnowledge(args) {
|
|
604
|
+
if (!this.neo4jAvailable || !this.driver) {
|
|
605
|
+
return this.createFallbackResponse('snow_graph_export_knowledge');
|
|
606
|
+
}
|
|
607
|
+
const session = this.driver.session();
|
|
608
|
+
try {
|
|
609
|
+
const { format = 'json', include_content = false } = args;
|
|
610
|
+
if (format === 'cypher') {
|
|
611
|
+
return {
|
|
612
|
+
content: [{
|
|
613
|
+
type: 'text',
|
|
614
|
+
text: `📤 Export Script (Cypher):
|
|
615
|
+
|
|
616
|
+
\`\`\`cypher
|
|
617
|
+
// Create indexes
|
|
618
|
+
CREATE INDEX artifact_id IF NOT EXISTS FOR (a:Artifact) ON (a.id);
|
|
619
|
+
CREATE INDEX artifact_type IF NOT EXISTS FOR (a:Artifact) ON (a.type);
|
|
620
|
+
|
|
621
|
+
// Export all artifacts
|
|
622
|
+
MATCH (a:Artifact)
|
|
623
|
+
RETURN a.id, a.name, a.type, a.purpose${include_content ? ', a.content' : ''};
|
|
624
|
+
|
|
625
|
+
// Export all relationships
|
|
626
|
+
MATCH (a:Artifact)-[r]->(b:Artifact)
|
|
627
|
+
RETURN a.id, type(r), b.id, r.data_flow;
|
|
628
|
+
\`\`\`
|
|
629
|
+
|
|
630
|
+
💾 **Usage:**
|
|
631
|
+
1. Run in target Neo4j instance
|
|
632
|
+
2. Import will recreate the knowledge graph
|
|
633
|
+
3. All patterns and relationships preserved`
|
|
634
|
+
}]
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
const artifacts = await session.run('MATCH (a:Artifact) RETURN a');
|
|
639
|
+
const relationships = await session.run('MATCH (a:Artifact)-[r]->(b:Artifact) RETURN a.id as from, type(r) as type, b.id as to');
|
|
640
|
+
const exportData = {
|
|
641
|
+
artifacts: artifacts.records.map((r) => r.get('a').properties),
|
|
642
|
+
relationships: relationships.records.map((r) => ({
|
|
643
|
+
from: r.get('from'),
|
|
644
|
+
type: r.get('type'),
|
|
645
|
+
to: r.get('to')
|
|
646
|
+
})),
|
|
647
|
+
metadata: {
|
|
648
|
+
exported_at: new Date().toISOString(),
|
|
649
|
+
total_artifacts: artifacts.records.length,
|
|
650
|
+
total_relationships: relationships.records.length
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
return {
|
|
654
|
+
content: [{
|
|
655
|
+
type: 'text',
|
|
656
|
+
text: `📤 Knowledge Export Complete:
|
|
657
|
+
|
|
658
|
+
\`\`\`json
|
|
659
|
+
${JSON.stringify(exportData, null, 2).substring(0, 1000)}...
|
|
660
|
+
\`\`\`
|
|
661
|
+
|
|
662
|
+
📊 **Export Summary:**
|
|
663
|
+
- Format: ${format}
|
|
664
|
+
- Artifacts: ${exportData.metadata.total_artifacts}
|
|
665
|
+
- Relationships: ${exportData.metadata.total_relationships}
|
|
666
|
+
- Content included: ${include_content ? 'Yes' : 'No'}
|
|
667
|
+
|
|
668
|
+
💾 **Next Steps:**
|
|
669
|
+
1. Save the export to a file
|
|
670
|
+
2. Use for backup or migration
|
|
671
|
+
3. Share with team members
|
|
672
|
+
4. Import into another instance`
|
|
673
|
+
}]
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
finally {
|
|
678
|
+
await session.close();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
async start() {
|
|
682
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
683
|
+
await this.server.connect(transport);
|
|
684
|
+
this.logger.info('ServiceNow Graph Memory MCP Server started');
|
|
685
|
+
}
|
|
686
|
+
async stop() {
|
|
687
|
+
if (this.driver) {
|
|
688
|
+
await this.driver.close();
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
// Start the server
|
|
693
|
+
const server = new ServiceNowGraphMemoryMCP();
|
|
694
|
+
server.start().catch((error) => {
|
|
695
|
+
console.error('Failed to start ServiceNow Graph Memory MCP:', error);
|
|
696
|
+
process.exit(1);
|
|
697
|
+
});
|
|
698
|
+
// Graceful shutdown
|
|
699
|
+
process.on('SIGINT', async () => {
|
|
700
|
+
await server.stop();
|
|
701
|
+
process.exit(0);
|
|
702
|
+
});
|
|
703
|
+
//# sourceMappingURL=servicenow-graph-memory-mcp.js.map
|