snow-flow 4.3.6 ā 4.3.8
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/dist/cli.js +20 -11
- package/dist/mcp/servicenow-knowledge-catalog-mcp.js +239 -242
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -754,28 +754,36 @@ Memory.store("swarm_session_${sessionId}", JSON.stringify({
|
|
|
754
754
|
}));
|
|
755
755
|
\`\`\`
|
|
756
756
|
|
|
757
|
-
### 2.
|
|
758
|
-
**
|
|
757
|
+
### 2. šØ MANDATORY: ServiceNow Auth & Update Set Setup
|
|
758
|
+
**CRITICAL: These steps are REQUIRED for ALL development work:**
|
|
759
759
|
|
|
760
760
|
\`\`\`javascript
|
|
761
|
-
// Step 2.1: Test ServiceNow authentication
|
|
761
|
+
// Step 2.1: MANDATORY - Test ServiceNow authentication
|
|
762
762
|
const authCheck = await snow_auth_diagnostics();
|
|
763
763
|
if (!authCheck.success) {
|
|
764
|
-
throw new Error("Authentication failed! Run: snow-flow auth login");
|
|
764
|
+
throw new Error("ā CRITICAL: Authentication failed! Run: snow-flow auth login");
|
|
765
765
|
}
|
|
766
766
|
|
|
767
|
-
// Step 2.2: Create Update Set for tracking changes
|
|
767
|
+
// Step 2.2: MANDATORY - Create Update Set for tracking ALL changes
|
|
768
768
|
const updateSetName = "Snow-Flow: ${objective.substring(0, 50)}... - ${new Date().toISOString().split('T')[0]}";
|
|
769
769
|
const updateSet = await snow_update_set_create({
|
|
770
770
|
name: updateSetName,
|
|
771
|
-
description: "Automated
|
|
772
|
-
auto_switch: true
|
|
771
|
+
description: "Automated Snow-Flow development for: ${objective}\\n\\nSession: ${sessionId}\\nAll changes tracked automatically",
|
|
772
|
+
auto_switch: true // šØ CRITICAL: Sets as current update set!
|
|
773
773
|
});
|
|
774
774
|
|
|
775
|
-
// Store Update Set info in memory
|
|
775
|
+
// Store Update Set info in memory for all agents
|
|
776
776
|
Memory.store("update_set_${sessionId}", JSON.stringify(updateSet));
|
|
777
|
+
Memory.store("current_update_set", updateSet.sys_id);
|
|
777
778
|
\`\`\`
|
|
778
779
|
|
|
780
|
+
**WHY THIS IS CRITICAL:**
|
|
781
|
+
- ā
All ServiceNow changes are automatically tracked
|
|
782
|
+
- ā
Enables deployment to other instances later
|
|
783
|
+
- ā
Provides rollback capabilities
|
|
784
|
+
- ā
Follows ServiceNow development best practices
|
|
785
|
+
- ā **WITHOUT UPDATE SET: Changes are untracked and risky!**
|
|
786
|
+
|
|
779
787
|
### 3. Create Master Task List
|
|
780
788
|
After completing setup steps, create task breakdown:
|
|
781
789
|
\`\`\`javascript
|
|
@@ -890,10 +898,11 @@ ${isAuthenticated ? 'ā
Authentication detected - full deployment capabilities'
|
|
|
890
898
|
|
|
891
899
|
Your agents MUST use these MCP tools IN THIS ORDER:
|
|
892
900
|
|
|
893
|
-
|
|
901
|
+
šØ **MANDATORY PRE-FLIGHT CHECKS** (ALWAYS do first!):
|
|
894
902
|
1. \`snow_auth_diagnostics\` - Test authentication and permissions
|
|
895
|
-
2.
|
|
896
|
-
3.
|
|
903
|
+
2. \`snow_update_set_create\` - Create and activate update set for tracking
|
|
904
|
+
3. If auth fails, STOP and provide instructions to run 'snow-flow auth login'
|
|
905
|
+
4. If update set fails, STOP - development work is not safe without tracking
|
|
897
906
|
|
|
898
907
|
šÆ **Core Development Tools**:
|
|
899
908
|
1. **Universal Query Tool**: \`snow_query_table\` - Works with ALL ServiceNow tables
|
|
@@ -1315,49 +1315,50 @@ ${args.help_text ? `ā Help: ${args.help_text}` : ''}
|
|
|
1315
1315
|
* Helper function to format action details for display
|
|
1316
1316
|
*/
|
|
1317
1317
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
}
|
|
1329
|
-
if (action.readonly !== undefined) {
|
|
1330
|
-
details.push(`Read-only: ${action.readonly}`);
|
|
1331
|
-
}
|
|
1332
|
-
if (action.value !== undefined && action.value !== '') {
|
|
1333
|
-
details.push(`Value: "${action.value}"`);
|
|
1334
|
-
}
|
|
1335
|
-
return details.length > 0 ? details.join(', ') : 'No specific action';
|
|
1318
|
+
catch(error) { n; this.logger.error('Failed to create catalog UI policy:', error); n; return { content: [{ type: 'text', text: `ā Failed to create catalog UI policy: ${error.message || error}` }] }; n; }
|
|
1319
|
+
}
|
|
1320
|
+
n;
|
|
1321
|
+
n;
|
|
1322
|
+
formatActionDetails(action, any);
|
|
1323
|
+
string;
|
|
1324
|
+
{
|
|
1325
|
+
const details = [];
|
|
1326
|
+
if (action.mandatory !== undefined) {
|
|
1327
|
+
details.push(`Mandatory: ${action.mandatory}`);
|
|
1336
1328
|
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1329
|
+
if (action.visible !== undefined) {
|
|
1330
|
+
details.push(`Visible: ${action.visible}`);
|
|
1331
|
+
}
|
|
1332
|
+
if (action.readonly !== undefined) {
|
|
1333
|
+
details.push(`Read-only: ${action.readonly}`);
|
|
1334
|
+
}
|
|
1335
|
+
if (action.value !== undefined && action.value !== '') {
|
|
1336
|
+
details.push(`Value: "${action.value}"`);
|
|
1337
|
+
}
|
|
1338
|
+
return details.length > 0 ? details.join(', ') : 'No specific action';
|
|
1339
|
+
}
|
|
1340
|
+
async;
|
|
1341
|
+
createCatalogClientScript(args, any);
|
|
1342
|
+
{
|
|
1343
|
+
try {
|
|
1344
|
+
this.logger.info('Creating catalog client script...');
|
|
1345
|
+
const scriptData = {
|
|
1346
|
+
cat_item: args.cat_item,
|
|
1347
|
+
name: args.name,
|
|
1348
|
+
script: args.script,
|
|
1349
|
+
type: args.type,
|
|
1350
|
+
applies_to: args.applies_to || 'item',
|
|
1351
|
+
cat_variable: args.variable || '',
|
|
1352
|
+
active: args.active !== false
|
|
1353
|
+
};
|
|
1354
|
+
const response = await this.client.createRecord('catalog_script_client', scriptData);
|
|
1355
|
+
if (!response.success) {
|
|
1356
|
+
throw new Error(`Failed to create catalog client script: ${response.error}`);
|
|
1357
|
+
}
|
|
1358
|
+
return {
|
|
1359
|
+
content: [{
|
|
1360
|
+
type: 'text',
|
|
1361
|
+
text: `ā
Catalog Client Script created successfully!
|
|
1361
1362
|
|
|
1362
1363
|
š **${args.name}**
|
|
1363
1364
|
š sys_id: ${response.data.sys_id}
|
|
@@ -1367,118 +1368,115 @@ ${args.variable ? `š Variable: ${args.variable}` : ''}
|
|
|
1367
1368
|
š Active: ${args.active !== false ? 'Yes' : 'No'}
|
|
1368
1369
|
|
|
1369
1370
|
⨠Client script added to catalog item!`
|
|
1371
|
+
}]
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
catch (error) {
|
|
1375
|
+
this.logger.error('Failed to create catalog client script:', error);
|
|
1376
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create catalog client script: ${error}`);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
async;
|
|
1380
|
+
searchCatalog(args, any);
|
|
1381
|
+
{
|
|
1382
|
+
try {
|
|
1383
|
+
this.logger.info('Searching service catalog...');
|
|
1384
|
+
let query = args.query ? `nameLIKE${args.query}^ORshort_descriptionLIKE${args.query}` : '';
|
|
1385
|
+
if (args.category) {
|
|
1386
|
+
query += query ? '^' : '';
|
|
1387
|
+
query += `category=${args.category}`;
|
|
1388
|
+
}
|
|
1389
|
+
if (args.catalog) {
|
|
1390
|
+
query += query ? '^' : '';
|
|
1391
|
+
query += `sc_catalogs=${args.catalog}`;
|
|
1392
|
+
}
|
|
1393
|
+
if (args.active_only) {
|
|
1394
|
+
query += query ? '^' : '';
|
|
1395
|
+
query += 'active=true';
|
|
1396
|
+
}
|
|
1397
|
+
const limit = args.limit || 20;
|
|
1398
|
+
this.logger.trackAPICall('SEARCH', 'sc_cat_item', limit);
|
|
1399
|
+
const response = await this.client.searchRecords('sc_cat_item', query, limit);
|
|
1400
|
+
if (!response.success) {
|
|
1401
|
+
throw new Error('Failed to search catalog');
|
|
1402
|
+
}
|
|
1403
|
+
const items = response.data.result;
|
|
1404
|
+
if (!items.length) {
|
|
1405
|
+
return {
|
|
1406
|
+
content: [{
|
|
1407
|
+
type: 'text',
|
|
1408
|
+
text: `ā No catalog items found${args.query ? ` matching "${args.query}"` : ''}`
|
|
1370
1409
|
}]
|
|
1371
1410
|
};
|
|
1372
1411
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to create catalog client script: ${error}`);
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Search Service Catalog
|
|
1380
|
-
*/
|
|
1381
|
-
async searchCatalog(args) {
|
|
1382
|
-
try {
|
|
1383
|
-
this.logger.info('Searching service catalog...');
|
|
1384
|
-
let query = args.query ? `nameLIKE${args.query}^ORshort_descriptionLIKE${args.query}` : '';
|
|
1385
|
-
if (args.category) {
|
|
1386
|
-
query += query ? '^' : '';
|
|
1387
|
-
query += `category=${args.category}`;
|
|
1388
|
-
}
|
|
1389
|
-
if (args.catalog) {
|
|
1390
|
-
query += query ? '^' : '';
|
|
1391
|
-
query += `sc_catalogs=${args.catalog}`;
|
|
1392
|
-
}
|
|
1393
|
-
if (args.active_only) {
|
|
1394
|
-
query += query ? '^' : '';
|
|
1395
|
-
query += 'active=true';
|
|
1396
|
-
}
|
|
1397
|
-
const limit = args.limit || 20;
|
|
1398
|
-
this.logger.trackAPICall('SEARCH', 'sc_cat_item', limit);
|
|
1399
|
-
const response = await this.client.searchRecords('sc_cat_item', query, limit);
|
|
1400
|
-
if (!response.success) {
|
|
1401
|
-
throw new Error('Failed to search catalog');
|
|
1402
|
-
}
|
|
1403
|
-
const items = response.data.result;
|
|
1404
|
-
if (!items.length) {
|
|
1405
|
-
return {
|
|
1406
|
-
content: [{
|
|
1407
|
-
type: 'text',
|
|
1408
|
-
text: `ā No catalog items found${args.query ? ` matching "${args.query}"` : ''}`
|
|
1409
|
-
}]
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
const itemList = items.map((item) => {
|
|
1413
|
-
return `šļø **${item.name}**
|
|
1412
|
+
const itemList = items.map((item) => {
|
|
1413
|
+
return `šļø **${item.name}**
|
|
1414
1414
|
š ${item.sys_id}
|
|
1415
1415
|
š ${item.short_description}
|
|
1416
1416
|
${item.price && item.price !== '0' ? `š° Price: $${item.price}` : ''}
|
|
1417
1417
|
š Active: ${item.active ? 'Yes' : 'No'}`;
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1418
|
+
}).join('\n\n');
|
|
1419
|
+
return {
|
|
1420
|
+
content: [{
|
|
1421
|
+
type: 'text',
|
|
1422
|
+
text: `š Catalog Search Results${args.query ? ` for "${args.query}"` : ''}:
|
|
1423
1423
|
|
|
1424
1424
|
${itemList}
|
|
1425
1425
|
|
|
1426
1426
|
⨠Found ${items.length} catalog item(s)`
|
|
1427
|
-
|
|
1428
|
-
|
|
1427
|
+
}]
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
catch (error) {
|
|
1431
|
+
this.logger.error('Failed to search catalog:', error);
|
|
1432
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search catalog: ${error}`);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
async;
|
|
1436
|
+
orderCatalogItem(args, any);
|
|
1437
|
+
{
|
|
1438
|
+
try {
|
|
1439
|
+
this.logger.info('Ordering catalog item...');
|
|
1440
|
+
// Create service catalog request
|
|
1441
|
+
const requestData = {
|
|
1442
|
+
requested_for: args.requested_for,
|
|
1443
|
+
opened_by: args.requested_for,
|
|
1444
|
+
special_instructions: args.special_instructions || ''
|
|
1445
|
+
};
|
|
1446
|
+
const requestResponse = await this.client.createRecord('sc_request', requestData);
|
|
1447
|
+
if (!requestResponse.success) {
|
|
1448
|
+
throw new Error(`Failed to create request: ${requestResponse.error}`);
|
|
1429
1449
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1450
|
+
const requestId = requestResponse.data.sys_id;
|
|
1451
|
+
// Create requested item (RITM)
|
|
1452
|
+
const ritmData = {
|
|
1453
|
+
request: requestId,
|
|
1454
|
+
cat_item: args.cat_item,
|
|
1455
|
+
requested_for: args.requested_for,
|
|
1456
|
+
quantity: args.quantity || 1,
|
|
1457
|
+
delivery_address: args.delivery_address || ''
|
|
1458
|
+
};
|
|
1459
|
+
const ritmResponse = await this.client.createRecord('sc_req_item', ritmData);
|
|
1460
|
+
if (!ritmResponse.success) {
|
|
1461
|
+
throw new Error(`Failed to create requested item: ${ritmResponse.error}`);
|
|
1433
1462
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
opened_by: args.requested_for,
|
|
1446
|
-
special_instructions: args.special_instructions || ''
|
|
1447
|
-
};
|
|
1448
|
-
const requestResponse = await this.client.createRecord('sc_request', requestData);
|
|
1449
|
-
if (!requestResponse.success) {
|
|
1450
|
-
throw new Error(`Failed to create request: ${requestResponse.error}`);
|
|
1451
|
-
}
|
|
1452
|
-
const requestId = requestResponse.data.sys_id;
|
|
1453
|
-
// Create requested item (RITM)
|
|
1454
|
-
const ritmData = {
|
|
1455
|
-
request: requestId,
|
|
1456
|
-
cat_item: args.cat_item,
|
|
1457
|
-
requested_for: args.requested_for,
|
|
1458
|
-
quantity: args.quantity || 1,
|
|
1459
|
-
delivery_address: args.delivery_address || ''
|
|
1460
|
-
};
|
|
1461
|
-
const ritmResponse = await this.client.createRecord('sc_req_item', ritmData);
|
|
1462
|
-
if (!ritmResponse.success) {
|
|
1463
|
-
throw new Error(`Failed to create requested item: ${ritmResponse.error}`);
|
|
1464
|
-
}
|
|
1465
|
-
const ritmId = ritmResponse.data.sys_id;
|
|
1466
|
-
const ritmNumber = ritmResponse.data.number;
|
|
1467
|
-
// Set variable values if provided
|
|
1468
|
-
if (args.variables) {
|
|
1469
|
-
for (const [varName, varValue] of Object.entries(args.variables)) {
|
|
1470
|
-
const varData = {
|
|
1471
|
-
request_item: ritmId,
|
|
1472
|
-
name: varName,
|
|
1473
|
-
value: varValue
|
|
1474
|
-
};
|
|
1475
|
-
await this.client.createRecord('sc_item_option_mtom', varData);
|
|
1476
|
-
}
|
|
1463
|
+
const ritmId = ritmResponse.data.sys_id;
|
|
1464
|
+
const ritmNumber = ritmResponse.data.number;
|
|
1465
|
+
// Set variable values if provided
|
|
1466
|
+
if (args.variables) {
|
|
1467
|
+
for (const [varName, varValue] of Object.entries(args.variables)) {
|
|
1468
|
+
const varData = {
|
|
1469
|
+
request_item: ritmId,
|
|
1470
|
+
name: varName,
|
|
1471
|
+
value: varValue
|
|
1472
|
+
};
|
|
1473
|
+
await this.client.createRecord('sc_item_option_mtom', varData);
|
|
1477
1474
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1475
|
+
}
|
|
1476
|
+
return {
|
|
1477
|
+
content: [{
|
|
1478
|
+
type: 'text',
|
|
1479
|
+
text: `ā
Catalog Item ordered successfully!
|
|
1482
1480
|
|
|
1483
1481
|
šļø **Order Placed**
|
|
1484
1482
|
š Request: ${requestId}
|
|
@@ -1489,52 +1487,51 @@ ${args.delivery_address ? `š Delivery: ${args.delivery_address}` : ''}
|
|
|
1489
1487
|
${args.special_instructions ? `š Instructions: ${args.special_instructions}` : ''}
|
|
1490
1488
|
|
|
1491
1489
|
⨠Order submitted for fulfillment!`
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
}
|
|
1495
|
-
catch (error) {
|
|
1496
|
-
this.logger.error('Failed to order catalog item:', error);
|
|
1497
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to order catalog item: ${error}`);
|
|
1498
|
-
}
|
|
1490
|
+
}]
|
|
1491
|
+
};
|
|
1499
1492
|
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
}
|
|
1493
|
+
catch (error) {
|
|
1494
|
+
this.logger.error('Failed to order catalog item:', error);
|
|
1495
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to order catalog item: ${error}`);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
async;
|
|
1499
|
+
getCatalogItemDetails(args, any);
|
|
1500
|
+
{
|
|
1501
|
+
try {
|
|
1502
|
+
this.logger.info('Getting catalog item details...', { sys_id: args.sys_id });
|
|
1503
|
+
// š DEBUGGING: Try different methods to find the item
|
|
1504
|
+
this.logger.info('š Step 1: Trying getRecord method...');
|
|
1505
|
+
let itemResponse = await this.client.getRecord('sc_cat_item', args.sys_id);
|
|
1506
|
+
if (!itemResponse.success) {
|
|
1507
|
+
this.logger.warn('ā getRecord failed, trying searchRecords as fallback...');
|
|
1508
|
+
this.logger.warn('getRecord error:', itemResponse.error);
|
|
1509
|
+
// Fallback: try searchRecords method
|
|
1510
|
+
itemResponse = await this.client.searchRecords('sc_cat_item', `sys_id=${args.sys_id}`, 1);
|
|
1511
|
+
if (!itemResponse.success || itemResponse.data.result.length === 0) {
|
|
1512
|
+
this.logger.error('ā Both getRecord and searchRecords failed');
|
|
1513
|
+
this.logger.error('searchRecords error:', itemResponse.error);
|
|
1514
|
+
// Final fallback: try to query with different parameters
|
|
1515
|
+
const queryResponse = await this.client.queryTable('sc_cat_item', `sys_id=${args.sys_id}`, 1);
|
|
1516
|
+
if (queryResponse.success && queryResponse.data.result.length > 0) {
|
|
1517
|
+
this.logger.info('ā
Found item using queryTable fallback');
|
|
1518
|
+
itemResponse = { success: true, data: queryResponse.data.result[0] };
|
|
1527
1519
|
}
|
|
1528
1520
|
else {
|
|
1529
|
-
this.logger.
|
|
1530
|
-
|
|
1521
|
+
this.logger.error('ā All methods failed to find catalog item');
|
|
1522
|
+
throw new Error(`Catalog item not found with sys_id: ${args.sys_id}. Tried getRecord, searchRecords, and queryTable.`);
|
|
1531
1523
|
}
|
|
1532
1524
|
}
|
|
1533
1525
|
else {
|
|
1534
|
-
this.logger.info('ā
Found item using
|
|
1526
|
+
this.logger.info('ā
Found item using searchRecords fallback');
|
|
1527
|
+
itemResponse = { success: true, data: itemResponse.data.result[0] };
|
|
1535
1528
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1529
|
+
}
|
|
1530
|
+
else {
|
|
1531
|
+
this.logger.info('ā
Found item using getRecord');
|
|
1532
|
+
}
|
|
1533
|
+
const item = itemResponse.data;
|
|
1534
|
+
let details = `šļø **${item.name}**
|
|
1538
1535
|
š sys_id: ${item.sys_id}
|
|
1539
1536
|
š ${item.short_description}
|
|
1540
1537
|
š ${item.description || 'No detailed description'}
|
|
@@ -1542,82 +1539,82 @@ ${item.price && item.price !== '0' ? `š° Price: $${item.price}` : ''}
|
|
|
1542
1539
|
${item.recurring_price && item.recurring_price !== '0' ? `š Recurring: $${item.recurring_price}` : ''}
|
|
1543
1540
|
š¦ Delivery: ${item.delivery_time || '3 business days'}
|
|
1544
1541
|
š Active: ${item.active ? 'Yes' : 'No'}`;
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
}
|
|
1542
|
+
// Get variables if requested
|
|
1543
|
+
if (args.include_variables) {
|
|
1544
|
+
const varResponse = await this.client.searchRecords('sc_cat_item_option', `cat_item=${args.sys_id}`, 50);
|
|
1545
|
+
if (varResponse.success && varResponse.data.result.length) {
|
|
1546
|
+
const variables = varResponse.data.result.map((v) => ` - ${v.question_text} (${v.type})${v.mandatory ? ' *Required' : ''}`).join('\n');
|
|
1547
|
+
details += `\n\nš **Variables:**\n${variables}`;
|
|
1552
1548
|
}
|
|
1553
|
-
return {
|
|
1554
|
-
content: [{
|
|
1555
|
-
type: 'text',
|
|
1556
|
-
text: details + '\n\n⨠Catalog item details retrieved!'
|
|
1557
|
-
}]
|
|
1558
|
-
};
|
|
1559
|
-
}
|
|
1560
|
-
catch (error) {
|
|
1561
|
-
this.logger.error('Failed to get catalog item details:', error);
|
|
1562
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get catalog item details: ${error}`);
|
|
1563
1549
|
}
|
|
1550
|
+
return {
|
|
1551
|
+
content: [{
|
|
1552
|
+
type: 'text',
|
|
1553
|
+
text: details + '\n\n⨠Catalog item details retrieved!'
|
|
1554
|
+
}]
|
|
1555
|
+
};
|
|
1564
1556
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1557
|
+
catch (error) {
|
|
1558
|
+
this.logger.error('Failed to get catalog item details:', error);
|
|
1559
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get catalog item details: ${error}`);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
async;
|
|
1563
|
+
discoverCatalogs(args, any);
|
|
1564
|
+
{
|
|
1565
|
+
try {
|
|
1566
|
+
this.logger.info('Discovering service catalogs...');
|
|
1567
|
+
let query = '';
|
|
1568
|
+
if (args.active_only) {
|
|
1569
|
+
query = 'active=true';
|
|
1570
|
+
}
|
|
1571
|
+
const catalogResponse = await this.client.searchRecords('sc_catalog', query, 50);
|
|
1572
|
+
if (!catalogResponse.success) {
|
|
1573
|
+
throw new Error('Failed to discover catalogs');
|
|
1574
|
+
}
|
|
1575
|
+
const catalogs = catalogResponse.data.result;
|
|
1576
|
+
// Get categories if requested
|
|
1577
|
+
const catalogsWithDetails = await Promise.all(catalogs.map(async (catalog) => {
|
|
1578
|
+
if (args.include_categories) {
|
|
1579
|
+
const catResponse = await this.client.searchRecords('sc_category', `sc_catalog=${catalog.sys_id}`, 20);
|
|
1580
|
+
const categories = catResponse.success ? catResponse.data.result : [];
|
|
1581
|
+
return { ...catalog, categories };
|
|
1578
1582
|
}
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
const catResponse = await this.client.searchRecords('sc_category', `sc_catalog=${catalog.sys_id}`, 20);
|
|
1584
|
-
const categories = catResponse.success ? catResponse.data.result : [];
|
|
1585
|
-
return { ...catalog, categories };
|
|
1586
|
-
}
|
|
1587
|
-
return catalog;
|
|
1588
|
-
}));
|
|
1589
|
-
const catalogText = catalogsWithDetails.map((catalog) => {
|
|
1590
|
-
let text = `šļø **${catalog.title}** ${catalog.active ? 'ā
' : 'ā'}
|
|
1583
|
+
return catalog;
|
|
1584
|
+
}));
|
|
1585
|
+
const catalogText = catalogsWithDetails.map((catalog) => {
|
|
1586
|
+
let text = `šļø **${catalog.title}** ${catalog.active ? 'ā
' : 'ā'}
|
|
1591
1587
|
š ${catalog.sys_id}
|
|
1592
1588
|
š ${catalog.description || 'No description'}`;
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1589
|
+
if (catalog.categories) {
|
|
1590
|
+
const categoryList = catalog.categories.map((cat) => ` - ${cat.title}`).join('\n');
|
|
1591
|
+
text += `\nš Categories:\n${categoryList || ' No categories'}`;
|
|
1592
|
+
}
|
|
1593
|
+
return text;
|
|
1594
|
+
}).join('\n\n');
|
|
1595
|
+
return {
|
|
1596
|
+
content: [{
|
|
1597
|
+
type: 'text',
|
|
1598
|
+
text: `š Discovered Service Catalogs:
|
|
1603
1599
|
|
|
1604
1600
|
${catalogText}
|
|
1605
1601
|
|
|
1606
1602
|
⨠Found ${catalogs.length} catalog(s)`
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
}
|
|
1610
|
-
catch (error) {
|
|
1611
|
-
this.logger.error('Failed to discover catalogs:', error);
|
|
1612
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to discover catalogs: ${error}`);
|
|
1613
|
-
}
|
|
1603
|
+
}]
|
|
1604
|
+
};
|
|
1614
1605
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
this.logger.info('ServiceNow Knowledge & Catalog MCP Server running on stdio');
|
|
1606
|
+
catch (error) {
|
|
1607
|
+
this.logger.error('Failed to discover catalogs:', error);
|
|
1608
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to discover catalogs: ${error}`);
|
|
1619
1609
|
}
|
|
1620
1610
|
}
|
|
1611
|
+
async;
|
|
1612
|
+
run();
|
|
1613
|
+
{
|
|
1614
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1615
|
+
await this.server.connect(transport);
|
|
1616
|
+
this.logger.info('ServiceNow Knowledge & Catalog MCP Server running on stdio');
|
|
1617
|
+
}
|
|
1621
1618
|
const server = new ServiceNowKnowledgeCatalogMCP();
|
|
1622
1619
|
server.run().catch(console.error);
|
|
1623
1620
|
//# sourceMappingURL=servicenow-knowledge-catalog-mcp.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.8",
|
|
4
4
|
"description": "Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 200+ ServiceNow tools for comprehensive platform development.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|