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
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "servicenow-mcp-server",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Multi-instance ServiceNow MCP server with 40+ tools, natural language search, and local script development",
|
|
5
|
+
"main": "src/server.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"mcpName": "io.github.happy-technologies-llc/mcp-servicenow-nodejs",
|
|
8
|
+
"bin": {
|
|
9
|
+
"servicenow-mcp-server": "./src/stdio-server.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "nodemon src/server.js",
|
|
13
|
+
"start": "node src/server.js",
|
|
14
|
+
"stdio": "node src/stdio-server.js",
|
|
15
|
+
"inspector": "npx @modelcontextprotocol/inspector",
|
|
16
|
+
"extract-metadata": "node scripts/extract-table-metadata.js",
|
|
17
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
18
|
+
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
|
|
19
|
+
"test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest --coverage",
|
|
20
|
+
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
24
|
+
"axios": "^1.6.0",
|
|
25
|
+
"chokidar": "^4.0.3",
|
|
26
|
+
"dotenv": "^16.3.1",
|
|
27
|
+
"express": "^4.18.2",
|
|
28
|
+
"zod": "^3.22.4"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/jest": "^30.0.0",
|
|
32
|
+
"jest": "^30.2.0",
|
|
33
|
+
"nodemon": "^3.0.2"
|
|
34
|
+
},
|
|
35
|
+
"author": "Happy Technologies LLC",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/Happy-Technologies-LLC/mcp-servicenow-nodejs.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/Happy-Technologies-LLC/mcp-servicenow-nodejs/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/Happy-Technologies-LLC/mcp-servicenow-nodejs#readme",
|
|
45
|
+
"keywords": [
|
|
46
|
+
"mcp",
|
|
47
|
+
"modelcontextprotocol",
|
|
48
|
+
"servicenow",
|
|
49
|
+
"itsm",
|
|
50
|
+
"claude",
|
|
51
|
+
"ai",
|
|
52
|
+
"automation",
|
|
53
|
+
"rest-api",
|
|
54
|
+
"service-catalog",
|
|
55
|
+
"cmdb",
|
|
56
|
+
"workflow",
|
|
57
|
+
"flow-designer",
|
|
58
|
+
"update-set",
|
|
59
|
+
"multi-instance"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Script
|
|
3
|
+
* Created: 2025-09-29T20:19:35.102Z
|
|
4
|
+
* Description: Set Integration Governance Framework as current update set
|
|
5
|
+
*
|
|
6
|
+
* INSTRUCTIONS:
|
|
7
|
+
* 1. Copy the script below
|
|
8
|
+
* 2. Navigate to ServiceNow: System Definition → Scripts - Background
|
|
9
|
+
* 3. Paste the script
|
|
10
|
+
* 4. Click "Run script"
|
|
11
|
+
* 5. Verify output in the output panel
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
var updateSetSysId = '3ddbc8edc3d432101fcbbd43e4013124';
|
|
15
|
+
var gr = new GlideRecord('sys_update_set');
|
|
16
|
+
if (gr.get(updateSetSysId)) {
|
|
17
|
+
gs.setUpdateSet(gr);
|
|
18
|
+
gs.print('✅ Update set changed to: ' + gr.name);
|
|
19
|
+
} else {
|
|
20
|
+
gs.print('❌ Update set not found: ' + updateSetSysId);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// End of script
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Script: link_ui_policy_actions
|
|
3
|
+
* Created: 2025-09-29T20:17:15.218Z
|
|
4
|
+
* Description: Link UI Policy Actions to their respective policies and variables
|
|
5
|
+
*
|
|
6
|
+
* INSTRUCTIONS:
|
|
7
|
+
* 1. Copy the entire script below
|
|
8
|
+
* 2. Navigate to ServiceNow: System Definition → Scripts - Background
|
|
9
|
+
* 3. Paste the script
|
|
10
|
+
* 4. Click "Run script"
|
|
11
|
+
* 5. Verify output in the output panel
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Map of UI Policy Action sys_id to configuration
|
|
16
|
+
var actions = {
|
|
17
|
+
// Policy 1: Show Tier 1 API Fields
|
|
18
|
+
'a7ac4c21c31832101fcbbd43e40131e5': {
|
|
19
|
+
ui_policy: '379c8061c31832101fcbbd43e401310f',
|
|
20
|
+
catalog_variable: 'IO:387c4c21c31832101fcbbd43e4013199',
|
|
21
|
+
variable: 'api_offering'
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
// Policy 2: Show Custom Integration Fields
|
|
25
|
+
'27ac0461c31832101fcbbd43e401319f': {
|
|
26
|
+
ui_policy: '739c8061c31832101fcbbd43e40131eb',
|
|
27
|
+
catalog_variable: 'IO:457c4c21c31832101fcbbd43e40131cd',
|
|
28
|
+
variable: 'target_system'
|
|
29
|
+
},
|
|
30
|
+
'27ac0461c31832101fcbbd43e40131a4': {
|
|
31
|
+
ui_policy: '739c8061c31832101fcbbd43e40131eb',
|
|
32
|
+
catalog_variable: 'IO:017c4c21c31832101fcbbd43e40131d9',
|
|
33
|
+
variable: 'requested_integration_tier'
|
|
34
|
+
},
|
|
35
|
+
'ebac0461c31832101fcbbd43e40131b5': {
|
|
36
|
+
ui_policy: '739c8061c31832101fcbbd43e40131eb',
|
|
37
|
+
catalog_variable: 'IO:517c082dc3d432101fcbbd43e40131dd',
|
|
38
|
+
variable: 'tier_1_justification'
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Policy 3: Show Data Protection Fields
|
|
42
|
+
'ebac0461c31832101fcbbd43e40131ba': {
|
|
43
|
+
ui_policy: 'ccac8061c31832101fcbbd43e40131f2',
|
|
44
|
+
catalog_variable: 'IO:657c8c21c31832101fcbbd43e401313f',
|
|
45
|
+
variable: 'lawful_basis'
|
|
46
|
+
},
|
|
47
|
+
'fbac0461c31832101fcbbd43e40131bf': {
|
|
48
|
+
ui_policy: 'ccac8061c31832101fcbbd43e40131f2',
|
|
49
|
+
catalog_variable: 'IO:f57c8c21c31832101fcbbd43e4013159',
|
|
50
|
+
variable: 'data_retention_period'
|
|
51
|
+
},
|
|
52
|
+
'fbac0461c31832101fcbbd43e40131c4': {
|
|
53
|
+
ui_policy: 'ccac8061c31832101fcbbd43e40131f2',
|
|
54
|
+
catalog_variable: 'IO:fd7c8c21c31832101fcbbd43e4013173',
|
|
55
|
+
variable: 'third_party_sharing'
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
gs.print('\n========================================');
|
|
60
|
+
gs.print('Linking UI Policy Actions');
|
|
61
|
+
gs.print('========================================\n');
|
|
62
|
+
|
|
63
|
+
var updateCount = 0;
|
|
64
|
+
var failCount = 0;
|
|
65
|
+
|
|
66
|
+
for (var sysId in actions) {
|
|
67
|
+
var gr = new GlideRecord('catalog_ui_policy_action');
|
|
68
|
+
if (gr.get(sysId)) {
|
|
69
|
+
gr.setValue('ui_policy', actions[sysId].ui_policy);
|
|
70
|
+
gr.setValue('catalog_variable', actions[sysId].catalog_variable);
|
|
71
|
+
gr.setValue('variable', actions[sysId].variable);
|
|
72
|
+
gr.update();
|
|
73
|
+
updateCount++;
|
|
74
|
+
gs.print('✅ Updated: ' + actions[sysId].variable + ' (' + sysId + ')');
|
|
75
|
+
} else {
|
|
76
|
+
failCount++;
|
|
77
|
+
gs.print('❌ NOT FOUND: ' + sysId);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
gs.print('\n========================================');
|
|
82
|
+
gs.print('Summary');
|
|
83
|
+
gs.print('========================================');
|
|
84
|
+
gs.print('✅ Successfully updated: ' + updateCount + ' actions');
|
|
85
|
+
if (failCount > 0) {
|
|
86
|
+
gs.print('❌ Failed to update: ' + failCount + ' actions');
|
|
87
|
+
}
|
|
88
|
+
gs.print('========================================\n');
|
|
89
|
+
|
|
90
|
+
// End of script
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Script: Set Current Update Set
|
|
3
|
+
* Update Set: Integration Governance Framework
|
|
4
|
+
* Update Set sys_id: 83f8cca9c3d432101fcbbd43e4013173
|
|
5
|
+
* Created: 2025-09-29T19:47:06.792Z
|
|
6
|
+
*
|
|
7
|
+
* INSTRUCTIONS:
|
|
8
|
+
* 1. Copy the entire script below
|
|
9
|
+
* 2. Navigate to ServiceNow: System Definition → Scripts - Background
|
|
10
|
+
* 3. Paste the script
|
|
11
|
+
* 4. Click "Run script"
|
|
12
|
+
* 5. Verify output shows: "Update set changed to: Integration Governance Framework"
|
|
13
|
+
* 6. Delete this file after successful execution
|
|
14
|
+
*
|
|
15
|
+
* ALTERNATIVE: Set manually via UI
|
|
16
|
+
* 1. Navigate to: System Update Sets → Local Update Sets
|
|
17
|
+
* 2. Find update set: Integration Governance Framework
|
|
18
|
+
* 3. Click "Make this my current set"
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var updateSetSysId = '83f8cca9c3d432101fcbbd43e4013173';
|
|
22
|
+
var gr = new GlideRecord('sys_update_set');
|
|
23
|
+
if (gr.get(updateSetSysId)) {
|
|
24
|
+
gs.setUpdateSet(gr);
|
|
25
|
+
gs.info('✅ Update set changed to: ' + gr.name);
|
|
26
|
+
} else {
|
|
27
|
+
gs.error('❌ Update set not found: ' + updateSetSysId);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// End of script
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Script: Set Current Update Set
|
|
3
|
+
* Update Set: Integration Governance Framework
|
|
4
|
+
* Update Set sys_id: 3ddbc8edc3d432101fcbbd43e4013124
|
|
5
|
+
* Created: 2025-09-29T19:59:33.155Z
|
|
6
|
+
*
|
|
7
|
+
* INSTRUCTIONS:
|
|
8
|
+
* 1. Copy the entire script below
|
|
9
|
+
* 2. Navigate to ServiceNow: System Definition → Scripts - Background
|
|
10
|
+
* 3. Paste the script
|
|
11
|
+
* 4. Click "Run script"
|
|
12
|
+
* 5. Verify output shows: "Update set changed to: Integration Governance Framework"
|
|
13
|
+
* 6. Delete this file after successful execution
|
|
14
|
+
*
|
|
15
|
+
* ALTERNATIVE: Set manually via UI
|
|
16
|
+
* 1. Navigate to: System Update Sets → Local Update Sets
|
|
17
|
+
* 2. Find update set: Integration Governance Framework
|
|
18
|
+
* 3. Click "Make this my current set"
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var updateSetSysId = '3ddbc8edc3d432101fcbbd43e4013124';
|
|
22
|
+
var gr = new GlideRecord('sys_update_set');
|
|
23
|
+
if (gr.get(updateSetSysId)) {
|
|
24
|
+
gs.setUpdateSet(gr);
|
|
25
|
+
gs.info('✅ Update set changed to: ' + gr.name);
|
|
26
|
+
} else {
|
|
27
|
+
gs.error('❌ Update set not found: ' + updateSetSysId);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// End of script
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Script: set_update_set_current
|
|
3
|
+
* Created: 2025-09-29T20:16:59.676Z
|
|
4
|
+
* Description: Set Integration Governance Framework as current update set
|
|
5
|
+
*
|
|
6
|
+
* INSTRUCTIONS:
|
|
7
|
+
* 1. Copy the entire script below
|
|
8
|
+
* 2. Navigate to ServiceNow: System Definition → Scripts - Background
|
|
9
|
+
* 3. Paste the script
|
|
10
|
+
* 4. Click "Run script"
|
|
11
|
+
* 5. Verify output in the output panel
|
|
12
|
+
* 6. Delete this file after successful execution
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
var updateSetSysId = '3ddbc8edc3d432101fcbbd43e4013124';
|
|
16
|
+
var gr = new GlideRecord('sys_update_set');
|
|
17
|
+
if (gr.get(updateSetSysId)) {
|
|
18
|
+
gs.setUpdateSet(gr);
|
|
19
|
+
gs.print('✅ Update set changed to: ' + gr.name);
|
|
20
|
+
} else {
|
|
21
|
+
gs.print('❌ Update set not found: ' + updateSetSysId);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// End of script
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Script: Diagnose sys_dictionary 403 Error
|
|
3
|
+
*
|
|
4
|
+
* Run this in ServiceNow: System Definition → Scripts - Background
|
|
5
|
+
* This will help identify WHY admin is getting 403
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Test 1: Can we create via GlideRecord (server-side)?
|
|
9
|
+
gs.info('=== Test 1: Create via GlideRecord ===');
|
|
10
|
+
try {
|
|
11
|
+
var gr = new GlideRecord('sys_dictionary');
|
|
12
|
+
gr.initialize();
|
|
13
|
+
gr.name = 'incident';
|
|
14
|
+
gr.element = 'u_test_field_' + gs.nowDateTime();
|
|
15
|
+
gr.column_label = 'Test Field ' + gs.nowDateTime();
|
|
16
|
+
gr.internal_type = 'string';
|
|
17
|
+
gr.max_length = 40;
|
|
18
|
+
|
|
19
|
+
var sysId = gr.insert();
|
|
20
|
+
if (sysId) {
|
|
21
|
+
gs.info('✅ SUCCESS: Created via GlideRecord: ' + sysId);
|
|
22
|
+
|
|
23
|
+
// Clean up
|
|
24
|
+
gr.get(sysId);
|
|
25
|
+
gr.deleteRecord();
|
|
26
|
+
gs.info('✅ Cleaned up test record');
|
|
27
|
+
} else {
|
|
28
|
+
gs.error('❌ FAILED: Could not create via GlideRecord');
|
|
29
|
+
}
|
|
30
|
+
} catch(e) {
|
|
31
|
+
gs.error('❌ EXCEPTION in GlideRecord: ' + e.message);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Test 2: Check current user roles
|
|
35
|
+
gs.info('=== Test 2: Current User Roles ===');
|
|
36
|
+
var userRoles = gs.getUser().getRoles();
|
|
37
|
+
gs.info('Current user: ' + gs.getUserName());
|
|
38
|
+
gs.info('Has admin role: ' + gs.getUser().hasRole('admin'));
|
|
39
|
+
gs.info('Has security_admin role: ' + gs.getUser().hasRole('security_admin'));
|
|
40
|
+
gs.info('Has personalize_dictionary role: ' + gs.getUser().hasRole('personalize_dictionary'));
|
|
41
|
+
gs.info('All roles: ' + userRoles);
|
|
42
|
+
|
|
43
|
+
// Test 3: Check ACLs on sys_dictionary
|
|
44
|
+
gs.info('=== Test 3: ACLs on sys_dictionary ===');
|
|
45
|
+
var acl = new GlideRecord('sys_security_acl');
|
|
46
|
+
acl.addQuery('name', 'sys_dictionary');
|
|
47
|
+
acl.query();
|
|
48
|
+
gs.info('Found ' + acl.getRowCount() + ' ACLs for sys_dictionary');
|
|
49
|
+
while (acl.next()) {
|
|
50
|
+
gs.info('ACL: ' + acl.operation + ' - Roles: ' + acl.roles);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Test 4: Check if update set is needed
|
|
54
|
+
gs.info('=== Test 4: Current Update Set ===');
|
|
55
|
+
var updateSet = gs.getUpdateSet();
|
|
56
|
+
gs.info('Current update set: ' + updateSet.name + ' (' + updateSet.sys_id + ')');
|
|
57
|
+
|
|
58
|
+
// Test 5: Try with elevated privileges
|
|
59
|
+
gs.info('=== Test 5: Test with setCanWriteToSystemFields ===');
|
|
60
|
+
var grAdmin = new GlideRecordSecure('sys_dictionary');
|
|
61
|
+
grAdmin.setWorkflow(false);
|
|
62
|
+
grAdmin.initialize();
|
|
63
|
+
grAdmin.name = 'incident';
|
|
64
|
+
grAdmin.element = 'u_admin_test_' + gs.nowDateTime();
|
|
65
|
+
grAdmin.column_label = 'Admin Test';
|
|
66
|
+
grAdmin.internal_type = 'string';
|
|
67
|
+
grAdmin.max_length = 40;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
var adminSysId = grAdmin.insert();
|
|
71
|
+
if (adminSysId) {
|
|
72
|
+
gs.info('✅ SUCCESS with GlideRecordSecure: ' + adminSysId);
|
|
73
|
+
grAdmin.get(adminSysId);
|
|
74
|
+
grAdmin.deleteRecord();
|
|
75
|
+
} else {
|
|
76
|
+
gs.error('❌ FAILED with GlideRecordSecure');
|
|
77
|
+
}
|
|
78
|
+
} catch(e) {
|
|
79
|
+
gs.error('❌ EXCEPTION with GlideRecordSecure: ' + e.message);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
gs.info('=== Diagnosis Complete ===');
|
|
83
|
+
gs.info('If Test 1 succeeded: 403 is REST API ACL issue, not server-side restriction');
|
|
84
|
+
gs.info('If Test 1 failed: System-level restriction (contact ServiceNow admin)');
|
|
85
|
+
gs.info('Check roles in Test 2 - ensure admin/personalize_dictionary present');
|