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,392 @@
|
|
|
1
|
+
# MCP Resources Architecture
|
|
2
|
+
|
|
3
|
+
## Architecture Diagram
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ MCP Client │
|
|
8
|
+
│ (Claude Code / CLI) │
|
|
9
|
+
└───────────────────┬─────────────────────────────────────────┘
|
|
10
|
+
│
|
|
11
|
+
│ ListResources / ReadResource
|
|
12
|
+
│
|
|
13
|
+
┌───────────────────▼─────────────────────────────────────────┐
|
|
14
|
+
│ MCP Server │
|
|
15
|
+
│ (mcp-server-consolidated.js) │
|
|
16
|
+
│ │
|
|
17
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
18
|
+
│ │ Resource Request Handlers │ │
|
|
19
|
+
│ │ │ │
|
|
20
|
+
│ │ ListResourcesRequestSchema ──────┐ │ │
|
|
21
|
+
│ │ ReadResourceRequestSchema ──────┤ │ │
|
|
22
|
+
│ └────────────────────────────────────┼────────────────┘ │
|
|
23
|
+
│ │ │
|
|
24
|
+
│ ┌────────────────────────────────────▼────────────────┐ │
|
|
25
|
+
│ │ resources.js │ │
|
|
26
|
+
│ │ │ │
|
|
27
|
+
│ │ createResourceHandlers( │ │
|
|
28
|
+
│ │ serviceNowClient, │ │
|
|
29
|
+
│ │ configManager, │ │
|
|
30
|
+
│ │ tableMetadata │ │
|
|
31
|
+
│ │ ) │ │
|
|
32
|
+
│ │ │ │
|
|
33
|
+
│ │ ┌────────────────────────────────────────────┐ │ │
|
|
34
|
+
│ │ │ listResources() │ │ │
|
|
35
|
+
│ │ │ - Build resource list │ │ │
|
|
36
|
+
│ │ │ - Include all instances │ │ │
|
|
37
|
+
│ │ │ - Add metadata resources │ │ │
|
|
38
|
+
│ │ └────────────────────────────────────────────┘ │ │
|
|
39
|
+
│ │ │ │
|
|
40
|
+
│ │ ┌────────────────────────────────────────────┐ │ │
|
|
41
|
+
│ │ │ readResource(uri) │ │ │
|
|
42
|
+
│ │ │ 1. Parse URI │ │ │
|
|
43
|
+
│ │ │ 2. Route to handler │ │ │
|
|
44
|
+
│ │ │ 3. Switch instance if needed │ │ │
|
|
45
|
+
│ │ │ 4. Fetch data │ │ │
|
|
46
|
+
│ │ │ 5. Format with metadata │ │ │
|
|
47
|
+
│ │ │ 6. Restore original instance │ │ │
|
|
48
|
+
│ │ └────────────────────────────────────────────┘ │ │
|
|
49
|
+
│ └──────────────────────────────────────────────────────┘ │
|
|
50
|
+
└───────────────────┬─────────────────────────────────────────┘
|
|
51
|
+
│
|
|
52
|
+
┌───────────┼───────────┬────────────────┐
|
|
53
|
+
│ │ │ │
|
|
54
|
+
▼ ▼ ▼ ▼
|
|
55
|
+
┌──────────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────┐
|
|
56
|
+
│ServiceNow │ │Config │ │Table │ │Instance │
|
|
57
|
+
│Client │ │Manager │ │Metadata │ │Switching │
|
|
58
|
+
│ │ │ │ │ │ │ │
|
|
59
|
+
│- getRecords │ │- list │ │- schemas │ │- save │
|
|
60
|
+
│- getRecord │ │- get │ │- fields │ │- switch │
|
|
61
|
+
│- setInstance │ │- switch │ │- types │ │- restore │
|
|
62
|
+
└──────────────┘ └──────────┘ └──────────────┘ └──────────┘
|
|
63
|
+
│ │
|
|
64
|
+
└─────────────────────────────────────────────┘
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
┌────────────────────────────┐
|
|
68
|
+
│ ServiceNow REST API │
|
|
69
|
+
│ (Multiple Instances) │
|
|
70
|
+
│ │
|
|
71
|
+
│ - dev.service-now.com │
|
|
72
|
+
│ - test.service-now.com │
|
|
73
|
+
│ - prod.service-now.com │
|
|
74
|
+
└─────────────────────────────┘
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Resource URI Routing
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
servicenow://instances
|
|
81
|
+
│
|
|
82
|
+
└──> configManager.listInstances()
|
|
83
|
+
Return all configured instances
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
servicenow://tables
|
|
87
|
+
│
|
|
88
|
+
└──> tableMetadata
|
|
89
|
+
Return all table definitions
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
servicenow://{instance}/info
|
|
93
|
+
│
|
|
94
|
+
├──> configManager.getInstance(instance)
|
|
95
|
+
├──> serviceNowClient.getCurrentInstance()
|
|
96
|
+
└──> Format server info + capabilities
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
servicenow://{instance}/incidents
|
|
100
|
+
│
|
|
101
|
+
├──> Switch to instance (if needed)
|
|
102
|
+
├──> serviceNowClient.getRecords('incident', {...})
|
|
103
|
+
├──> Format with metadata
|
|
104
|
+
└──> Restore original instance
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
servicenow://{instance}/incidents/{number}
|
|
108
|
+
│
|
|
109
|
+
├──> Switch to instance (if needed)
|
|
110
|
+
├──> serviceNowClient.getRecords('incident', {query: 'number=...'})
|
|
111
|
+
├──> Format single record with metadata
|
|
112
|
+
└──> Restore original instance
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
servicenow://{instance}/update-sets/{sys_id}
|
|
116
|
+
│
|
|
117
|
+
├──> Switch to instance (if needed)
|
|
118
|
+
├──> serviceNowClient.getRecord('sys_update_set', sys_id)
|
|
119
|
+
├──> serviceNowClient.getRecords('sys_update_xml', {query: 'update_set=...'})
|
|
120
|
+
├──> Group by type, aggregate counts
|
|
121
|
+
├──> Format detailed breakdown
|
|
122
|
+
└──> Restore original instance
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Data Flow
|
|
126
|
+
|
|
127
|
+
### List Resources Request
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
Client Request
|
|
131
|
+
│
|
|
132
|
+
▼
|
|
133
|
+
MCP Server: ListResourcesRequestSchema
|
|
134
|
+
│
|
|
135
|
+
▼
|
|
136
|
+
resources.js: listResources()
|
|
137
|
+
│
|
|
138
|
+
├──> Get current instance
|
|
139
|
+
├──> Get all instances
|
|
140
|
+
├──> Build resource list
|
|
141
|
+
│ ├── Global resources (instances, tables)
|
|
142
|
+
│ ├── Current instance resources
|
|
143
|
+
│ └── Other instance resources
|
|
144
|
+
│
|
|
145
|
+
▼
|
|
146
|
+
Return: { resources: [...] }
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Read Resource Request
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Client Request: servicenow://dev/incidents
|
|
153
|
+
│
|
|
154
|
+
▼
|
|
155
|
+
MCP Server: ReadResourceRequestSchema
|
|
156
|
+
│
|
|
157
|
+
▼
|
|
158
|
+
resources.js: readResource(uri)
|
|
159
|
+
│
|
|
160
|
+
├──> Parse URI
|
|
161
|
+
│ ├── Extract instance: "dev"
|
|
162
|
+
│ └── Extract resource: "incidents"
|
|
163
|
+
│
|
|
164
|
+
├──> Save current instance
|
|
165
|
+
│
|
|
166
|
+
├──> Switch to requested instance
|
|
167
|
+
│ └──> serviceNowClient.setInstance(dev)
|
|
168
|
+
│
|
|
169
|
+
├──> Fetch data
|
|
170
|
+
│ └──> serviceNowClient.getRecords('incident', {
|
|
171
|
+
│ sysparm_query: 'active=true',
|
|
172
|
+
│ sysparm_limit: 25,
|
|
173
|
+
│ sysparm_fields: 'number,short_description,...'
|
|
174
|
+
│ })
|
|
175
|
+
│
|
|
176
|
+
├──> Format response
|
|
177
|
+
│ └──> {
|
|
178
|
+
│ metadata: {timestamp, instance, description, count},
|
|
179
|
+
│ data: [...]
|
|
180
|
+
│ }
|
|
181
|
+
│
|
|
182
|
+
├──> Restore original instance
|
|
183
|
+
│ └──> serviceNowClient.setInstance(original)
|
|
184
|
+
│
|
|
185
|
+
▼
|
|
186
|
+
Return: { contents: [{uri, mimeType, text}] }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Instance Switching Flow
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Request: servicenow://prod/incidents
|
|
193
|
+
(Current instance: dev)
|
|
194
|
+
|
|
195
|
+
1. Save current state
|
|
196
|
+
┌──────────────────────┐
|
|
197
|
+
│ originalInstance = │
|
|
198
|
+
│ name: 'dev' │
|
|
199
|
+
│ url: 'dev.sn.com' │
|
|
200
|
+
└──────────────────────┘
|
|
201
|
+
|
|
202
|
+
2. Switch to requested instance
|
|
203
|
+
┌──────────────────────┐
|
|
204
|
+
│ configManager.get │
|
|
205
|
+
│ Instance('prod') │
|
|
206
|
+
│ │
|
|
207
|
+
│ serviceNowClient. │
|
|
208
|
+
│ setInstance(...) │
|
|
209
|
+
└──────────────────────┘
|
|
210
|
+
|
|
211
|
+
3. Execute request
|
|
212
|
+
┌──────────────────────┐
|
|
213
|
+
│ GET /api/now/table/ │
|
|
214
|
+
│ incident │
|
|
215
|
+
│ │
|
|
216
|
+
│ Host: prod.sn.com │
|
|
217
|
+
│ Auth: prod creds │
|
|
218
|
+
└──────────────────────┘
|
|
219
|
+
|
|
220
|
+
4. Restore original instance
|
|
221
|
+
┌──────────────────────┐
|
|
222
|
+
│ serviceNowClient. │
|
|
223
|
+
│ setInstance( │
|
|
224
|
+
│ originalInstance │
|
|
225
|
+
│ ) │
|
|
226
|
+
└──────────────────────┘
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Error Handling Flow
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Invalid URI: servicenow://invalid-format
|
|
233
|
+
│
|
|
234
|
+
▼
|
|
235
|
+
Parse URI (regex match fails)
|
|
236
|
+
│
|
|
237
|
+
▼
|
|
238
|
+
throw Error('Invalid resource URI format...')
|
|
239
|
+
│
|
|
240
|
+
▼
|
|
241
|
+
MCP Server catches error
|
|
242
|
+
│
|
|
243
|
+
▼
|
|
244
|
+
Return error response to client
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
Resource not found: servicenow://dev/unknown
|
|
248
|
+
│
|
|
249
|
+
▼
|
|
250
|
+
Parse URI successfully
|
|
251
|
+
│
|
|
252
|
+
▼
|
|
253
|
+
No matching resource handler
|
|
254
|
+
│
|
|
255
|
+
▼
|
|
256
|
+
throw Error('Unknown resource path: unknown. Available: ...')
|
|
257
|
+
│
|
|
258
|
+
▼
|
|
259
|
+
MCP Server catches error
|
|
260
|
+
│
|
|
261
|
+
▼
|
|
262
|
+
Return error response with suggestions
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
Instance not found: servicenow://nonexistent/incidents
|
|
266
|
+
│
|
|
267
|
+
▼
|
|
268
|
+
configManager.getInstance('nonexistent')
|
|
269
|
+
│
|
|
270
|
+
▼
|
|
271
|
+
throw Error('Instance "nonexistent" not found. Available: ...')
|
|
272
|
+
│
|
|
273
|
+
▼
|
|
274
|
+
MCP Server catches error
|
|
275
|
+
│
|
|
276
|
+
▼
|
|
277
|
+
Return error response with instance list
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Resource Response Format
|
|
281
|
+
|
|
282
|
+
All resources return a consistent format:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
{
|
|
286
|
+
contents: [
|
|
287
|
+
{
|
|
288
|
+
uri: "servicenow://dev/incidents",
|
|
289
|
+
mimeType: "application/json",
|
|
290
|
+
text: JSON.stringify({
|
|
291
|
+
metadata: {
|
|
292
|
+
timestamp: "2025-10-06T12:00:00.000Z",
|
|
293
|
+
instance: "dev",
|
|
294
|
+
description: "Active incidents from dev",
|
|
295
|
+
record_count: 15
|
|
296
|
+
},
|
|
297
|
+
data: [
|
|
298
|
+
{ /* incident 1 */ },
|
|
299
|
+
{ /* incident 2 */ },
|
|
300
|
+
// ...
|
|
301
|
+
]
|
|
302
|
+
}, null, 2)
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Performance Optimization
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
Resource Request: servicenow://dev/incidents
|
|
312
|
+
│
|
|
313
|
+
├──> Field Selection
|
|
314
|
+
│ └──> sysparm_fields: 'number,short_description,state,...'
|
|
315
|
+
│ (Only essential fields, not all 100+ fields)
|
|
316
|
+
│
|
|
317
|
+
├──> Limit Records
|
|
318
|
+
│ └──> sysparm_limit: 25
|
|
319
|
+
│ (Default limit prevents large payloads)
|
|
320
|
+
│
|
|
321
|
+
├──> Query Filter
|
|
322
|
+
│ └──> sysparm_query: 'active=true'
|
|
323
|
+
│ (Server-side filtering)
|
|
324
|
+
│
|
|
325
|
+
└──> Caching Metadata
|
|
326
|
+
└──> Include timestamp for client caching decisions
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Extension Points
|
|
330
|
+
|
|
331
|
+
Future resource types can be easily added:
|
|
332
|
+
|
|
333
|
+
```javascript
|
|
334
|
+
// In resources.js readResource()
|
|
335
|
+
|
|
336
|
+
// Resource: servicenow://[instance]/problems
|
|
337
|
+
if (resource === 'problems') {
|
|
338
|
+
const problems = await serviceNowClient.getRecords('problem', {
|
|
339
|
+
sysparm_query: 'active=true',
|
|
340
|
+
sysparm_limit: 25,
|
|
341
|
+
sysparm_fields: 'number,short_description,state,...'
|
|
342
|
+
});
|
|
343
|
+
return formatResource(problems, `Active problems from ${instanceName}`);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Resource: servicenow://[instance]/catalog-items
|
|
347
|
+
if (resource === 'catalog-items') {
|
|
348
|
+
const items = await serviceNowClient.getRecords('sc_cat_item', {
|
|
349
|
+
sysparm_query: 'active=true',
|
|
350
|
+
sysparm_limit: 50,
|
|
351
|
+
sysparm_fields: 'name,short_description,category,...'
|
|
352
|
+
});
|
|
353
|
+
return formatResource(items, `Catalog items from ${instanceName}`);
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Integration with Tools
|
|
358
|
+
|
|
359
|
+
Resources and Tools work together:
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
┌──────────────────────────────────────────────────────┐
|
|
363
|
+
│ MCP Client │
|
|
364
|
+
└──────────────────┬───────────────────────────────────┘
|
|
365
|
+
│
|
|
366
|
+
┌──────────┴──────────┐
|
|
367
|
+
│ │
|
|
368
|
+
▼ ▼
|
|
369
|
+
┌──────────────┐ ┌─────────────┐
|
|
370
|
+
│ Resources │ │ Tools │
|
|
371
|
+
│ (Read-Only) │ │ (Read/Write)│
|
|
372
|
+
└──────┬───────┘ └──────┬──────┘
|
|
373
|
+
│ │
|
|
374
|
+
│ GET data │ Modify data
|
|
375
|
+
│ │
|
|
376
|
+
▼ ▼
|
|
377
|
+
┌─────────────────────────────────────┐
|
|
378
|
+
│ ServiceNow REST API │
|
|
379
|
+
└─────────────────────────────────────┘
|
|
380
|
+
|
|
381
|
+
Example workflow:
|
|
382
|
+
1. Resource: Read servicenow://dev/incidents
|
|
383
|
+
→ Get list of incidents
|
|
384
|
+
|
|
385
|
+
2. Tool: SN-Update-Record
|
|
386
|
+
→ Update specific incident
|
|
387
|
+
|
|
388
|
+
3. Resource: Read servicenow://dev/incidents/{number}
|
|
389
|
+
→ Verify update
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
This architecture provides a clean separation between read-only resources (cacheable, fast) and write tools (modify state, slower).
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# MCP Resources Implementation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document describes the MCP Resources implementation for the ServiceNow MCP server. Resources provide read-only, cacheable access to ServiceNow data through a URI-based interface.
|
|
6
|
+
|
|
7
|
+
## Implementation
|
|
8
|
+
|
|
9
|
+
**File:** `/src/resources.js`
|
|
10
|
+
|
|
11
|
+
The resources module exports factory functions that create resource handlers for the MCP server.
|
|
12
|
+
|
|
13
|
+
### Integration
|
|
14
|
+
|
|
15
|
+
To integrate with the MCP server (`src/mcp-server-consolidated.js`):
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import { createResourceHandlers } from './resources.js';
|
|
19
|
+
|
|
20
|
+
// Inside createMcpServer function, after loading tableMetadata:
|
|
21
|
+
const { listResources, readResource } = createResourceHandlers(
|
|
22
|
+
serviceNowClient,
|
|
23
|
+
configManager,
|
|
24
|
+
tableMetadata
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Register resource handlers
|
|
28
|
+
server.setRequestHandler(ListResourcesRequestSchema, listResources);
|
|
29
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
30
|
+
const { uri } = request.params;
|
|
31
|
+
return await readResource(uri);
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Resource URI Format
|
|
36
|
+
|
|
37
|
+
All resources follow the pattern: `servicenow://[instance]/[resource]/[id]`
|
|
38
|
+
|
|
39
|
+
### Global Resources
|
|
40
|
+
|
|
41
|
+
Resources that don't require instance selection:
|
|
42
|
+
|
|
43
|
+
- `servicenow://instances` - List all configured ServiceNow instances
|
|
44
|
+
- `servicenow://tables` - List all available ServiceNow tables with metadata
|
|
45
|
+
|
|
46
|
+
### Instance-Specific Resources
|
|
47
|
+
|
|
48
|
+
Resources that query data from a specific instance:
|
|
49
|
+
|
|
50
|
+
- `servicenow://{instance}/info` - Instance information and capabilities
|
|
51
|
+
- `servicenow://{instance}/incidents` - List active incidents
|
|
52
|
+
- `servicenow://{instance}/incidents/{number}` - Specific incident (e.g., INC0012345)
|
|
53
|
+
- `servicenow://{instance}/users` - List active users
|
|
54
|
+
- `servicenow://{instance}/update-sets` - List update sets in progress
|
|
55
|
+
- `servicenow://{instance}/update-sets/{sys_id}` - Specific update set with contents
|
|
56
|
+
- `servicenow://{instance}/groups` - List active user groups
|
|
57
|
+
- `servicenow://{instance}/change-requests` - List active change requests
|
|
58
|
+
|
|
59
|
+
## Features
|
|
60
|
+
|
|
61
|
+
### 1. Multi-Instance Support
|
|
62
|
+
|
|
63
|
+
Resources automatically route to the correct ServiceNow instance:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// Access default instance
|
|
67
|
+
servicenow://dev/incidents
|
|
68
|
+
|
|
69
|
+
// Access prod instance
|
|
70
|
+
servicenow://prod/incidents
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The implementation handles instance switching and restoration automatically.
|
|
74
|
+
|
|
75
|
+
### 2. Metadata Enrichment
|
|
76
|
+
|
|
77
|
+
All resources return data wrapped with metadata:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"metadata": {
|
|
82
|
+
"timestamp": "2025-10-06T12:00:00.000Z",
|
|
83
|
+
"instance": "dev",
|
|
84
|
+
"description": "Active incidents from dev",
|
|
85
|
+
"record_count": 15
|
|
86
|
+
},
|
|
87
|
+
"data": [...]
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Cacheability
|
|
92
|
+
|
|
93
|
+
Resources are read-only and include timestamps, making them suitable for client-side caching.
|
|
94
|
+
|
|
95
|
+
### 4. Update Set Inspection
|
|
96
|
+
|
|
97
|
+
The update set resources provide detailed breakdowns:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
servicenow://dev/update-sets/abc123
|
|
101
|
+
// Returns:
|
|
102
|
+
{
|
|
103
|
+
"update_set": {
|
|
104
|
+
"sys_id": "abc123",
|
|
105
|
+
"name": "My Feature",
|
|
106
|
+
"state": "in progress",
|
|
107
|
+
...
|
|
108
|
+
},
|
|
109
|
+
"total_records": 43,
|
|
110
|
+
"components": [
|
|
111
|
+
{
|
|
112
|
+
"type": "Business Rule",
|
|
113
|
+
"count": 5,
|
|
114
|
+
"items": ["Rule 1", "Rule 2", ...]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "UI Policy",
|
|
118
|
+
"count": 3,
|
|
119
|
+
"items": [...]
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Example Usage
|
|
126
|
+
|
|
127
|
+
### List All Resources
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
// MCP Client
|
|
131
|
+
const resources = await client.listResources();
|
|
132
|
+
console.log(resources);
|
|
133
|
+
// Shows all available resource URIs with descriptions
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Read Incidents from Dev Instance
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// MCP Client
|
|
140
|
+
const incidents = await client.readResource({
|
|
141
|
+
uri: 'servicenow://dev/incidents'
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
console.log(incidents.contents[0].text);
|
|
145
|
+
// {
|
|
146
|
+
// "metadata": {
|
|
147
|
+
// "timestamp": "2025-10-06T12:00:00.000Z",
|
|
148
|
+
// "instance": "dev",
|
|
149
|
+
// "description": "Active incidents from dev",
|
|
150
|
+
// "record_count": 15
|
|
151
|
+
// },
|
|
152
|
+
// "data": [
|
|
153
|
+
// {
|
|
154
|
+
// "number": "INC0012345",
|
|
155
|
+
// "short_description": "Server down",
|
|
156
|
+
// "state": "1",
|
|
157
|
+
// "priority": "1",
|
|
158
|
+
// ...
|
|
159
|
+
// }
|
|
160
|
+
// ]
|
|
161
|
+
// }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Read Specific Incident
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// MCP Client
|
|
168
|
+
const incident = await client.readResource({
|
|
169
|
+
uri: 'servicenow://dev/incidents/INC0012345'
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Inspect Update Set
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// MCP Client
|
|
177
|
+
const updateSet = await client.readResource({
|
|
178
|
+
uri: 'servicenow://dev/update-sets/abc123def456'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Returns detailed breakdown of update set contents grouped by type
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Error Handling
|
|
185
|
+
|
|
186
|
+
The implementation provides clear error messages:
|
|
187
|
+
|
|
188
|
+
- **Invalid URI format** - Returns format help
|
|
189
|
+
- **Resource not found** - Specific error with available resources
|
|
190
|
+
- **Instance not found** - Lists available instances
|
|
191
|
+
- **ServiceNow API errors** - Forwarded with context
|
|
192
|
+
|
|
193
|
+
## Performance Considerations
|
|
194
|
+
|
|
195
|
+
### Default Limits
|
|
196
|
+
|
|
197
|
+
- Incidents: 25 records
|
|
198
|
+
- Users: 50 records
|
|
199
|
+
- Update sets: 25 records
|
|
200
|
+
- Groups: 50 records
|
|
201
|
+
- Change requests: 25 records
|
|
202
|
+
- Update set contents: 1000 records (with first 10 per type displayed)
|
|
203
|
+
|
|
204
|
+
### Field Selection
|
|
205
|
+
|
|
206
|
+
Resources request only essential fields to minimize payload size:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
sysparm_fields: 'number,short_description,state,priority,assigned_to,sys_created_on'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Instance Switching
|
|
213
|
+
|
|
214
|
+
The implementation saves and restores the current instance, ensuring thread safety in multi-client scenarios.
|
|
215
|
+
|
|
216
|
+
## Future Enhancements
|
|
217
|
+
|
|
218
|
+
Potential additions to the resources implementation:
|
|
219
|
+
|
|
220
|
+
1. **Pagination Support** - Add offset/limit to resource URIs
|
|
221
|
+
2. **Filtering** - Support query parameters in URIs
|
|
222
|
+
3. **Additional Resources**:
|
|
223
|
+
- `servicenow://{instance}/problems` - List problems
|
|
224
|
+
- `servicenow://{instance}/catalog-items` - List service catalog items
|
|
225
|
+
- `servicenow://{instance}/workflows` - List workflows
|
|
226
|
+
- `servicenow://{instance}/business-rules` - List business rules
|
|
227
|
+
|
|
228
|
+
4. **Resource Templates** - Dynamic resource generation based on table metadata
|
|
229
|
+
|
|
230
|
+
5. **Aggregations** - Summary resources:
|
|
231
|
+
- `servicenow://{instance}/dashboard` - High-level metrics
|
|
232
|
+
- `servicenow://{instance}/stats/incidents` - Incident statistics
|
|
233
|
+
|
|
234
|
+
## Testing
|
|
235
|
+
|
|
236
|
+
Example manual test flow:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Using MCP Inspector
|
|
240
|
+
npx @modelcontextprotocol/inspector node src/stdio-server.js
|
|
241
|
+
|
|
242
|
+
# List all resources
|
|
243
|
+
> resources/list
|
|
244
|
+
|
|
245
|
+
# Read instance info
|
|
246
|
+
> resources/read servicenow://dev/info
|
|
247
|
+
|
|
248
|
+
# Read incidents
|
|
249
|
+
> resources/read servicenow://dev/incidents
|
|
250
|
+
|
|
251
|
+
# Read specific incident
|
|
252
|
+
> resources/read servicenow://dev/incidents/INC0012345
|
|
253
|
+
|
|
254
|
+
# Read update set
|
|
255
|
+
> resources/read servicenow://dev/update-sets/abc123
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Documentation
|
|
259
|
+
|
|
260
|
+
- **API Reference**: See `docs/API_REFERENCE.md` for complete tool documentation
|
|
261
|
+
- **Setup Guide**: See `docs/SETUP_GUIDE.md` for configuration
|
|
262
|
+
- **Multi-Instance**: See `docs/MULTI_INSTANCE_CONFIGURATION.md` for instance setup
|
|
263
|
+
|
|
264
|
+
## Summary
|
|
265
|
+
|
|
266
|
+
The MCP Resources implementation provides:
|
|
267
|
+
|
|
268
|
+
- **9+ resource types** for common ServiceNow data
|
|
269
|
+
- **Multi-instance routing** with automatic switching
|
|
270
|
+
- **Metadata enrichment** with timestamps and record counts
|
|
271
|
+
- **Cacheable responses** suitable for client-side caching
|
|
272
|
+
- **Error handling** with helpful messages
|
|
273
|
+
- **Performance optimized** with field selection and limits
|
|
274
|
+
- **Extensible design** for easy addition of new resources
|
|
275
|
+
|
|
276
|
+
Resources complement the MCP tools by providing read-only access to frequently needed data without requiring explicit tool calls.
|