skills/catalog/approval-summarization/SKILL.md
Summarize approval requests with context including what is being requested, who is requesting, business justification, and similar past approvals
npx skillsauth add happy-technologies-llc/happy-servicenow-skills approval-summarizationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill generates comprehensive approval summaries that give approvers the context they need to make informed decisions. It covers:
sysapproval_approver with full request and item contextsys_user including role, department, and managersc_req_item to show exactly what was requestedsc_request for similar requestsWhen to use: When approvers need a quick, comprehensive summary of pending approvals, when building approval digest notifications, or when creating approval dashboards with contextual data.
Value proposition: Reduces approval decision time by presenting all relevant context in a single view, decreases approval bottlenecks, and improves decision quality by surfacing historical precedent and risk factors.
approver_user, itil, or adminsysapproval_approver, sc_request, sc_req_item, sc_cat_item, item_option_new, and sys_userQuery for all approvals awaiting action by a specific approver or group.
Using MCP (Claude Code/Desktop):
Tool: SN-Query-Table
Parameters:
table_name: sysapproval_approver
query: approver=[approver_sys_id]^state=requested
fields: sys_id,sysapproval,sysapproval.number,sysapproval.short_description,sysapproval.sys_class_name,state,approver,group,sys_created_on,due_date,expected_start,comments
limit: 25
order_by: sys_created_on
Using REST API:
GET /api/now/table/sysapproval_approver?sysparm_query=approver=[approver_sys_id]^state=requested&sysparm_fields=sys_id,sysapproval,sysapproval.number,sysapproval.short_description,sysapproval.sys_class_name,state,approver,group,sys_created_on,due_date,comments&sysparm_limit=25&sysparm_display_value=true
Get group approvals:
Tool: SN-Query-Table
Parameters:
table_name: sysapproval_approver
query: group=[group_sys_id]^state=requested
fields: sys_id,sysapproval.number,sysapproval.short_description,state,group,sys_created_on,due_date
limit: 25
For each approval, pull the full request and item context.
Get the requested item details:
Tool: SN-Query-Table
Parameters:
table_name: sc_req_item
query: request=[request_sys_id]
fields: sys_id,number,cat_item,cat_item.name,cat_item.short_description,cat_item.price,quantity,requested_for,requested_for.name,requested_for.department,requested_for.manager,opened_by,opened_by.name,stage,state,price,description
limit: 10
Using REST API:
GET /api/now/table/sc_req_item?sysparm_query=request=[request_sys_id]&sysparm_fields=sys_id,number,cat_item,cat_item.name,cat_item.short_description,cat_item.price,quantity,requested_for,requested_for.name,requested_for.department,requested_for.manager,opened_by,opened_by.name,stage,state,price,description&sysparm_limit=10&sysparm_display_value=true
Retrieve the specific answers the requester provided on the catalog item form.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sc_item_option_mtom
query: request_item=[ritm_sys_id]
fields: sc_item_option.item_option_new.question_text,sc_item_option.value,sc_item_option.item_option_new.name,sc_item_option.item_option_new.type
limit: 30
Using background script for clean variable extraction:
Tool: SN-Execute-Background-Script
Parameters:
description: Extract catalog variable values for RITM
script: |
var ritmId = '[ritm_sys_id]';
var ritm = new GlideRecord('sc_req_item');
ritm.get(ritmId);
var variables = [];
var opts = new GlideRecord('sc_item_option_mtom');
opts.addQuery('request_item', ritmId);
opts.query();
while (opts.next()) {
var option = opts.sc_item_option;
var varDef = option.item_option_new;
if (varDef) {
variables.push({
question: varDef.question_text.toString(),
answer: option.value.getDisplayValue(),
variable_name: varDef.name.toString(),
mandatory: varDef.mandatory.toString() === 'true'
});
}
}
var result = {
ritm_number: ritm.number.toString(),
item_name: ritm.cat_item.getDisplayValue(),
requested_for: ritm.requested_for.getDisplayValue(),
department: ritm.requested_for.department.getDisplayValue(),
variables: variables
};
gs.info(JSON.stringify(result, null, 2));
Gather relevant information about the person making the request.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sys_user
query: sys_id=[requested_for_sys_id]
fields: sys_id,name,user_name,email,title,department,manager,location,cost_center,company,vip,active
limit: 1
Using REST API:
GET /api/now/table/sys_user/[requested_for_sys_id]?sysparm_fields=sys_id,name,user_name,email,title,department,manager,location,cost_center,company,vip,active&sysparm_display_value=true
Find similar past approvals to provide precedent for the approver's decision.
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Analyze historical approval patterns for similar requests
script: |
var catItemId = '[cat_item_sys_id]';
var departmentId = '[department_sys_id]';
var history = {
same_item_total: 0,
same_item_approved: 0,
same_item_rejected: 0,
same_dept_total: 0,
avg_approval_time_hours: 0,
recent_approvals: []
};
// Same item across all departments (last 6 months)
var ga = new GlideAggregate('sysapproval_approver');
ga.addQuery('sysapproval.sys_class_name', 'sc_req_item');
ga.addQuery('sys_created_on', '>=', gs.monthsAgoStart(6));
ga.addJoinQuery('sc_req_item', 'sysapproval', 'sys_id')
.addCondition('cat_item', catItemId);
ga.addAggregate('COUNT');
ga.addAggregate('COUNT', 'state');
ga.groupBy('state');
ga.query();
while (ga.next()) {
var state = ga.state.toString();
var count = parseInt(ga.getAggregate('COUNT'));
history.same_item_total += count;
if (state === 'approved') history.same_item_approved = count;
if (state === 'rejected') history.same_item_rejected = count;
}
// Recent approvals for same item
var recent = new GlideRecord('sysapproval_approver');
recent.addQuery('sysapproval.sys_class_name', 'sc_req_item');
recent.addQuery('state', 'approved');
recent.addQuery('sys_created_on', '>=', gs.monthsAgoStart(3));
recent.addJoinQuery('sc_req_item', 'sysapproval', 'sys_id')
.addCondition('cat_item', catItemId);
recent.orderByDesc('sys_updated_on');
recent.setLimit(5);
recent.query();
while (recent.next()) {
history.recent_approvals.push({
approved_by: recent.approver.getDisplayValue(),
date: recent.sys_updated_on.getDisplayValue(),
request: recent.sysapproval.getDisplayValue()
});
}
history.approval_rate = history.same_item_total > 0
? Math.round((history.same_item_approved / history.same_item_total) * 100) + '%'
: 'N/A';
gs.info(JSON.stringify(history, null, 2));
Compile all gathered context into a structured summary.
Using MCP:
Tool: SN-Add-Work-Notes
Parameters:
table_name: sysapproval_approver
sys_id: [approval_sys_id]
work_notes: |
=== APPROVAL SUMMARY ===
REQUEST: REQ0045123 / RITM0067890
ITEM: New Laptop Request - Performance Model (Dell Latitude 7640)
PRICE: $1,800.00
REQUESTER:
- Name: John Smith ([email protected])
- Title: Senior Software Engineer
- Department: Engineering
- Manager: Jane Doe
- Location: Building A, Floor 3
- VIP: No
WHAT'S BEING REQUESTED:
- Laptop Model: Performance (Dell Latitude 7640)
- RAM: 32GB
- Storage: 1TB SSD
- Additional Software: Docker Desktop, IntelliJ IDEA
- Business Justification: "Current laptop is 4 years old and unable to run containerized development environments. Build times exceed 30 minutes affecting productivity."
- Replacing Existing: Yes (Asset Tag: LAP-2022-0456)
HISTORICAL CONTEXT:
- Same item ordered 47 times in last 6 months
- Approval rate: 94% (44 approved, 3 rejected)
- Engineering department: 18 orders (all approved)
- Recent approvals: 3 in last 30 days by IT Director
RISK ASSESSMENT:
- Cost: Within standard budget threshold ($2,500)
- Justification: Strong (productivity impact documented)
- Precedent: Consistent with approval history
- Compliance: Asset replacement documented
RECOMMENDATION SIGNAL: Approve
Generate digest summaries for approvers with multiple pending items.
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Generate approval digest for approver
script: |
var approverId = '[approver_sys_id]';
var digest = { approver: '', pending_count: 0, total_value: 0, approvals: [] };
var approver = new GlideRecord('sys_user');
approver.get(approverId);
digest.approver = approver.name.toString();
var ga = new GlideRecord('sysapproval_approver');
ga.addQuery('approver', approverId);
ga.addQuery('state', 'requested');
ga.orderBy('sys_created_on');
ga.query();
while (ga.next()) {
digest.pending_count++;
var ritm = new GlideRecord('sc_req_item');
if (ritm.get(ga.sysapproval.toString())) {
var price = parseFloat(ritm.price) || 0;
digest.total_value += price;
digest.approvals.push({
approval_id: ga.sys_id.toString(),
request_number: ritm.request.getDisplayValue(),
ritm_number: ritm.number.toString(),
item: ritm.cat_item.getDisplayValue(),
requested_for: ritm.requested_for.getDisplayValue(),
department: ritm.requested_for.department.getDisplayValue(),
price: price,
waiting_since: ga.sys_created_on.getDisplayValue()
});
}
}
digest.total_value = '$' + digest.total_value.toFixed(2);
gs.info(JSON.stringify(digest, null, 2));
| Tool | When to Use |
|------|-------------|
| SN-Query-Table | Query approvals, requests, items, variables, and user profiles |
| SN-Get-Record | Retrieve individual approval or request records |
| SN-NL-Search | Find requests or items by description keywords |
| SN-Execute-Background-Script | Batch analysis, historical patterns, digest generation |
| SN-Add-Work-Notes | Post approval summaries to approval or request records |
| Endpoint | Method | Purpose |
|----------|--------|---------|
| /api/now/table/sysapproval_approver | GET | Query pending approvals |
| /api/now/table/sc_request | GET | Retrieve parent request details |
| /api/now/table/sc_req_item | GET | Get requested item details and variables |
| /api/now/table/sc_cat_item | GET | Look up catalog item definitions |
| /api/now/table/sc_item_option_mtom | GET | Extract variable values from requests |
| /api/now/table/sys_user | GET | Get requester profile information |
Cause: The sc_item_option_mtom join is not returning expected variable values
Solution: Some items use sc_item_option directly. Try querying sc_item_option with request_item=[ritm_sys_id] instead. For older requests, variables may be stored differently.
Cause: The sysapproval field on the approval record may reference a request (REQ) rather than a requested item (RITM)
Solution: Check sysapproval.sys_class_name to determine whether the approval is linked to sc_request or sc_req_item, and adjust your joins accordingly.
Cause: Old approval records may have been archived or purged
Solution: Adjust the date range in historical queries. Check if the instance uses table rotation or archiving on sysapproval_approver.
Cause: The department field on the user record is empty
Solution: Fall back to company or cost_center for organizational context. Check if the user's manager chain can provide department information.
Input: "Summarize approval SYSAPPR0012345"
Output: A structured summary including request details, requester profile, variable values, historical approval rate for the same item, and a recommendation signal based on precedent and policy compliance.
Input: "Generate an approval digest for manager Jane Doe"
Output:
APPROVAL DIGEST - Jane Doe
Date: 2026-03-19
Pending Approvals: 4
Total Value: $7,450.00
1. REQ0045123 / RITM0067890 - New Laptop ($1,800) - John Smith, Engineering - 2 days pending
2. REQ0045130 / RITM0067897 - Software License x5 ($2,500) - Lisa Park, Marketing - 1 day pending
3. REQ0045135 / RITM0067902 - Conference Travel ($2,400) - Mike Johnson, Sales - 4 hours pending
4. REQ0045138 / RITM0067905 - Desk Phone ($750) - Sarah Kim, HR - 1 hour pending
Tool: SN-Get-Record
Parameters:
table_name: sysapproval_approver
sys_id: [approval_sys_id]
# Result analysis flags:
# - Cost exceeds $5,000 threshold (requires VP approval)
# - First time this item has been ordered by this department
# - Requester is a contractor (non-FTE)
# - No business justification provided (mandatory field bypass)
catalog/approval-workflows - Configure approval routing rulescatalog/request-fulfillment - Post-approval fulfillment processingcatalog/item-creation - Catalog item setup and configurationcatalog/catalog-item-generation - Generate items from descriptionsadmin/workflow-creation - Build approval workflow logictesting
Manage supplier onboarding, qualification, performance monitoring, and offboarding with auditable lifecycle controls
tools
Identify emerging risks, prioritize intake signals, and route candidates into formal GRC risk assessment workflows
documentation
Screen inbound documents for completeness, policy risk, and routing readiness before extraction or case workflows
testing
Generate concise task summaries with status, timeline, blockers, SLA risk, and recommended next actions