skills/reporting/analytics-generation/SKILL.md
Generate analytics dashboards and visualizations from natural language descriptions covering PA indicators, data collectors, and widgets
npx skillsauth add happy-technologies-llc/happy-servicenow-skills analytics-generationInstall 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 covers generating analytics dashboards, Performance Analytics (PA) indicators, data collectors, widgets, and standard reports from natural language descriptions:
When to use: When stakeholders request new dashboards, KPI tracking, trend analysis, or when translating business reporting requirements into ServiceNow analytics configuration.
pa_admin, report_admin, or adminreporting/query-generation for advanced query constructionpa_dashboards (Dashboard)
├── pa_tabs (Dashboard Tabs)
│ └── pa_widgets (Widget Instances)
│ └── pa_widget_indicators (Widget-Indicator Links)
├── pa_indicators (Indicators/KPIs)
│ ├── pa_indicator_source (Indicator Sources)
│ └── pa_data_collectors (Data Collectors)
│ └── pa_job_logs (Collection Logs)
└── sys_report (Standard Reports)
Key Tables: | Table | Purpose | |-------|---------| | pa_dashboards | Dashboard container definitions | | pa_widgets | Widget instances placed on dashboards | | pa_indicators | KPI/metric definitions with formulas | | pa_data_collectors | Scheduled jobs that collect indicator data | | sys_report | Standard ServiceNow reports (charts, lists, pivot tables) |
Indicators define WHAT to measure.
Create a count-based indicator:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_indicators
data:
name: "Open Critical Incidents"
description: "Count of open incidents with priority 1 (Critical)"
type: 1
aggregate: "COUNT"
table: "incident"
conditions: "active=true^priority=1"
frequency: "daily"
direction: "minimize"
unit: "incidents"
precision: 0
active: true
REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/pa_indicators" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"name": "Open Critical Incidents",
"description": "Count of open incidents with priority 1",
"type": 1,
"aggregate": "COUNT",
"table": "incident",
"conditions": "active=true^priority=1",
"frequency": "daily",
"active": true
}'
Create an average-based indicator:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_indicators
data:
name: "Average Incident Resolution Time"
description: "Average time in hours from opening to resolution"
type: 1
aggregate: "AVG"
table: "incident"
field: "business_duration"
conditions: "state=6^resolved_atISNOTEMPTY"
frequency: "daily"
direction: "minimize"
unit: "hours"
precision: 1
active: true
Create a percentage indicator:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_indicators
data:
name: "SLA Compliance Rate"
description: "Percentage of incidents resolved within SLA"
type: 2
aggregate: "COUNT"
table: "incident"
conditions: "state=6"
numerator_conditions: "state=6^made_sla=true"
frequency: "daily"
direction: "maximize"
unit: "%"
precision: 1
active: true
Data collectors define WHEN and HOW to gather indicator data.
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_data_collectors
data:
indicator: [indicator_sys_id]
name: "Daily Open Critical Incidents Collector"
active: true
run_as: "system"
collection_frequency: "daily"
is_scheduled: true
REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/pa_data_collectors" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"indicator": "[indicator_sys_id]",
"name": "Daily Open Critical Incidents Collector",
"active": true,
"collection_frequency": "daily",
"is_scheduled": true
}'
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_dashboards
data:
name: "IT Service Management Overview"
description: "Executive dashboard for ITSM key performance indicators"
active: true
published: true
owner: [user_sys_id]
REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/pa_dashboards" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"name": "IT Service Management Overview",
"description": "Executive dashboard for ITSM KPIs",
"active": true,
"published": true
}'
PA Indicator Widget Types: | Type | Value | Use Case | |------|-------|----------| | Scorecard | scorecard | Single KPI with trend | | Time Series | time_series | Metric over time (line chart) | | Breakdown | breakdown | Metric split by dimension | | Dial | dial | Gauge-style single metric | | Single Score | single_score | Large number display | | List | list | Tabular data | | Pivot Table | pivot | Cross-tabulation |
Create a scorecard widget:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_widgets
data:
dashboard: [dashboard_sys_id]
indicator: [indicator_sys_id]
visualization: "scorecard"
name: "Critical Incidents Scorecard"
row: 0
column: 0
width: 6
height: 4
active: true
Create a time series widget:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_widgets
data:
dashboard: [dashboard_sys_id]
indicator: [indicator_sys_id]
visualization: "time_series"
name: "Incident Volume Trend"
row: 0
column: 6
width: 6
height: 4
active: true
time_series_period: "last_12_months"
Create a breakdown widget:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: pa_widgets
data:
dashboard: [dashboard_sys_id]
indicator: [indicator_sys_id]
visualization: "breakdown"
name: "Incidents by Priority"
breakdown: [breakdown_sys_id]
row: 4
column: 0
width: 6
height: 4
active: true
chart_type: "bar"
For simpler reporting needs without PA overhead, use sys_report.
Create a bar chart report:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: sys_report
data:
title: "Incidents by Category"
table: "incident"
type: "bar"
field: "category"
filter: "active=true"
aggregate: "COUNT"
group: "category"
is_published: true
active: true
chart_size: "large"
REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/sys_report" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"title": "Incidents by Category",
"table": "incident",
"type": "bar",
"field": "category",
"filter": "active=true",
"aggregate": "COUNT",
"is_published": true
}'
Create a trend report:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: sys_report
data:
title: "Weekly Incident Volume"
table: "incident"
type: "line"
field: "sys_created_on"
filter: "sys_created_on>=javascript:gs.daysAgo(90)"
aggregate: "COUNT"
trend_field: "sys_created_on"
interval: "week"
is_published: true
active: true
Create a pivot table report:
MCP Approach:
Tool: SN-Create-Record
Parameters:
table_name: sys_report
data:
title: "Incidents: Priority vs State"
table: "incident"
type: "pivot"
field: "priority"
stack: "state"
filter: "sys_created_on>=javascript:gs.daysAgo(30)"
aggregate: "COUNT"
is_published: true
active: true
Breakdowns define dimensions for slicing indicator data.
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: pa_breakdowns
query: table=incident^active=true
fields: sys_id,name,field,table
limit: 50
If a needed breakdown does not exist:
Tool: SN-Create-Record
Parameters:
table_name: pa_breakdowns
data:
name: "Incident Priority Breakdown"
table: "incident"
field: "priority"
active: true
Verify indicator configuration:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: pa_indicators
query: sys_id=[indicator_sys_id]
fields: sys_id,name,aggregate,table,conditions,frequency,active
Verify dashboard widgets:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: pa_widgets
query: dashboard=[dashboard_sys_id]
fields: sys_id,name,visualization,indicator,row,column,width,height,active
limit: 50
Check data collector status:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: pa_data_collectors
query: indicator=[indicator_sys_id]
fields: sys_id,name,active,is_scheduled,last_collection_time
| Action | MCP Tool | REST Endpoint | |--------|----------|---------------| | Create indicator | SN-Create-Record | POST /api/now/table/pa_indicators | | Create data collector | SN-Create-Record | POST /api/now/table/pa_data_collectors | | Create dashboard | SN-Create-Record | POST /api/now/table/pa_dashboards | | Add widget | SN-Create-Record | POST /api/now/table/pa_widgets | | Create report | SN-Create-Record | POST /api/now/table/sys_report | | Query indicators | SN-Query-Table | GET /api/now/table/pa_indicators | | Query dashboards | SN-Query-Table | GET /api/now/table/pa_dashboards | | Update widget | SN-Update-Record | PATCH /api/now/table/pa_widgets/{sys_id} |
Symptom: Indicator exists but displays zero or no data Causes:
Tool: SN-Query-Table
Parameters:
table_name: pa_data_collectors
query: indicator=[indicator_sys_id]
fields: sys_id,name,active,is_scheduled,last_collection_time
Then verify the condition query returns data:
Tool: SN-Query-Table
Parameters:
table_name: incident
query: active=true^priority=1
fields: sys_id
limit: 1
Symptom: Dashboard created but not appearing in navigation Causes:
Tool: SN-Update-Record
Parameters:
table_name: pa_dashboards
sys_id: [dashboard_sys_id]
data:
published: true
active: true
Symptom: Report shows all records instead of filtered set Cause: Filter encoded query syntax incorrect Solution: Validate the encoded query:
Tool: SN-Query-Table
Parameters:
table_name: incident
query: [your_filter_query]
fields: sys_id
limit: 5
If results are unexpected, adjust the query.
Symptom: Widgets overlap or display incorrectly Cause: Row/column/width/height values conflict Solution: Review all widget positions:
Tool: SN-Query-Table
Parameters:
table_name: pa_widgets
query: dashboard=[dashboard_sys_id]
fields: name,row,column,width,height
limit: 20
# 1. Create indicators
Tool: SN-Create-Record
Parameters:
table_name: pa_indicators
data:
name: "Open Incidents"
aggregate: "COUNT"
table: "incident"
conditions: "active=true"
frequency: "daily"
active: true
# Result: indicator1_sys_id
Tool: SN-Create-Record
Parameters:
table_name: pa_indicators
data:
name: "MTTR (Hours)"
aggregate: "AVG"
table: "incident"
field: "business_duration"
conditions: "state=6^sys_created_on>=javascript:gs.daysAgo(30)"
frequency: "daily"
active: true
# Result: indicator2_sys_id
# 2. Create data collectors for each indicator
Tool: SN-Create-Record
Parameters:
table_name: pa_data_collectors
data:
indicator: indicator1_sys_id
name: "Open Incidents Daily"
active: true
is_scheduled: true
# 3. Create dashboard
Tool: SN-Create-Record
Parameters:
table_name: pa_dashboards
data:
name: "ITSM Executive Dashboard"
published: true
active: true
# Result: dashboard_sys_id
# 4. Add widgets
Tool: SN-Create-Record
Parameters:
table_name: pa_widgets
data:
dashboard: dashboard_sys_id
indicator: indicator1_sys_id
visualization: "single_score"
name: "Open Incidents"
row: 0
column: 0
width: 3
height: 3
Tool: SN-Create-Record
Parameters:
table_name: pa_widgets
data:
dashboard: dashboard_sys_id
indicator: indicator2_sys_id
visualization: "time_series"
name: "MTTR Trend"
row: 0
column: 3
width: 9
height: 6
Tool: SN-Create-Record
Parameters:
table_name: sys_report
data:
title: "Top 10 Incident Categories This Month"
table: "incident"
type: "bar"
field: "category"
filter: "sys_created_on>=javascript:gs.beginningOfThisMonth()"
aggregate: "COUNT"
orderby: "COUNT"
order_direction: "desc"
row_count: 10
is_published: true
reporting/query-generation - Generate complex queries for reportsitsm/incident-management - Incident data model contextadmin/scheduled-jobs - Configure scheduled data collectionea/business-app-insights - Application-level analyticstesting
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