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,1322 @@
|
|
|
1
|
+
# Puppeteer Integration for ServiceNow MCP Server
|
|
2
|
+
# Comprehensive Analysis and Recommendation
|
|
3
|
+
|
|
4
|
+
**Date:** 2025-10-06
|
|
5
|
+
**Status:** RESEARCH COMPLETE - RECOMMENDATION PROVIDED
|
|
6
|
+
**Analyst:** Claude Code Research Agent
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Executive Summary
|
|
11
|
+
|
|
12
|
+
This document analyzes the feasibility, benefits, risks, and recommendation for integrating Puppeteer browser automation into the ServiceNow MCP Server.
|
|
13
|
+
|
|
14
|
+
### Final Recommendation: **IMPLEMENT LATER (Low Priority)**
|
|
15
|
+
|
|
16
|
+
**Reasoning:**
|
|
17
|
+
1. Recent UI API discoveries (`/api/now/ui/concoursepicker/*`) eliminated 90% of the need for browser automation
|
|
18
|
+
2. REST API + background script automation covers nearly all ServiceNow operations
|
|
19
|
+
3. Puppeteer would add significant complexity with marginal benefit
|
|
20
|
+
4. Flow Designer (the primary UI-only operation) can be handled via template approach
|
|
21
|
+
5. Better ROI by improving existing REST API tools
|
|
22
|
+
|
|
23
|
+
**When to Revisit:**
|
|
24
|
+
- User demand for UI testing/validation tools emerges
|
|
25
|
+
- Need for screenshot-based documentation automation
|
|
26
|
+
- Discovery of critical UI-only operations that can't be solved via REST API
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. Puppeteer Capabilities Analysis
|
|
31
|
+
|
|
32
|
+
### What Puppeteer Can Do
|
|
33
|
+
|
|
34
|
+
#### Core Browser Automation
|
|
35
|
+
- **Page Navigation**: Load any URL, handle redirects, manage navigation history
|
|
36
|
+
- **Element Interaction**: Click, type, select, hover, drag-and-drop
|
|
37
|
+
- **Form Automation**: Fill forms, submit, handle file uploads
|
|
38
|
+
- **JavaScript Execution**: Execute arbitrary JavaScript in page context
|
|
39
|
+
- **Screenshot Capture**: Full page, viewport, element-specific screenshots
|
|
40
|
+
- **PDF Generation**: Convert pages to PDF documents
|
|
41
|
+
- **Network Interception**: Monitor/modify HTTP requests and responses
|
|
42
|
+
- **Cookie Management**: Get, set, delete cookies across sessions
|
|
43
|
+
- **Session Persistence**: Save and restore browser sessions
|
|
44
|
+
|
|
45
|
+
#### Authentication Handling
|
|
46
|
+
|
|
47
|
+
**1. Form-Based Authentication** ✅
|
|
48
|
+
```javascript
|
|
49
|
+
await page.goto('https://instance.service-now.com/login.do');
|
|
50
|
+
await page.type('#user_name', username);
|
|
51
|
+
await page.type('#user_password', password);
|
|
52
|
+
await page.click('#sysverb_login');
|
|
53
|
+
await page.waitForNavigation();
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**2. Cookie-Based Session Management** ✅
|
|
57
|
+
```javascript
|
|
58
|
+
// Save session
|
|
59
|
+
const cookies = await page.cookies();
|
|
60
|
+
fs.writeFileSync('session.json', JSON.stringify(cookies));
|
|
61
|
+
|
|
62
|
+
// Restore session
|
|
63
|
+
const savedCookies = JSON.parse(fs.readFileSync('session.json'));
|
|
64
|
+
await page.setCookie(...savedCookies);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**3. HTTP Basic Authentication** ✅
|
|
68
|
+
```javascript
|
|
69
|
+
await page.authenticate({
|
|
70
|
+
username: 'admin',
|
|
71
|
+
password: 'password'
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**4. SSO/OAuth** ⚠️
|
|
76
|
+
- Can handle OAuth flows by following redirects
|
|
77
|
+
- May struggle with complex MFA (SMS, authenticator apps)
|
|
78
|
+
- Can handle SAML redirects if purely browser-based
|
|
79
|
+
|
|
80
|
+
**5. Multi-Factor Authentication** ❌
|
|
81
|
+
- Cannot handle SMS codes (requires external input)
|
|
82
|
+
- Cannot handle authenticator app codes (time-based, external)
|
|
83
|
+
- Can handle push notifications if they're browser-based
|
|
84
|
+
|
|
85
|
+
### Performance Considerations
|
|
86
|
+
|
|
87
|
+
| Metric | Value | Notes |
|
|
88
|
+
|--------|-------|-------|
|
|
89
|
+
| **Browser Launch** | 1-2 seconds | Headless mode |
|
|
90
|
+
| **Page Load** | 2-5 seconds | Depends on page complexity |
|
|
91
|
+
| **Navigation** | 1-3 seconds | Per page transition |
|
|
92
|
+
| **Screenshot** | 0.5-1 second | Full page |
|
|
93
|
+
| **Memory Usage** | 100-300 MB | Per browser instance |
|
|
94
|
+
| **CPU Usage** | Moderate | Spikes during page load |
|
|
95
|
+
|
|
96
|
+
**Compared to REST API:**
|
|
97
|
+
- REST API: 100-500ms per request
|
|
98
|
+
- Puppeteer: 3-8 seconds per operation
|
|
99
|
+
- **15-80x slower than REST API**
|
|
100
|
+
|
|
101
|
+
### Reliability and Error Handling
|
|
102
|
+
|
|
103
|
+
#### Common Failure Scenarios
|
|
104
|
+
1. **Timeouts**: Pages that load slowly or hang
|
|
105
|
+
2. **Element Not Found**: Selectors that change or don't exist
|
|
106
|
+
3. **JavaScript Errors**: Page scripts that throw errors
|
|
107
|
+
4. **Network Issues**: Connection failures, slow networks
|
|
108
|
+
5. **Session Expiration**: Authentication timeouts
|
|
109
|
+
6. **UI Changes**: ServiceNow version updates breaking selectors
|
|
110
|
+
|
|
111
|
+
#### Error Recovery Strategies
|
|
112
|
+
```javascript
|
|
113
|
+
// Retry with exponential backoff
|
|
114
|
+
async function retryOperation(fn, maxRetries = 3) {
|
|
115
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
116
|
+
try {
|
|
117
|
+
return await fn();
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (i === maxRetries - 1) throw error;
|
|
120
|
+
await sleep(Math.pow(2, i) * 1000);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Graceful degradation
|
|
126
|
+
async function clickElement(selector) {
|
|
127
|
+
try {
|
|
128
|
+
await page.click(selector);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
// Fallback to JavaScript click
|
|
131
|
+
await page.evaluate((sel) => {
|
|
132
|
+
document.querySelector(sel).click();
|
|
133
|
+
}, selector);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 2. ServiceNow UI Operations Analysis
|
|
141
|
+
|
|
142
|
+
### Operations That Currently Require UI Interaction
|
|
143
|
+
|
|
144
|
+
#### ❌ No Longer Required (Solved via REST API/Background Scripts)
|
|
145
|
+
|
|
146
|
+
| Operation | Previous Limitation | Current Solution |
|
|
147
|
+
|-----------|-------------------|------------------|
|
|
148
|
+
| **Update Set Switching** | UI-only | ✅ `/api/now/ui/concoursepicker/updateset` |
|
|
149
|
+
| **Application Scope Switching** | UI-only | ✅ `/api/now/ui/concoursepicker/application` |
|
|
150
|
+
| **Background Script Execution** | Manual copy-paste | ✅ `sys_trigger` automated execution |
|
|
151
|
+
| **UI Policy Actions** | REST API won't link | ✅ Background script with setValue() |
|
|
152
|
+
| **Table/Field Creation** | Partial API support | ✅ Full REST API support |
|
|
153
|
+
| **Workflow Creation** | Complex but possible | ✅ `SN-Create-Workflow` tool |
|
|
154
|
+
|
|
155
|
+
#### ⚠️ Still UI-Required (Candidates for Puppeteer)
|
|
156
|
+
|
|
157
|
+
| Operation | Why UI-Required | Workaround Exists? |
|
|
158
|
+
|-----------|----------------|-------------------|
|
|
159
|
+
| **Flow Designer Logic Blocks** | No REST API for complex logic | ✅ Template + clone approach |
|
|
160
|
+
| **Flow Compilation** | No API endpoint | ✅ Create in draft, compile in UI |
|
|
161
|
+
| **Visual Flow Testing** | Debugging UI-specific | ⚠️ Can test via FlowAPI |
|
|
162
|
+
| **Studio IDE Operations** | Scoped app development UI | ⚠️ Update sets + REST API |
|
|
163
|
+
| **UI16/NextExperience Testing** | Visual validation | ❌ No workaround |
|
|
164
|
+
| **Form Layout Configuration** | Complex drag-drop UI | ⚠️ REST API possible but complex |
|
|
165
|
+
| **Report Builder** | Visual configuration | ⚠️ `sys_report` table accessible |
|
|
166
|
+
|
|
167
|
+
### Use Cases Where Puppeteer Would Add Value
|
|
168
|
+
|
|
169
|
+
#### 1. Flow Designer Automation (Priority: Medium)
|
|
170
|
+
|
|
171
|
+
**Current Gap:**
|
|
172
|
+
- Cannot create complex logic blocks (IF, FOREACH with nested conditions) via REST API
|
|
173
|
+
- Flow compilation requires UI interaction
|
|
174
|
+
- Visual debugging not available programmatically
|
|
175
|
+
|
|
176
|
+
**Puppeteer Solution:**
|
|
177
|
+
```javascript
|
|
178
|
+
// Navigate to Flow Designer
|
|
179
|
+
await page.goto('https://instance.service-now.com/now/flow/designer');
|
|
180
|
+
|
|
181
|
+
// Create new flow
|
|
182
|
+
await page.click('button[data-test="new-flow"]');
|
|
183
|
+
await page.type('#flow-name', 'Automated Flow');
|
|
184
|
+
|
|
185
|
+
// Add IF condition
|
|
186
|
+
await page.click('button[data-action="add-logic"]');
|
|
187
|
+
await page.click('div[data-logic-type="if"]');
|
|
188
|
+
await page.type('#condition-script', 'current.state == 2');
|
|
189
|
+
|
|
190
|
+
// Add action
|
|
191
|
+
await page.click('button[data-action="add-action"]');
|
|
192
|
+
await page.select('#action-type', 'create_record');
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Value:** Enables fully automated flow creation without templates
|
|
196
|
+
|
|
197
|
+
**Risk:** High - UI selectors change frequently, fragile
|
|
198
|
+
|
|
199
|
+
#### 2. UI Testing and Validation (Priority: Low)
|
|
200
|
+
|
|
201
|
+
**Use Case:** Verify UI policy effects, form layouts, visual consistency
|
|
202
|
+
|
|
203
|
+
**Puppeteer Solution:**
|
|
204
|
+
```javascript
|
|
205
|
+
// Test UI policy behavior
|
|
206
|
+
await page.goto('https://instance.service-now.com/incident.do?sys_id=-1');
|
|
207
|
+
await page.select('#priority', '1');
|
|
208
|
+
await page.waitForSelector('#assigned_to.mandatory'); // Verify field becomes mandatory
|
|
209
|
+
|
|
210
|
+
// Capture screenshot for documentation
|
|
211
|
+
await page.screenshot({ path: 'ui-policy-test.png', fullPage: true });
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Value:** Automated UI regression testing
|
|
215
|
+
|
|
216
|
+
**Risk:** Low - read-only operations
|
|
217
|
+
|
|
218
|
+
#### 3. Documentation Screenshot Automation (Priority: Low)
|
|
219
|
+
|
|
220
|
+
**Use Case:** Generate screenshots for documentation, training materials
|
|
221
|
+
|
|
222
|
+
**Puppeteer Solution:**
|
|
223
|
+
```javascript
|
|
224
|
+
const screenshots = [
|
|
225
|
+
{ url: '/incident.do?sys_id=-1', name: 'incident-form' },
|
|
226
|
+
{ url: '/flow_designer.do', name: 'flow-designer' },
|
|
227
|
+
{ url: '$pa_dashboard.do', name: 'dashboard' }
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
for (const shot of screenshots) {
|
|
231
|
+
await page.goto(instance + shot.url);
|
|
232
|
+
await page.screenshot({
|
|
233
|
+
path: `docs/screenshots/${shot.name}.png`,
|
|
234
|
+
fullPage: true
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Value:** Streamlines documentation process
|
|
240
|
+
|
|
241
|
+
**Risk:** Low - read-only operations
|
|
242
|
+
|
|
243
|
+
#### 4. Form Layout Validation (Priority: Very Low)
|
|
244
|
+
|
|
245
|
+
**Use Case:** Verify form layouts, section visibility, field ordering
|
|
246
|
+
|
|
247
|
+
**Puppeteer Solution:**
|
|
248
|
+
```javascript
|
|
249
|
+
await page.goto('https://instance.service-now.com/incident.do');
|
|
250
|
+
const layout = await page.evaluate(() => {
|
|
251
|
+
const sections = document.querySelectorAll('.section-header');
|
|
252
|
+
return Array.from(sections).map(s => s.textContent);
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Value:** Automated layout verification
|
|
257
|
+
|
|
258
|
+
**Risk:** Low - read-only operations
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 3. Existing Puppeteer Implementations
|
|
263
|
+
|
|
264
|
+
### Official MCP Puppeteer Server
|
|
265
|
+
|
|
266
|
+
**Status:** Archived (No longer actively maintained)
|
|
267
|
+
**Repository:** https://github.com/modelcontextprotocol/servers-archived
|
|
268
|
+
|
|
269
|
+
**Why Archived:**
|
|
270
|
+
- "Historical reference implementations"
|
|
271
|
+
- "NO SECURITY GUARANTEES ARE PROVIDED"
|
|
272
|
+
- Replaced by actively maintained alternatives
|
|
273
|
+
|
|
274
|
+
**Tools Provided:**
|
|
275
|
+
- `puppeteer_navigate` - Navigate to URLs
|
|
276
|
+
- `puppeteer_screenshot` - Capture screenshots
|
|
277
|
+
- `puppeteer_click` - Click elements
|
|
278
|
+
- Console log monitoring
|
|
279
|
+
|
|
280
|
+
**Limitations:**
|
|
281
|
+
- No form filling
|
|
282
|
+
- No authentication management
|
|
283
|
+
- No session persistence
|
|
284
|
+
- Basic functionality only
|
|
285
|
+
|
|
286
|
+
### Community Puppeteer MCP Servers
|
|
287
|
+
|
|
288
|
+
#### 1. Xandon/puppeteer-mcp-server
|
|
289
|
+
**Features:**
|
|
290
|
+
- Browser automation
|
|
291
|
+
- New browser instances
|
|
292
|
+
- Existing Chrome window connections
|
|
293
|
+
|
|
294
|
+
#### 2. merajmehrabi/puppeteer-mcp-server
|
|
295
|
+
**Features:**
|
|
296
|
+
- Browser automation
|
|
297
|
+
- Chrome window interaction
|
|
298
|
+
- Enhanced tool set
|
|
299
|
+
|
|
300
|
+
**Note:** Both are community projects with varying maintenance levels
|
|
301
|
+
|
|
302
|
+
### ServiceNow + Puppeteer Examples
|
|
303
|
+
|
|
304
|
+
**Search Result:** No significant ServiceNow + Puppeteer integrations found
|
|
305
|
+
|
|
306
|
+
**Analysis:**
|
|
307
|
+
- ServiceNow community uses REST API for automation
|
|
308
|
+
- Puppet (infrastructure tool) has ServiceNow integrations, but not Puppeteer
|
|
309
|
+
- Lack of examples suggests limited demand for browser automation approach
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 4. Architecture Design
|
|
314
|
+
|
|
315
|
+
### Integration Architecture Options
|
|
316
|
+
|
|
317
|
+
#### Option 1: Embedded Puppeteer Module (Recommended)
|
|
318
|
+
|
|
319
|
+
**Structure:**
|
|
320
|
+
```
|
|
321
|
+
src/
|
|
322
|
+
├── servicenow-client.js # REST API client
|
|
323
|
+
├── servicenow-puppeteer-client.js # Puppeteer client (NEW)
|
|
324
|
+
├── mcp-server-consolidated.js # MCP tool registration
|
|
325
|
+
└── config-manager.js # Configuration
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Pros:**
|
|
329
|
+
- Single MCP server process
|
|
330
|
+
- Shared configuration
|
|
331
|
+
- Unified session management
|
|
332
|
+
- Easier deployment
|
|
333
|
+
|
|
334
|
+
**Cons:**
|
|
335
|
+
- Increases main process memory usage
|
|
336
|
+
- Browser crashes affect entire MCP server
|
|
337
|
+
- Longer startup time
|
|
338
|
+
|
|
339
|
+
#### Option 2: Separate Puppeteer Service
|
|
340
|
+
|
|
341
|
+
**Structure:**
|
|
342
|
+
```
|
|
343
|
+
src/
|
|
344
|
+
├── servicenow-client.js # REST API client
|
|
345
|
+
├── mcp-server-consolidated.js # Main MCP server
|
|
346
|
+
└── puppeteer-service/
|
|
347
|
+
├── server.js # Standalone Puppeteer server
|
|
348
|
+
├── browser-pool.js # Browser instance pool
|
|
349
|
+
└── session-manager.js # Session persistence
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Pros:**
|
|
353
|
+
- Process isolation (browser crashes don't affect MCP server)
|
|
354
|
+
- Can scale Puppeteer service independently
|
|
355
|
+
- Can restart browser without restarting MCP server
|
|
356
|
+
- Better resource management
|
|
357
|
+
|
|
358
|
+
**Cons:**
|
|
359
|
+
- More complex architecture
|
|
360
|
+
- Requires inter-process communication
|
|
361
|
+
- Additional deployment complexity
|
|
362
|
+
- Harder to debug
|
|
363
|
+
|
|
364
|
+
#### Option 3: On-Demand Puppeteer (Hybrid)
|
|
365
|
+
|
|
366
|
+
**Structure:**
|
|
367
|
+
```javascript
|
|
368
|
+
class ServiceNowPuppeteerClient {
|
|
369
|
+
async executeWithBrowser(operation) {
|
|
370
|
+
const browser = await puppeteer.launch({ headless: true });
|
|
371
|
+
try {
|
|
372
|
+
return await operation(browser);
|
|
373
|
+
} finally {
|
|
374
|
+
await browser.close(); // Always cleanup
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**Pros:**
|
|
381
|
+
- Browser only runs when needed
|
|
382
|
+
- Automatic cleanup
|
|
383
|
+
- Lower memory footprint when idle
|
|
384
|
+
- Simple implementation
|
|
385
|
+
|
|
386
|
+
**Cons:**
|
|
387
|
+
- 1-2 second overhead per operation (browser launch)
|
|
388
|
+
- No session persistence
|
|
389
|
+
- Slower for multiple operations
|
|
390
|
+
|
|
391
|
+
### Recommended Architecture: Embedded with Browser Pool
|
|
392
|
+
|
|
393
|
+
**Rationale:**
|
|
394
|
+
- Balance between simplicity and performance
|
|
395
|
+
- Reuse browser instances for multiple operations
|
|
396
|
+
- Automatic cleanup after idle timeout
|
|
397
|
+
- Session persistence within pool lifetime
|
|
398
|
+
|
|
399
|
+
**Implementation:**
|
|
400
|
+
```javascript
|
|
401
|
+
class BrowserPool {
|
|
402
|
+
constructor(maxInstances = 3) {
|
|
403
|
+
this.maxInstances = maxInstances;
|
|
404
|
+
this.instances = [];
|
|
405
|
+
this.idleTimeout = 5 * 60 * 1000; // 5 minutes
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async acquire() {
|
|
409
|
+
// Return idle instance or create new one
|
|
410
|
+
const idle = this.instances.find(i => !i.inUse);
|
|
411
|
+
if (idle) {
|
|
412
|
+
idle.inUse = true;
|
|
413
|
+
idle.lastUsed = Date.now();
|
|
414
|
+
return idle.browser;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (this.instances.length < this.maxInstances) {
|
|
418
|
+
const browser = await puppeteer.launch({
|
|
419
|
+
headless: true,
|
|
420
|
+
args: ['--no-sandbox'] // Docker-compatible
|
|
421
|
+
});
|
|
422
|
+
const instance = {
|
|
423
|
+
browser,
|
|
424
|
+
inUse: true,
|
|
425
|
+
lastUsed: Date.now()
|
|
426
|
+
};
|
|
427
|
+
this.instances.push(instance);
|
|
428
|
+
return browser;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
throw new Error('Browser pool exhausted');
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
release(browser) {
|
|
435
|
+
const instance = this.instances.find(i => i.browser === browser);
|
|
436
|
+
if (instance) {
|
|
437
|
+
instance.inUse = false;
|
|
438
|
+
instance.lastUsed = Date.now();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
async cleanup() {
|
|
443
|
+
const now = Date.now();
|
|
444
|
+
for (const instance of this.instances) {
|
|
445
|
+
if (!instance.inUse && (now - instance.lastUsed) > this.idleTimeout) {
|
|
446
|
+
await instance.browser.close();
|
|
447
|
+
this.instances = this.instances.filter(i => i !== instance);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Session Management and Authentication
|
|
455
|
+
|
|
456
|
+
#### Strategy 1: Session Cookie Persistence (Recommended)
|
|
457
|
+
|
|
458
|
+
**Flow:**
|
|
459
|
+
```javascript
|
|
460
|
+
// 1. Initial authentication
|
|
461
|
+
async function authenticateServiceNow(page, instance, username, password) {
|
|
462
|
+
await page.goto(`${instance}/login.do`);
|
|
463
|
+
|
|
464
|
+
// Check if already authenticated
|
|
465
|
+
if (await page.$('#user_info_dropdown')) {
|
|
466
|
+
return { authenticated: true, fromCache: true };
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Perform login
|
|
470
|
+
await page.type('#user_name', username);
|
|
471
|
+
await page.type('#user_password', password);
|
|
472
|
+
await page.click('#sysverb_login');
|
|
473
|
+
await page.waitForSelector('#user_info_dropdown');
|
|
474
|
+
|
|
475
|
+
// Save session
|
|
476
|
+
const cookies = await page.cookies();
|
|
477
|
+
await saveCookies(instance, username, cookies);
|
|
478
|
+
|
|
479
|
+
return { authenticated: true, fromCache: false };
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// 2. Restore session
|
|
483
|
+
async function restoreSession(page, instance, username) {
|
|
484
|
+
const cookies = await loadCookies(instance, username);
|
|
485
|
+
if (cookies) {
|
|
486
|
+
await page.setCookie(...cookies);
|
|
487
|
+
await page.goto(`${instance}/nav_to.do`);
|
|
488
|
+
|
|
489
|
+
// Verify session still valid
|
|
490
|
+
if (await page.$('#user_info_dropdown')) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// 3. Session-aware page operation
|
|
498
|
+
async function withSession(instance, username, password, operation) {
|
|
499
|
+
const browser = await browserPool.acquire();
|
|
500
|
+
const page = await browser.newPage();
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
// Try to restore session
|
|
504
|
+
const restored = await restoreSession(page, instance, username);
|
|
505
|
+
|
|
506
|
+
// Fallback to fresh authentication
|
|
507
|
+
if (!restored) {
|
|
508
|
+
await authenticateServiceNow(page, instance, username, password);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return await operation(page);
|
|
512
|
+
} finally {
|
|
513
|
+
await page.close();
|
|
514
|
+
browserPool.release(browser);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Pros:**
|
|
520
|
+
- Fast subsequent operations (no re-authentication)
|
|
521
|
+
- Works with form-based auth
|
|
522
|
+
- Session cookies stored securely
|
|
523
|
+
|
|
524
|
+
**Cons:**
|
|
525
|
+
- Sessions expire (requires re-authentication)
|
|
526
|
+
- Cookie storage requires encryption
|
|
527
|
+
- SSO/OAuth may invalidate cookies frequently
|
|
528
|
+
|
|
529
|
+
#### Strategy 2: User Data Directory Persistence
|
|
530
|
+
|
|
531
|
+
**Flow:**
|
|
532
|
+
```javascript
|
|
533
|
+
const browser = await puppeteer.launch({
|
|
534
|
+
headless: true,
|
|
535
|
+
userDataDir: `./sessions/${instance}/${username}`,
|
|
536
|
+
args: ['--no-sandbox']
|
|
537
|
+
});
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Pros:**
|
|
541
|
+
- Persists full browser state (cookies, localStorage, cache)
|
|
542
|
+
- Survives browser restarts
|
|
543
|
+
- Works with SSO/OAuth
|
|
544
|
+
|
|
545
|
+
**Cons:**
|
|
546
|
+
- Stores more data than needed
|
|
547
|
+
- One user per userDataDir
|
|
548
|
+
- Cleanup more complex
|
|
549
|
+
|
|
550
|
+
### Error Recovery Strategies
|
|
551
|
+
|
|
552
|
+
```javascript
|
|
553
|
+
class PuppeteerOperationHandler {
|
|
554
|
+
async executeWithRetry(operation, maxRetries = 3) {
|
|
555
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
556
|
+
try {
|
|
557
|
+
return await operation();
|
|
558
|
+
} catch (error) {
|
|
559
|
+
console.error(`Attempt ${attempt} failed:`, error.message);
|
|
560
|
+
|
|
561
|
+
// Check if recoverable
|
|
562
|
+
if (this.isRecoverable(error) && attempt < maxRetries) {
|
|
563
|
+
await this.sleep(Math.pow(2, attempt) * 1000); // Exponential backoff
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Non-recoverable or final attempt
|
|
568
|
+
throw new EnhancedError(error, {
|
|
569
|
+
operation: operation.name,
|
|
570
|
+
attempt,
|
|
571
|
+
recoverable: this.isRecoverable(error)
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
isRecoverable(error) {
|
|
578
|
+
const recoverableErrors = [
|
|
579
|
+
'Navigation timeout',
|
|
580
|
+
'net::ERR_CONNECTION_REFUSED',
|
|
581
|
+
'Execution context was destroyed',
|
|
582
|
+
'Protocol error (Target.sendMessageToTarget)'
|
|
583
|
+
];
|
|
584
|
+
|
|
585
|
+
return recoverableErrors.some(msg => error.message.includes(msg));
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
async sleep(ms) {
|
|
589
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### Rate Limiting and Throttling
|
|
595
|
+
|
|
596
|
+
```javascript
|
|
597
|
+
class RateLimiter {
|
|
598
|
+
constructor(requestsPerMinute = 10) {
|
|
599
|
+
this.requestsPerMinute = requestsPerMinute;
|
|
600
|
+
this.queue = [];
|
|
601
|
+
this.processing = false;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
async execute(operation) {
|
|
605
|
+
return new Promise((resolve, reject) => {
|
|
606
|
+
this.queue.push({ operation, resolve, reject });
|
|
607
|
+
this.processQueue();
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
async processQueue() {
|
|
612
|
+
if (this.processing || this.queue.length === 0) return;
|
|
613
|
+
|
|
614
|
+
this.processing = true;
|
|
615
|
+
const { operation, resolve, reject } = this.queue.shift();
|
|
616
|
+
|
|
617
|
+
try {
|
|
618
|
+
const result = await operation();
|
|
619
|
+
resolve(result);
|
|
620
|
+
} catch (error) {
|
|
621
|
+
reject(error);
|
|
622
|
+
} finally {
|
|
623
|
+
// Wait before processing next
|
|
624
|
+
const delayMs = (60 * 1000) / this.requestsPerMinute;
|
|
625
|
+
await new Promise(r => setTimeout(r, delayMs));
|
|
626
|
+
this.processing = false;
|
|
627
|
+
this.processQueue(); // Process next item
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
## 5. Pros and Cons Analysis
|
|
636
|
+
|
|
637
|
+
### PROS ✅
|
|
638
|
+
|
|
639
|
+
#### 1. UI-Only Operations
|
|
640
|
+
- Can automate Flow Designer logic block creation
|
|
641
|
+
- Can perform visual UI testing
|
|
642
|
+
- Can handle operations with no REST API equivalent
|
|
643
|
+
|
|
644
|
+
#### 2. Visual Verification
|
|
645
|
+
- Screenshot capture for documentation
|
|
646
|
+
- Form layout validation
|
|
647
|
+
- UI policy testing
|
|
648
|
+
|
|
649
|
+
#### 3. E2E Testing
|
|
650
|
+
- Test complete user workflows
|
|
651
|
+
- Verify JavaScript behaviors
|
|
652
|
+
- Validate client-side logic
|
|
653
|
+
|
|
654
|
+
#### 4. Documentation Automation
|
|
655
|
+
- Auto-generate screenshots
|
|
656
|
+
- Capture form states
|
|
657
|
+
- Document UI changes
|
|
658
|
+
|
|
659
|
+
#### 5. Fallback Option
|
|
660
|
+
- Provides alternative when REST API fails
|
|
661
|
+
- Can work around API limitations
|
|
662
|
+
- Handles edge cases
|
|
663
|
+
|
|
664
|
+
### CONS ❌
|
|
665
|
+
|
|
666
|
+
#### 1. Performance (Critical)
|
|
667
|
+
- **15-80x slower than REST API** (3-8s vs 100-500ms)
|
|
668
|
+
- Browser launch overhead (1-2 seconds)
|
|
669
|
+
- Page load times (2-5 seconds per navigation)
|
|
670
|
+
- Memory intensive (100-300MB per browser)
|
|
671
|
+
|
|
672
|
+
#### 2. Reliability (Critical)
|
|
673
|
+
- **Fragile**: UI changes break selectors
|
|
674
|
+
- **Timeouts**: Pages hang, slow networks
|
|
675
|
+
- **Sessions expire**: Require re-authentication
|
|
676
|
+
- **Element not found**: Selectors change
|
|
677
|
+
- **ServiceNow version sensitivity**: Updates break automation
|
|
678
|
+
|
|
679
|
+
#### 3. Complexity (High)
|
|
680
|
+
- Session management complexity
|
|
681
|
+
- Browser lifecycle management
|
|
682
|
+
- Error handling more complex
|
|
683
|
+
- Debugging harder than REST API
|
|
684
|
+
- Requires UI selector maintenance
|
|
685
|
+
|
|
686
|
+
#### 4. Maintenance Burden (High)
|
|
687
|
+
- Selectors require updates when UI changes
|
|
688
|
+
- ServiceNow version compatibility testing
|
|
689
|
+
- Session management edge cases
|
|
690
|
+
- Browser version compatibility
|
|
691
|
+
- MCP server startup time increases
|
|
692
|
+
|
|
693
|
+
#### 5. Security Considerations
|
|
694
|
+
- Credential storage (session cookies)
|
|
695
|
+
- Browser sandbox escape risks
|
|
696
|
+
- Headless browser detection by ServiceNow
|
|
697
|
+
- CORS/CSP bypass concerns
|
|
698
|
+
|
|
699
|
+
#### 6. Limited Need (Critical)
|
|
700
|
+
- **90% of operations** now possible via REST API
|
|
701
|
+
- UI API breakthrough eliminated primary use cases
|
|
702
|
+
- Template approach viable for Flow Designer
|
|
703
|
+
- Background script automation covers complex scenarios
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## 6. Implementation Roadmap (If Approved)
|
|
708
|
+
|
|
709
|
+
### Phase 1: Foundation (Week 1-2)
|
|
710
|
+
|
|
711
|
+
**Goal:** Basic Puppeteer integration with authentication
|
|
712
|
+
|
|
713
|
+
**Tasks:**
|
|
714
|
+
1. Install dependencies
|
|
715
|
+
```bash
|
|
716
|
+
npm install puppeteer
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
2. Create `src/servicenow-puppeteer-client.js`
|
|
720
|
+
- Browser pool implementation
|
|
721
|
+
- Session management
|
|
722
|
+
- Authentication handler
|
|
723
|
+
|
|
724
|
+
3. Add configuration
|
|
725
|
+
```json
|
|
726
|
+
{
|
|
727
|
+
"puppeteer": {
|
|
728
|
+
"enabled": false,
|
|
729
|
+
"headless": true,
|
|
730
|
+
"browserPoolSize": 3,
|
|
731
|
+
"sessionTimeout": 300000,
|
|
732
|
+
"launchOptions": {
|
|
733
|
+
"args": ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
4. Implement basic tools
|
|
740
|
+
- `SN-Puppeteer-Navigate`
|
|
741
|
+
- `SN-Puppeteer-Screenshot`
|
|
742
|
+
|
|
743
|
+
**Deliverables:**
|
|
744
|
+
- Puppeteer client with authentication
|
|
745
|
+
- 2 basic MCP tools
|
|
746
|
+
- Configuration system
|
|
747
|
+
- Unit tests
|
|
748
|
+
|
|
749
|
+
### Phase 2: Flow Designer Automation (Week 3-4)
|
|
750
|
+
|
|
751
|
+
**Goal:** Automate Flow Designer operations
|
|
752
|
+
|
|
753
|
+
**Tasks:**
|
|
754
|
+
1. Reverse engineer Flow Designer selectors
|
|
755
|
+
2. Implement flow creation workflow
|
|
756
|
+
3. Add logic block creation
|
|
757
|
+
4. Add flow compilation trigger
|
|
758
|
+
|
|
759
|
+
**Tools:**
|
|
760
|
+
- `SN-Puppeteer-Create-Flow`
|
|
761
|
+
- `SN-Puppeteer-Add-Flow-Logic`
|
|
762
|
+
- `SN-Puppeteer-Compile-Flow`
|
|
763
|
+
|
|
764
|
+
**Deliverables:**
|
|
765
|
+
- Flow Designer automation tools
|
|
766
|
+
- Selector mapping documentation
|
|
767
|
+
- Integration tests
|
|
768
|
+
- Example flows
|
|
769
|
+
|
|
770
|
+
### Phase 3: UI Testing Tools (Week 5-6)
|
|
771
|
+
|
|
772
|
+
**Goal:** Automated UI validation
|
|
773
|
+
|
|
774
|
+
**Tasks:**
|
|
775
|
+
1. Form layout validator
|
|
776
|
+
2. UI policy tester
|
|
777
|
+
3. Screenshot generator
|
|
778
|
+
|
|
779
|
+
**Tools:**
|
|
780
|
+
- `SN-Puppeteer-Validate-Form-Layout`
|
|
781
|
+
- `SN-Puppeteer-Test-UI-Policy`
|
|
782
|
+
- `SN-Puppeteer-Generate-Screenshots`
|
|
783
|
+
|
|
784
|
+
**Deliverables:**
|
|
785
|
+
- UI testing tools
|
|
786
|
+
- Documentation automation
|
|
787
|
+
- Test examples
|
|
788
|
+
|
|
789
|
+
### Phase 4: Production Hardening (Week 7-8)
|
|
790
|
+
|
|
791
|
+
**Goal:** Production-ready implementation
|
|
792
|
+
|
|
793
|
+
**Tasks:**
|
|
794
|
+
1. Error recovery testing
|
|
795
|
+
2. Performance optimization
|
|
796
|
+
3. Security audit
|
|
797
|
+
4. Documentation
|
|
798
|
+
|
|
799
|
+
**Deliverables:**
|
|
800
|
+
- Production-ready code
|
|
801
|
+
- Security review report
|
|
802
|
+
- Performance benchmarks
|
|
803
|
+
- User documentation
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
## 7. Risk Analysis
|
|
808
|
+
|
|
809
|
+
### High Risks 🔴
|
|
810
|
+
|
|
811
|
+
#### 1. UI Change Fragility
|
|
812
|
+
**Risk:** ServiceNow UI updates break all selectors
|
|
813
|
+
**Impact:** Tools stop working entirely
|
|
814
|
+
**Mitigation:**
|
|
815
|
+
- Version-specific selector maps
|
|
816
|
+
- Fallback to REST API where possible
|
|
817
|
+
- Automated selector validation
|
|
818
|
+
- Community-maintained selector database
|
|
819
|
+
|
|
820
|
+
#### 2. Performance Degradation
|
|
821
|
+
**Risk:** Operations take 10-30 seconds instead of sub-second
|
|
822
|
+
**Impact:** Poor user experience, timeouts
|
|
823
|
+
**Mitigation:**
|
|
824
|
+
- Browser pooling
|
|
825
|
+
- Session persistence
|
|
826
|
+
- Lazy loading
|
|
827
|
+
- Warn users about slowness
|
|
828
|
+
|
|
829
|
+
#### 3. Session Management Complexity
|
|
830
|
+
**Risk:** Authentication fails, sessions expire mid-operation
|
|
831
|
+
**Impact:** Operations fail randomly
|
|
832
|
+
**Mitigation:**
|
|
833
|
+
- Robust retry logic
|
|
834
|
+
- Session validation before operations
|
|
835
|
+
- Re-authentication fallback
|
|
836
|
+
- Clear error messages
|
|
837
|
+
|
|
838
|
+
### Medium Risks ⚠️
|
|
839
|
+
|
|
840
|
+
#### 4. Maintenance Burden
|
|
841
|
+
**Risk:** Requires ongoing selector updates
|
|
842
|
+
**Impact:** High maintenance cost
|
|
843
|
+
**Mitigation:**
|
|
844
|
+
- Selector versioning system
|
|
845
|
+
- Community contributions
|
|
846
|
+
- Automated selector discovery
|
|
847
|
+
|
|
848
|
+
#### 5. Security Concerns
|
|
849
|
+
**Risk:** Browser vulnerabilities, credential leaks
|
|
850
|
+
**Impact:** Security breach
|
|
851
|
+
**Mitigation:**
|
|
852
|
+
- Secure credential storage (encrypted)
|
|
853
|
+
- Sandboxed browser execution
|
|
854
|
+
- Regular security audits
|
|
855
|
+
- Minimal permission model
|
|
856
|
+
|
|
857
|
+
### Low Risks 🟢
|
|
858
|
+
|
|
859
|
+
#### 6. Resource Usage
|
|
860
|
+
**Risk:** High memory/CPU consumption
|
|
861
|
+
**Impact:** Server overload
|
|
862
|
+
**Mitigation:**
|
|
863
|
+
- Browser pool limits
|
|
864
|
+
- Automatic cleanup
|
|
865
|
+
- Resource monitoring
|
|
866
|
+
|
|
867
|
+
---
|
|
868
|
+
|
|
869
|
+
## 8. Alternatives to Puppeteer
|
|
870
|
+
|
|
871
|
+
### Alternative 1: REST API Only (Current Approach) ✅ RECOMMENDED
|
|
872
|
+
|
|
873
|
+
**Coverage:**
|
|
874
|
+
- ✅ 95% of ServiceNow operations
|
|
875
|
+
- ✅ Update set management (UI API)
|
|
876
|
+
- ✅ Application scope switching (UI API)
|
|
877
|
+
- ✅ Background script execution (sys_trigger)
|
|
878
|
+
- ✅ Workflow creation
|
|
879
|
+
|
|
880
|
+
**Missing:**
|
|
881
|
+
- ❌ Flow Designer complex logic creation
|
|
882
|
+
- ❌ Visual UI testing
|
|
883
|
+
- ❌ Screenshot automation
|
|
884
|
+
|
|
885
|
+
**Verdict:** Covers almost all needs, proven reliable
|
|
886
|
+
|
|
887
|
+
### Alternative 2: Template + Clone Approach ✅ VIABLE
|
|
888
|
+
|
|
889
|
+
**For Flow Designer:**
|
|
890
|
+
1. Create template flows in UI
|
|
891
|
+
2. Export as update sets
|
|
892
|
+
3. Clone via REST API
|
|
893
|
+
4. Modify via background scripts
|
|
894
|
+
|
|
895
|
+
**Pros:**
|
|
896
|
+
- No Puppeteer needed
|
|
897
|
+
- Reliable and maintainable
|
|
898
|
+
- Version-controlled templates
|
|
899
|
+
|
|
900
|
+
**Cons:**
|
|
901
|
+
- Limited flexibility
|
|
902
|
+
- Requires template maintenance
|
|
903
|
+
|
|
904
|
+
### Alternative 3: Selenium (Not Recommended)
|
|
905
|
+
|
|
906
|
+
**Comparison with Puppeteer:**
|
|
907
|
+
- Similar capabilities
|
|
908
|
+
- More complex setup
|
|
909
|
+
- Worse performance
|
|
910
|
+
- Less Node.js-friendly
|
|
911
|
+
|
|
912
|
+
**Verdict:** No advantage over Puppeteer
|
|
913
|
+
|
|
914
|
+
### Alternative 4: Playwright (Better Alternative)
|
|
915
|
+
|
|
916
|
+
**Advantages over Puppeteer:**
|
|
917
|
+
- ✅ Better cross-browser support (Chrome, Firefox, Safari)
|
|
918
|
+
- ✅ Better error messages
|
|
919
|
+
- ✅ Auto-waiting for elements
|
|
920
|
+
- ✅ Better debugging tools
|
|
921
|
+
- ✅ More reliable selectors
|
|
922
|
+
|
|
923
|
+
**Disadvantages:**
|
|
924
|
+
- Heavier dependency
|
|
925
|
+
- More complex
|
|
926
|
+
|
|
927
|
+
**Verdict:** If implementing browser automation, consider Playwright instead
|
|
928
|
+
|
|
929
|
+
---
|
|
930
|
+
|
|
931
|
+
## 9. Final Recommendation
|
|
932
|
+
|
|
933
|
+
### IMPLEMENT LATER (Priority: Low)
|
|
934
|
+
|
|
935
|
+
#### Recommendation Tier: D (Nice-to-Have, Not Critical)
|
|
936
|
+
|
|
937
|
+
**Reasoning:**
|
|
938
|
+
|
|
939
|
+
1. **Low ROI**
|
|
940
|
+
- Recent UI API breakthrough (`/api/now/ui/concoursepicker/*`) solved 90% of UI-only operations
|
|
941
|
+
- REST API + background scripts cover nearly all use cases
|
|
942
|
+
- Flow Designer template approach is viable workaround
|
|
943
|
+
- Current tools (34 MCP tools) already comprehensive
|
|
944
|
+
|
|
945
|
+
2. **High Cost**
|
|
946
|
+
- Significant implementation complexity (4-8 weeks)
|
|
947
|
+
- Ongoing maintenance burden (selector updates)
|
|
948
|
+
- Performance impact (15-80x slower)
|
|
949
|
+
- Resource overhead (memory, CPU)
|
|
950
|
+
- Security risks (browser vulnerabilities)
|
|
951
|
+
|
|
952
|
+
3. **Limited Demand**
|
|
953
|
+
- No community examples of ServiceNow + Puppeteer
|
|
954
|
+
- ServiceNow users rely on REST API for automation
|
|
955
|
+
- Official Puppeteer MCP server was archived (no demand)
|
|
956
|
+
|
|
957
|
+
4. **Better Alternatives**
|
|
958
|
+
- REST API: Faster, more reliable, better documented
|
|
959
|
+
- Background Scripts: Can do anything Puppeteer can, server-side
|
|
960
|
+
- Template Approach: Proven for Flow Designer
|
|
961
|
+
- Playwright: If browser automation needed, better than Puppeteer
|
|
962
|
+
|
|
963
|
+
### When to Revisit This Decision
|
|
964
|
+
|
|
965
|
+
**Implement Puppeteer if:**
|
|
966
|
+
1. ✅ User demand emerges for UI testing tools (3+ feature requests)
|
|
967
|
+
2. ✅ ServiceNow removes REST API access (unlikely)
|
|
968
|
+
3. ✅ Critical UI-only operations discovered (can't be solved via REST API)
|
|
969
|
+
4. ✅ Screenshot automation becomes core requirement
|
|
970
|
+
5. ✅ Visual regression testing becomes priority
|
|
971
|
+
|
|
972
|
+
**Until then:**
|
|
973
|
+
- Focus on improving existing REST API tools
|
|
974
|
+
- Expand background script automation
|
|
975
|
+
- Enhance Flow Designer template approach
|
|
976
|
+
- Document UI API discoveries
|
|
977
|
+
|
|
978
|
+
### Immediate Action Items
|
|
979
|
+
|
|
980
|
+
Instead of Puppeteer, invest in:
|
|
981
|
+
|
|
982
|
+
1. **Enhance Flow Designer Support**
|
|
983
|
+
- Implement `SN-List-Flows` tool (read-only)
|
|
984
|
+
- Implement `SN-Clone-Flow` tool (template-based)
|
|
985
|
+
- Document template creation best practices
|
|
986
|
+
- Create flow template library
|
|
987
|
+
|
|
988
|
+
2. **Improve REST API Coverage**
|
|
989
|
+
- Add more convenience tools for common tables
|
|
990
|
+
- Enhance batch operation support
|
|
991
|
+
- Better error messages and validation
|
|
992
|
+
- Performance optimization
|
|
993
|
+
|
|
994
|
+
3. **Background Script Library**
|
|
995
|
+
- Create reusable script templates
|
|
996
|
+
- Document common patterns
|
|
997
|
+
- Build script validation tool
|
|
998
|
+
- Add script testing utilities
|
|
999
|
+
|
|
1000
|
+
4. **Documentation**
|
|
1001
|
+
- Create comprehensive usage guides
|
|
1002
|
+
- Add video tutorials
|
|
1003
|
+
- Build example repository
|
|
1004
|
+
- Community contribution guide
|
|
1005
|
+
|
|
1006
|
+
---
|
|
1007
|
+
|
|
1008
|
+
## 10. Proof of Concept (If Approved)
|
|
1009
|
+
|
|
1010
|
+
### Simplest Puppeteer Operation: Screenshot Capture
|
|
1011
|
+
|
|
1012
|
+
**Goal:** Prove Puppeteer can authenticate and capture ServiceNow screenshots
|
|
1013
|
+
|
|
1014
|
+
**Implementation:**
|
|
1015
|
+
```javascript
|
|
1016
|
+
// src/proof-of-concept/puppeteer-screenshot.js
|
|
1017
|
+
|
|
1018
|
+
import puppeteer from 'puppeteer';
|
|
1019
|
+
import fs from 'fs/promises';
|
|
1020
|
+
|
|
1021
|
+
async function captureServiceNowScreenshot(instance, username, password, url) {
|
|
1022
|
+
const browser = await puppeteer.launch({
|
|
1023
|
+
headless: true,
|
|
1024
|
+
args: ['--no-sandbox']
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
try {
|
|
1028
|
+
const page = await browser.newPage();
|
|
1029
|
+
|
|
1030
|
+
// Set viewport
|
|
1031
|
+
await page.setViewport({ width: 1920, height: 1080 });
|
|
1032
|
+
|
|
1033
|
+
// Navigate to login
|
|
1034
|
+
await page.goto(`${instance}/login.do`);
|
|
1035
|
+
|
|
1036
|
+
// Authenticate
|
|
1037
|
+
await page.type('#user_name', username);
|
|
1038
|
+
await page.type('#user_password', password);
|
|
1039
|
+
await page.click('#sysverb_login');
|
|
1040
|
+
await page.waitForSelector('#user_info_dropdown', { timeout: 10000 });
|
|
1041
|
+
|
|
1042
|
+
// Navigate to target page
|
|
1043
|
+
await page.goto(`${instance}${url}`);
|
|
1044
|
+
await page.waitForSelector('body', { timeout: 10000 });
|
|
1045
|
+
|
|
1046
|
+
// Capture screenshot
|
|
1047
|
+
const screenshot = await page.screenshot({ fullPage: true });
|
|
1048
|
+
|
|
1049
|
+
// Save session for reuse
|
|
1050
|
+
const cookies = await page.cookies();
|
|
1051
|
+
await fs.writeFile('session.json', JSON.stringify(cookies));
|
|
1052
|
+
|
|
1053
|
+
return screenshot;
|
|
1054
|
+
} finally {
|
|
1055
|
+
await browser.close();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// Test
|
|
1060
|
+
const result = await captureServiceNowScreenshot(
|
|
1061
|
+
'https://dev123.service-now.com',
|
|
1062
|
+
'admin',
|
|
1063
|
+
'password',
|
|
1064
|
+
'/incident.do?sys_id=-1'
|
|
1065
|
+
);
|
|
1066
|
+
|
|
1067
|
+
await fs.writeFile('screenshot.png', result);
|
|
1068
|
+
console.log('✅ Screenshot captured successfully');
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
**Expected Result:**
|
|
1072
|
+
- ✅ Successfully authenticates
|
|
1073
|
+
- ✅ Captures screenshot of incident form
|
|
1074
|
+
- ✅ Saves session cookies
|
|
1075
|
+
- ⏱️ Takes ~5-8 seconds
|
|
1076
|
+
|
|
1077
|
+
**Success Criteria:**
|
|
1078
|
+
- Screenshot clearly shows ServiceNow interface
|
|
1079
|
+
- Authentication works without manual intervention
|
|
1080
|
+
- Session persists across operations
|
|
1081
|
+
|
|
1082
|
+
**Go/No-Go Decision:**
|
|
1083
|
+
- If POC succeeds easily → Consider implementation
|
|
1084
|
+
- If authentication fails → Investigate SSO/MFA blockers
|
|
1085
|
+
- If performance > 15 seconds → Not viable
|
|
1086
|
+
|
|
1087
|
+
---
|
|
1088
|
+
|
|
1089
|
+
## 11. Comparison with Current Capabilities
|
|
1090
|
+
|
|
1091
|
+
### Current MCP Server (v2.0) Capabilities
|
|
1092
|
+
|
|
1093
|
+
| Category | Tools | Coverage |
|
|
1094
|
+
|----------|-------|----------|
|
|
1095
|
+
| **Instance Management** | 2 tools | ✅ 100% |
|
|
1096
|
+
| **Table Operations** | 8 tools | ✅ 100% |
|
|
1097
|
+
| **ITSM** | 7 tools | ✅ 90% |
|
|
1098
|
+
| **Update Sets** | 5 tools | ✅ 100% (via UI API) |
|
|
1099
|
+
| **Script Execution** | 2 tools | ✅ 100% (via sys_trigger) |
|
|
1100
|
+
| **Workflow** | 4 tools | ✅ 90% |
|
|
1101
|
+
| **Flow Designer** | 0 tools | ❌ 0% (complex logic) |
|
|
1102
|
+
| **UI Testing** | 0 tools | ❌ 0% |
|
|
1103
|
+
| **Screenshots** | 0 tools | ❌ 0% |
|
|
1104
|
+
|
|
1105
|
+
### With Puppeteer Integration
|
|
1106
|
+
|
|
1107
|
+
| Category | Additional Tools | Coverage Gain |
|
|
1108
|
+
|----------|-----------------|---------------|
|
|
1109
|
+
| **Flow Designer** | +5 tools | ✅ 70% (logic creation) |
|
|
1110
|
+
| **UI Testing** | +3 tools | ✅ 80% (validation) |
|
|
1111
|
+
| **Screenshots** | +2 tools | ✅ 100% (automation) |
|
|
1112
|
+
| **Form Validation** | +2 tools | ✅ 90% (layout checks) |
|
|
1113
|
+
|
|
1114
|
+
**Overall Coverage Increase:** 5% (from 95% to 100%)
|
|
1115
|
+
|
|
1116
|
+
**Is 5% gain worth the cost?**
|
|
1117
|
+
- Implementation: 4-8 weeks
|
|
1118
|
+
- Maintenance: Ongoing
|
|
1119
|
+
- Performance impact: Negative
|
|
1120
|
+
- Complexity: High
|
|
1121
|
+
|
|
1122
|
+
**Verdict:** Not worth the cost for 5% coverage gain
|
|
1123
|
+
|
|
1124
|
+
---
|
|
1125
|
+
|
|
1126
|
+
## 12. Proposed MCP Tools (If Implemented)
|
|
1127
|
+
|
|
1128
|
+
### Tier 1: Essential Tools
|
|
1129
|
+
|
|
1130
|
+
#### SN-Puppeteer-Screenshot
|
|
1131
|
+
**Description:** Capture screenshot of ServiceNow page or element
|
|
1132
|
+
|
|
1133
|
+
**Parameters:**
|
|
1134
|
+
```javascript
|
|
1135
|
+
{
|
|
1136
|
+
url: string, // Relative URL (e.g., "/incident.do")
|
|
1137
|
+
selector: string, // CSS selector (optional, defaults to full page)
|
|
1138
|
+
width: number, // Viewport width (default: 1920)
|
|
1139
|
+
height: number, // Viewport height (default: 1080)
|
|
1140
|
+
fullPage: boolean, // Capture full page (default: true)
|
|
1141
|
+
format: 'png' | 'jpeg' // Image format (default: 'png')
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
**Returns:**
|
|
1146
|
+
```javascript
|
|
1147
|
+
{
|
|
1148
|
+
success: boolean,
|
|
1149
|
+
screenshot: Buffer, // Image data
|
|
1150
|
+
dimensions: { width, height },
|
|
1151
|
+
timestamp: string
|
|
1152
|
+
}
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
#### SN-Puppeteer-Navigate
|
|
1156
|
+
**Description:** Navigate to ServiceNow page and return page info
|
|
1157
|
+
|
|
1158
|
+
**Parameters:**
|
|
1159
|
+
```javascript
|
|
1160
|
+
{
|
|
1161
|
+
url: string, // Relative URL
|
|
1162
|
+
waitFor: string // Selector to wait for (optional)
|
|
1163
|
+
}
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
**Returns:**
|
|
1167
|
+
```javascript
|
|
1168
|
+
{
|
|
1169
|
+
success: boolean,
|
|
1170
|
+
url: string, // Final URL after redirects
|
|
1171
|
+
title: string, // Page title
|
|
1172
|
+
loaded: boolean
|
|
1173
|
+
}
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
### Tier 2: Flow Designer Tools
|
|
1177
|
+
|
|
1178
|
+
#### SN-Puppeteer-Create-Flow
|
|
1179
|
+
**Description:** Create Flow Designer flow with logic blocks
|
|
1180
|
+
|
|
1181
|
+
**Parameters:**
|
|
1182
|
+
```javascript
|
|
1183
|
+
{
|
|
1184
|
+
name: string,
|
|
1185
|
+
description: string,
|
|
1186
|
+
trigger: 'record' | 'schedule' | 'rest',
|
|
1187
|
+
table: string, // For record trigger
|
|
1188
|
+
condition: string, // Flow trigger condition
|
|
1189
|
+
logicBlocks: [ // Logic blocks to add
|
|
1190
|
+
{
|
|
1191
|
+
type: 'if' | 'foreach' | 'action',
|
|
1192
|
+
condition: string,
|
|
1193
|
+
action: string,
|
|
1194
|
+
parameters: object
|
|
1195
|
+
}
|
|
1196
|
+
]
|
|
1197
|
+
}
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
**Returns:**
|
|
1201
|
+
```javascript
|
|
1202
|
+
{
|
|
1203
|
+
success: boolean,
|
|
1204
|
+
flow_sys_id: string,
|
|
1205
|
+
url: string, // Link to Flow Designer
|
|
1206
|
+
compiled: boolean
|
|
1207
|
+
}
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
### Tier 3: UI Testing Tools
|
|
1211
|
+
|
|
1212
|
+
#### SN-Puppeteer-Test-UI-Policy
|
|
1213
|
+
**Description:** Test UI policy behavior
|
|
1214
|
+
|
|
1215
|
+
**Parameters:**
|
|
1216
|
+
```javascript
|
|
1217
|
+
{
|
|
1218
|
+
form: string, // Form name (e.g., "incident")
|
|
1219
|
+
uiPolicy: string, // UI policy name
|
|
1220
|
+
testCases: [
|
|
1221
|
+
{
|
|
1222
|
+
setField: string,
|
|
1223
|
+
setValue: any,
|
|
1224
|
+
expectField: string,
|
|
1225
|
+
expectState: 'visible' | 'mandatory' | 'readonly'
|
|
1226
|
+
}
|
|
1227
|
+
]
|
|
1228
|
+
}
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1231
|
+
**Returns:**
|
|
1232
|
+
```javascript
|
|
1233
|
+
{
|
|
1234
|
+
success: boolean,
|
|
1235
|
+
results: [
|
|
1236
|
+
{
|
|
1237
|
+
testCase: object,
|
|
1238
|
+
passed: boolean,
|
|
1239
|
+
actual: string,
|
|
1240
|
+
expected: string
|
|
1241
|
+
}
|
|
1242
|
+
]
|
|
1243
|
+
}
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
---
|
|
1247
|
+
|
|
1248
|
+
## 13. Conclusion
|
|
1249
|
+
|
|
1250
|
+
### Summary
|
|
1251
|
+
|
|
1252
|
+
Puppeteer integration for ServiceNow MCP Server is **technically feasible** but **not strategically necessary** at this time.
|
|
1253
|
+
|
|
1254
|
+
**Key Findings:**
|
|
1255
|
+
1. ✅ Puppeteer can automate UI operations
|
|
1256
|
+
2. ✅ Authentication and session management are solvable
|
|
1257
|
+
3. ❌ Performance is significantly worse than REST API (15-80x slower)
|
|
1258
|
+
4. ❌ Maintenance burden is high (selector updates, version compatibility)
|
|
1259
|
+
5. ❌ Limited value proposition (5% coverage gain)
|
|
1260
|
+
6. ✅ Better alternatives exist (REST API, background scripts, templates)
|
|
1261
|
+
|
|
1262
|
+
### Final Recommendation: DEFER
|
|
1263
|
+
|
|
1264
|
+
**Do NOT implement Puppeteer integration now.**
|
|
1265
|
+
|
|
1266
|
+
**Instead:**
|
|
1267
|
+
1. Continue enhancing REST API tools
|
|
1268
|
+
2. Expand background script automation
|
|
1269
|
+
3. Develop Flow Designer template approach
|
|
1270
|
+
4. Document UI API discoveries
|
|
1271
|
+
5. Monitor user demand for browser automation
|
|
1272
|
+
|
|
1273
|
+
**Revisit decision if:**
|
|
1274
|
+
- Multiple users request UI testing tools
|
|
1275
|
+
- Critical UI-only operations discovered
|
|
1276
|
+
- ServiceNow removes REST API access (extremely unlikely)
|
|
1277
|
+
|
|
1278
|
+
### Next Steps
|
|
1279
|
+
|
|
1280
|
+
1. ✅ Close this research (document archived)
|
|
1281
|
+
2. ✅ Focus on improving existing tools
|
|
1282
|
+
3. ✅ Create Flow Designer template library
|
|
1283
|
+
4. ✅ Enhance REST API coverage
|
|
1284
|
+
5. ⏸️ Monitor community feedback for Puppeteer demand
|
|
1285
|
+
|
|
1286
|
+
---
|
|
1287
|
+
|
|
1288
|
+
## 14. References
|
|
1289
|
+
|
|
1290
|
+
### Research Sources
|
|
1291
|
+
|
|
1292
|
+
**Puppeteer Documentation:**
|
|
1293
|
+
- https://pptr.dev/
|
|
1294
|
+
- https://github.com/puppeteer/puppeteer
|
|
1295
|
+
|
|
1296
|
+
**MCP Puppeteer Server:**
|
|
1297
|
+
- https://github.com/modelcontextprotocol/servers-archived (archived)
|
|
1298
|
+
- https://www.npmjs.com/package/@modelcontextprotocol/server-puppeteer
|
|
1299
|
+
|
|
1300
|
+
**ServiceNow APIs:**
|
|
1301
|
+
- REST API: https://docs.servicenow.com/
|
|
1302
|
+
- UI API: `/api/now/ui/concoursepicker/*` (discovered 2025-09-29)
|
|
1303
|
+
- Background Script: `sys_trigger` table (automated execution)
|
|
1304
|
+
|
|
1305
|
+
**Community Resources:**
|
|
1306
|
+
- ServiceNow Community: https://www.servicenow.com/community/
|
|
1307
|
+
- Reddit r/servicenow: https://www.reddit.com/r/servicenow/
|
|
1308
|
+
|
|
1309
|
+
### Related Project Documentation
|
|
1310
|
+
|
|
1311
|
+
- `/docs/research/UI_API_BREAKTHROUGH.md` - UI API discovery
|
|
1312
|
+
- `/docs/research/FLOW_DESIGNER_LIMITATIONS.md` - Flow Designer analysis
|
|
1313
|
+
- `/docs/research/WORKFLOW_VS_FLOW_DESIGNER.md` - Automation comparison
|
|
1314
|
+
- `/docs/BACKGROUND_SCRIPT_EXECUTION.md` - Background script automation
|
|
1315
|
+
- `/docs/API_REFERENCE.md` - Complete MCP tool reference
|
|
1316
|
+
|
|
1317
|
+
---
|
|
1318
|
+
|
|
1319
|
+
**Document Version:** 1.0
|
|
1320
|
+
**Last Updated:** 2025-10-06
|
|
1321
|
+
**Status:** FINAL RECOMMENDATION - DEFER IMPLEMENTATION
|
|
1322
|
+
**Approval Required:** Product Owner / Technical Lead
|