servicenow-mcp-server 2.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/.claude/settings.local.json +70 -0
- package/CLAUDE.md +777 -0
- package/LICENSE +21 -0
- package/README.md +562 -0
- package/assets/logo.svg +385 -0
- package/config/servicenow-instances.json.example +28 -0
- package/docs/403_TROUBLESHOOTING.md +329 -0
- package/docs/API_REFERENCE.md +1142 -0
- package/docs/APPLICATION_SCOPE_VALIDATION.md +681 -0
- package/docs/CLAUDE_DESKTOP_SETUP.md +373 -0
- package/docs/CONVENIENCE_TOOLS.md +601 -0
- package/docs/CONVENIENCE_TOOLS_SUMMARY.md +371 -0
- package/docs/FLOW_DESIGNER_GUIDE.md +1021 -0
- package/docs/IMPLEMENTATION_COMPLETE.md +165 -0
- package/docs/INSTANCE_SWITCHING_GUIDE.md +219 -0
- package/docs/MULTI_INSTANCE_CONFIGURATION.md +185 -0
- package/docs/NATURAL_LANGUAGE_SEARCH_IMPLEMENTATION.md +221 -0
- package/docs/PUPPETEER_INTEGRATION_PROPOSAL.md +1322 -0
- package/docs/QUICK_REFERENCE.md +395 -0
- package/docs/README.md +75 -0
- package/docs/RESOURCES_ARCHITECTURE.md +392 -0
- package/docs/RESOURCES_IMPLEMENTATION.md +276 -0
- package/docs/RESOURCES_SUMMARY.md +104 -0
- package/docs/SETUP_GUIDE.md +104 -0
- package/docs/UI_OPERATIONS_ARCHITECTURE.md +1219 -0
- package/docs/UI_OPERATIONS_DECISION_MATRIX.md +542 -0
- package/docs/UI_OPERATIONS_SUMMARY.md +507 -0
- package/docs/UPDATE_SET_VALIDATION.md +598 -0
- package/docs/UPDATE_SET_VALIDATION_SUMMARY.md +209 -0
- package/docs/VALIDATION_SUMMARY.md +479 -0
- package/jest.config.js +24 -0
- package/package.json +61 -0
- package/scripts/background_script_2025-09-29T20-19-35-101Z.js +23 -0
- package/scripts/link_ui_policy_actions_2025-09-29T20-17-15-218Z.js +90 -0
- package/scripts/set_update_set_Integration_Governance_Framework_2025-09-29T19-47-06-790Z.js +30 -0
- package/scripts/set_update_set_Integration_Governance_Framework_2025-09-29T19-59-33-152Z.js +30 -0
- package/scripts/set_update_set_current_2025-09-29T20-16-59-675Z.js +24 -0
- package/scripts/test_sys_dictionary_403.js +85 -0
- package/setup/setup-report.json +5313 -0
- package/src/config/comprehensive-table-definitions.json +2575 -0
- package/src/config/instance-config.json +4693 -0
- package/src/config/prompts.md +59 -0
- package/src/config/table-definitions.json +4681 -0
- package/src/config-manager.js +146 -0
- package/src/mcp-server-consolidated.js +2894 -0
- package/src/natural-language.js +472 -0
- package/src/resources.js +326 -0
- package/src/script-sync.js +428 -0
- package/src/server.js +125 -0
- package/src/servicenow-client.js +1625 -0
- package/src/stdio-server.js +52 -0
- package/start-mcp.sh +7 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceNow MCP Server - Multi-Instance Configuration Manager
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 Happy Technologies LLC
|
|
5
|
+
* Licensed under the MIT License - see LICENSE file for details
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
export class ConfigManager {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.configPath = path.join(__dirname, '../config/servicenow-instances.json');
|
|
18
|
+
this.instances = null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Load instances from JSON config file
|
|
23
|
+
*/
|
|
24
|
+
loadInstances() {
|
|
25
|
+
if (this.instances) {
|
|
26
|
+
return this.instances;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const configData = fs.readFileSync(this.configPath, 'utf8');
|
|
31
|
+
const config = JSON.parse(configData);
|
|
32
|
+
this.instances = config.instances;
|
|
33
|
+
return this.instances;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
// Fallback to .env if config file doesn't exist
|
|
36
|
+
if (error.code === 'ENOENT') {
|
|
37
|
+
console.warn('⚠️ servicenow-instances.json not found, falling back to .env');
|
|
38
|
+
return this.loadFromEnv();
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Failed to load ServiceNow instances config: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Fallback: Load single instance from .env file (backward compatibility)
|
|
46
|
+
*/
|
|
47
|
+
loadFromEnv() {
|
|
48
|
+
if (!process.env.SERVICENOW_INSTANCE_URL || !process.env.SERVICENOW_USERNAME || !process.env.SERVICENOW_PASSWORD) {
|
|
49
|
+
throw new Error('Missing ServiceNow credentials. Create config/servicenow-instances.json or set SERVICENOW_INSTANCE_URL, SERVICENOW_USERNAME, SERVICENOW_PASSWORD in .env');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.instances = [{
|
|
53
|
+
name: 'default',
|
|
54
|
+
url: process.env.SERVICENOW_INSTANCE_URL,
|
|
55
|
+
username: process.env.SERVICENOW_USERNAME,
|
|
56
|
+
password: process.env.SERVICENOW_PASSWORD,
|
|
57
|
+
default: true,
|
|
58
|
+
description: 'Loaded from .env'
|
|
59
|
+
}];
|
|
60
|
+
|
|
61
|
+
return this.instances;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get instance by name
|
|
66
|
+
* @param {string} name - Instance name
|
|
67
|
+
* @returns {object} Instance configuration
|
|
68
|
+
*/
|
|
69
|
+
getInstance(name) {
|
|
70
|
+
const instances = this.loadInstances();
|
|
71
|
+
const instance = instances.find(i => i.name === name);
|
|
72
|
+
|
|
73
|
+
if (!instance) {
|
|
74
|
+
throw new Error(`Instance '${name}' not found. Available instances: ${instances.map(i => i.name).join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return instance;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get default instance
|
|
82
|
+
* @returns {object} Default instance configuration
|
|
83
|
+
*/
|
|
84
|
+
getDefaultInstance() {
|
|
85
|
+
const instances = this.loadInstances();
|
|
86
|
+
const defaultInstance = instances.find(i => i.default === true);
|
|
87
|
+
|
|
88
|
+
if (!defaultInstance) {
|
|
89
|
+
// If no default is set, use the first instance
|
|
90
|
+
return instances[0];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return defaultInstance;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get instance by name or default if not specified
|
|
98
|
+
* @param {string} name - Optional instance name
|
|
99
|
+
* @returns {object} Instance configuration
|
|
100
|
+
*/
|
|
101
|
+
getInstanceOrDefault(name = null) {
|
|
102
|
+
if (name) {
|
|
103
|
+
return this.getInstance(name);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check for SERVICENOW_INSTANCE env variable
|
|
107
|
+
const envInstance = process.env.SERVICENOW_INSTANCE;
|
|
108
|
+
if (envInstance) {
|
|
109
|
+
return this.getInstance(envInstance);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return this.getDefaultInstance();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* List all available instances
|
|
117
|
+
* @returns {Array} List of instance names and descriptions
|
|
118
|
+
*/
|
|
119
|
+
listInstances() {
|
|
120
|
+
const instances = this.loadInstances();
|
|
121
|
+
return instances.map(i => ({
|
|
122
|
+
name: i.name,
|
|
123
|
+
url: i.url,
|
|
124
|
+
default: i.default || false,
|
|
125
|
+
description: i.description || ''
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validate instance configuration
|
|
131
|
+
* @param {object} instance - Instance configuration
|
|
132
|
+
* @returns {boolean} True if valid
|
|
133
|
+
*/
|
|
134
|
+
validateInstance(instance) {
|
|
135
|
+
const required = ['name', 'url', 'username', 'password'];
|
|
136
|
+
for (const field of required) {
|
|
137
|
+
if (!instance[field]) {
|
|
138
|
+
throw new Error(`Instance configuration missing required field: ${field}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Singleton instance
|
|
146
|
+
export const configManager = new ConfigManager();
|