@tedorigawa001/servicenow-mcp 1.4.0 → 1.5.1
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/README.md +10 -10
- package/dist/tools/grc-audit.d.ts +157 -0
- package/dist/tools/grc-audit.d.ts.map +1 -0
- package/dist/tools/grc-audit.js +232 -0
- package/dist/tools/grc-audit.js.map +1 -0
- package/dist/tools/grc-compliance.d.ts +800 -0
- package/dist/tools/grc-compliance.d.ts.map +1 -0
- package/dist/tools/grc-compliance.js +679 -0
- package/dist/tools/grc-compliance.js.map +1 -0
- package/dist/tools/grc-indicator.d.ts +290 -0
- package/dist/tools/grc-indicator.d.ts.map +1 -0
- package/dist/tools/grc-indicator.js +228 -0
- package/dist/tools/grc-indicator.js.map +1 -0
- package/dist/tools/grc-risk.d.ts +285 -0
- package/dist/tools/grc-risk.d.ts.map +1 -0
- package/dist/tools/grc-risk.js +256 -0
- package/dist/tools/grc-risk.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +30 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/security.d.ts +5 -366
- package/dist/tools/security.d.ts.map +1 -1
- package/dist/tools/security.js +5 -148
- package/dist/tools/security.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<br/>
|
|
13
13
|
|
|
14
14
|
[](https://github.com/tedorigawa001/ServiceNow-MCP)
|
|
15
|
-
[](docs/TOOLS.md)
|
|
16
16
|
[](https://www.npmjs.com/package/@tedorigawa001/servicenow-mcp)
|
|
17
17
|
[](https://www.typescriptlang.org/)
|
|
18
18
|
[](LICENSE)
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
## AI から ServiceNow を自然言語で操作する MCP サーバー
|
|
25
25
|
|
|
26
|
-
> **ローカル PC で動作 ·
|
|
26
|
+
> **ローカル PC で動作 · 450+ ツール · 5 分セットアップ · MIT ライセンス**
|
|
27
27
|
|
|
28
28
|
Claude・Cursor・VS Code などの AI ツールから、ServiceNow のインシデント・変更・CMDB・スクリプトなどをすべて自然言語で操作できます。
|
|
29
29
|
|
|
30
|
-
### v1.
|
|
30
|
+
### v1.4.0 ハイライト
|
|
31
31
|
|
|
32
|
-
- USEM
|
|
33
|
-
-
|
|
34
|
-
- `
|
|
32
|
+
- 書き込みフィールド許可リストを残りのツール群(user/group・USEM/VRルール・agile・task・scripting・app-studio・portal・reporting・VA topic)に拡張し、mass assignment の穴を解消
|
|
33
|
+
- 許可リストは実行時チェックに加え JSON Schema 側でも `additionalProperties: false` により二重防御
|
|
34
|
+
- USEM のクエリフィルタ値に `sanitizeLikeValue` を適用(生の `query` パラメータは既存の意図通り非サニタイズのまま)
|
|
35
35
|
|
|
36
36
|
</div>
|
|
37
37
|
|
|
@@ -566,7 +566,7 @@ SCRIPTING_ENABLED=false # 本番では原則 false のまま
|
|
|
566
566
|
mindmap
|
|
567
567
|
root((ツールパッケージ))
|
|
568
568
|
full
|
|
569
|
-
全
|
|
569
|
+
全450+ツール
|
|
570
570
|
service_desk
|
|
571
571
|
インシデント管理
|
|
572
572
|
タスク/承認
|
|
@@ -601,7 +601,7 @@ mindmap
|
|
|
601
601
|
|
|
602
602
|
| パッケージ名 | 対象ロール | 主なツール |
|
|
603
603
|
|------------|----------|-----------|
|
|
604
|
-
| `full` | 管理者 | 全ツール (
|
|
604
|
+
| `full` | 管理者 | 全ツール (450+) |
|
|
605
605
|
| `service_desk` | L1/L2 エージェント | インシデント・タスク・KB・SLA |
|
|
606
606
|
| `change_coordinator` | 変更管理者 | 変更リクエスト・CAB・CMDB |
|
|
607
607
|
| `knowledge_author` | KB 著者 | KB 作成・公開 |
|
|
@@ -777,7 +777,7 @@ servicenow-mcp/
|
|
|
777
777
|
│ │ ├── client.ts # REST API クライアント (OAuth)
|
|
778
778
|
│ │ ├── instances.ts # マルチインスタンスマネージャー
|
|
779
779
|
│ │ └── types.ts # TypeScript 型定義
|
|
780
|
-
│ ├── tools/ #
|
|
780
|
+
│ ├── tools/ # 44 ドメインモジュール (450+ ツール)
|
|
781
781
|
│ │ ├── index.ts # ツールルーター & パッケージ定義
|
|
782
782
|
│ │ ├── incident.ts
|
|
783
783
|
│ │ ├── change.ts
|
|
@@ -867,7 +867,7 @@ Model Context Protocol の略で、AI クライアントが外部ツールを呼
|
|
|
867
867
|
|
|
868
868
|
<div align="center">
|
|
869
869
|
|
|
870
|
-
**
|
|
870
|
+
**450+ ツール · 44 モジュール · ローカル PC で動作 · 永久オープンソース**
|
|
871
871
|
|
|
872
872
|
役に立ったら ⭐ スターをお願いします — 他の人が見つけやすくなります。
|
|
873
873
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GRC — Audit Management tools. Covers Engagements (audit projects) and
|
|
3
|
+
* Control Tests (the actual "audit result" record — `sn_audit_result` does
|
|
4
|
+
* not exist; see docs/GRC_DESIGN.md).
|
|
5
|
+
*
|
|
6
|
+
* Read tools: Tier 0. Write tools: Tier 1 (WRITE_ENABLED=true).
|
|
7
|
+
*
|
|
8
|
+
* Tables verified against a live PDI (dev400464, 2026-07-12):
|
|
9
|
+
* - sn_audit_engagement (Engagement) — number prefix ENG, extends planned_task
|
|
10
|
+
* - sn_audit_control_test (Control Test) — number prefix CTR, subclass of sn_audit_task
|
|
11
|
+
* sn_audit_task itself has 0 direct records — always query the subclass
|
|
12
|
+
* (sn_audit_control_test / sn_audit_activity / sn_audit_interview /
|
|
13
|
+
* sn_audit_walkthrough), never sn_audit_task alone.
|
|
14
|
+
*/
|
|
15
|
+
import type { ServiceNowClient } from '../servicenow/client.js';
|
|
16
|
+
export declare function getGrcAuditToolDefinitions(): ({
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: string;
|
|
21
|
+
properties: {
|
|
22
|
+
state: {
|
|
23
|
+
type: string;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
engagement_type: {
|
|
27
|
+
type: string;
|
|
28
|
+
description: string;
|
|
29
|
+
};
|
|
30
|
+
query: {
|
|
31
|
+
type: string;
|
|
32
|
+
description: string;
|
|
33
|
+
};
|
|
34
|
+
limit: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
display_value: {
|
|
39
|
+
description: string;
|
|
40
|
+
oneOf: ({
|
|
41
|
+
type: string;
|
|
42
|
+
enum?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
type: string;
|
|
45
|
+
enum: string[];
|
|
46
|
+
})[];
|
|
47
|
+
};
|
|
48
|
+
number_or_sysid?: undefined;
|
|
49
|
+
control?: undefined;
|
|
50
|
+
test_plan?: undefined;
|
|
51
|
+
design_effectiveness?: undefined;
|
|
52
|
+
operation_effectiveness?: undefined;
|
|
53
|
+
top?: undefined;
|
|
54
|
+
};
|
|
55
|
+
required?: undefined;
|
|
56
|
+
};
|
|
57
|
+
} | {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
inputSchema: {
|
|
61
|
+
type: string;
|
|
62
|
+
properties: {
|
|
63
|
+
number_or_sysid: {
|
|
64
|
+
type: string;
|
|
65
|
+
description: string;
|
|
66
|
+
};
|
|
67
|
+
state?: undefined;
|
|
68
|
+
engagement_type?: undefined;
|
|
69
|
+
query?: undefined;
|
|
70
|
+
limit?: undefined;
|
|
71
|
+
display_value?: undefined;
|
|
72
|
+
control?: undefined;
|
|
73
|
+
test_plan?: undefined;
|
|
74
|
+
design_effectiveness?: undefined;
|
|
75
|
+
operation_effectiveness?: undefined;
|
|
76
|
+
top?: undefined;
|
|
77
|
+
};
|
|
78
|
+
required: string[];
|
|
79
|
+
};
|
|
80
|
+
} | {
|
|
81
|
+
name: string;
|
|
82
|
+
description: string;
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: string;
|
|
85
|
+
properties: {
|
|
86
|
+
state: {
|
|
87
|
+
type: string;
|
|
88
|
+
description: string;
|
|
89
|
+
};
|
|
90
|
+
control: {
|
|
91
|
+
type: string;
|
|
92
|
+
description: string;
|
|
93
|
+
};
|
|
94
|
+
test_plan: {
|
|
95
|
+
type: string;
|
|
96
|
+
description: string;
|
|
97
|
+
};
|
|
98
|
+
design_effectiveness: {
|
|
99
|
+
type: string;
|
|
100
|
+
enum: string[];
|
|
101
|
+
description: string;
|
|
102
|
+
};
|
|
103
|
+
operation_effectiveness: {
|
|
104
|
+
type: string;
|
|
105
|
+
enum: string[];
|
|
106
|
+
description: string;
|
|
107
|
+
};
|
|
108
|
+
query: {
|
|
109
|
+
type: string;
|
|
110
|
+
description: string;
|
|
111
|
+
};
|
|
112
|
+
limit: {
|
|
113
|
+
type: string;
|
|
114
|
+
description: string;
|
|
115
|
+
};
|
|
116
|
+
display_value: {
|
|
117
|
+
description: string;
|
|
118
|
+
oneOf: ({
|
|
119
|
+
type: string;
|
|
120
|
+
enum?: undefined;
|
|
121
|
+
} | {
|
|
122
|
+
type: string;
|
|
123
|
+
enum: string[];
|
|
124
|
+
})[];
|
|
125
|
+
};
|
|
126
|
+
engagement_type?: undefined;
|
|
127
|
+
number_or_sysid?: undefined;
|
|
128
|
+
top?: undefined;
|
|
129
|
+
};
|
|
130
|
+
required?: undefined;
|
|
131
|
+
};
|
|
132
|
+
} | {
|
|
133
|
+
name: string;
|
|
134
|
+
description: string;
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: string;
|
|
137
|
+
properties: {
|
|
138
|
+
top: {
|
|
139
|
+
type: string;
|
|
140
|
+
description: string;
|
|
141
|
+
};
|
|
142
|
+
state?: undefined;
|
|
143
|
+
engagement_type?: undefined;
|
|
144
|
+
query?: undefined;
|
|
145
|
+
limit?: undefined;
|
|
146
|
+
display_value?: undefined;
|
|
147
|
+
number_or_sysid?: undefined;
|
|
148
|
+
control?: undefined;
|
|
149
|
+
test_plan?: undefined;
|
|
150
|
+
design_effectiveness?: undefined;
|
|
151
|
+
operation_effectiveness?: undefined;
|
|
152
|
+
};
|
|
153
|
+
required?: undefined;
|
|
154
|
+
};
|
|
155
|
+
})[];
|
|
156
|
+
export declare function executeGrcAuditToolCall(client: ServiceNowClient, name: string, args: Record<string, any>): Promise<any>;
|
|
157
|
+
//# sourceMappingURL=grc-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grc-audit.d.ts","sourceRoot":"","sources":["../../src/tools/grc-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAuDhE,wBAAgB,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+EzC;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,OAAO,CAAC,GAAG,CAAC,CAwGd"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { sanitizeLikeValue } from '../servicenow/client.js';
|
|
2
|
+
import { ServiceNowError } from '../utils/errors.js';
|
|
3
|
+
const SYS_ID_RE = /^[0-9a-f]{32}$/i;
|
|
4
|
+
const queryValue = (value) => sanitizeLikeValue(String(value));
|
|
5
|
+
const ENGAGEMENT_STATE_LABELS = {
|
|
6
|
+
'-5': 'Scope',
|
|
7
|
+
'1': 'Validate',
|
|
8
|
+
'2': 'Fieldwork',
|
|
9
|
+
'3': 'Closed Complete',
|
|
10
|
+
'4': 'Closed Incomplete',
|
|
11
|
+
'5': 'Follow Up',
|
|
12
|
+
'6': 'Awaiting Approval',
|
|
13
|
+
};
|
|
14
|
+
const ENGAGEMENT_STATE_SCHEMA = {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'State filter. Single value or comma-separated list. -5=Scope, 1=Validate, 2=Fieldwork, ' +
|
|
17
|
+
'3=Closed Complete, 4=Closed Incomplete, 5=Follow Up, 6=Awaiting Approval',
|
|
18
|
+
};
|
|
19
|
+
const ENGAGEMENT_FIELDS = 'number,name,short_description,state,engagement_type,audit_period_start,audit_period_end,' +
|
|
20
|
+
'auditors,approvers,opinion,result,task_percent_complete,high_priority_issues,sys_id';
|
|
21
|
+
const CONTROL_TEST_FIELDS = 'number,short_description,state,control,test_plan,issue,design_effectiveness,' +
|
|
22
|
+
'operation_effectiveness,opinion,performed_on,sys_id';
|
|
23
|
+
/** Build a `state=` / `stateIN` clause from a single value or comma list. */
|
|
24
|
+
function stateClause(state) {
|
|
25
|
+
if (state === undefined || state === null || state === '')
|
|
26
|
+
return undefined;
|
|
27
|
+
const values = String(state)
|
|
28
|
+
.split(',')
|
|
29
|
+
.map(s => s.trim())
|
|
30
|
+
.filter(Boolean);
|
|
31
|
+
if (values.length === 0)
|
|
32
|
+
return undefined;
|
|
33
|
+
return values.length === 1 ? `state=${queryValue(values[0])}` : `stateIN${values.map(queryValue).join(',')}`;
|
|
34
|
+
}
|
|
35
|
+
/** Normalize the stats API result into [{ state, label, count }]. */
|
|
36
|
+
function summarizeByState(stats, labels) {
|
|
37
|
+
const rows = Array.isArray(stats) ? stats : [];
|
|
38
|
+
return rows
|
|
39
|
+
.map(row => {
|
|
40
|
+
const value = String(row?.groupby_fields?.[0]?.value ?? '');
|
|
41
|
+
const count = parseInt(String(row?.stats?.count ?? '0'), 10);
|
|
42
|
+
return { state: value, label: labels[value] ?? value, count: Number.isFinite(count) ? count : 0 };
|
|
43
|
+
})
|
|
44
|
+
.sort((a, b) => b.count - a.count);
|
|
45
|
+
}
|
|
46
|
+
export function getGrcAuditToolDefinitions() {
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
name: 'list_audit_engagements',
|
|
50
|
+
description: 'List Audit Engagements (sn_audit_engagement) — the top-level audit project record. ' +
|
|
51
|
+
'Filter by state or engagement type. Ordered by most recently updated.',
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
state: ENGAGEMENT_STATE_SCHEMA,
|
|
56
|
+
engagement_type: { type: 'string', description: 'Engagement type choice value, e.g. "4" (IT Audit), "6" (Compliance Audit), "11" (Vendor Audit)' },
|
|
57
|
+
query: { type: 'string', description: 'Additional raw encoded query appended with ^' },
|
|
58
|
+
limit: { type: 'number', description: 'Max records (default: 25, max: 1000)' },
|
|
59
|
+
display_value: {
|
|
60
|
+
description: 'Return human-readable reference/choice values (true) or both raw and display ("all")',
|
|
61
|
+
oneOf: [{ type: 'boolean' }, { type: 'string', enum: ['all'] }],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'get_audit_engagement',
|
|
68
|
+
description: 'Get full details of a single Audit Engagement by sys_id or number (e.g. "ENG0000104").',
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {
|
|
72
|
+
number_or_sysid: { type: 'string', description: 'Engagement number (ENGxxxxxxx) or 32-char sys_id' },
|
|
73
|
+
},
|
|
74
|
+
required: ['number_or_sysid'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'list_audit_control_tests',
|
|
79
|
+
description: 'List Control Tests (sn_audit_control_test) — the record of testing a Control within an audit ' +
|
|
80
|
+
'engagement; this is the real "audit result" (there is no sn_audit_result table). Filter by ' +
|
|
81
|
+
'control, test plan, or design/operation effectiveness.',
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
state: ENGAGEMENT_STATE_SCHEMA,
|
|
86
|
+
control: { type: 'string', description: 'Filter by related Control sys_id' },
|
|
87
|
+
test_plan: { type: 'string', description: 'Filter by related Test Plan sys_id' },
|
|
88
|
+
design_effectiveness: { type: 'string', enum: ['none', 'effective', 'ineffective'], description: 'Filter by design effectiveness result' },
|
|
89
|
+
operation_effectiveness: { type: 'string', enum: ['none', 'effective', 'ineffective'], description: 'Filter by operating effectiveness result' },
|
|
90
|
+
query: { type: 'string', description: 'Additional raw encoded query appended with ^' },
|
|
91
|
+
limit: { type: 'number', description: 'Max records (default: 25, max: 1000)' },
|
|
92
|
+
display_value: {
|
|
93
|
+
description: 'Return human-readable reference/choice values (true) or both raw and display ("all")',
|
|
94
|
+
oneOf: [{ type: 'boolean' }, { type: 'string', enum: ['all'] }],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'get_audit_control_test',
|
|
101
|
+
description: 'Get full details of a single Control Test by sys_id or number (e.g. "CTR0000153").',
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
number_or_sysid: { type: 'string', description: 'Control Test number (CTRxxxxxxx) or 32-char sys_id' },
|
|
106
|
+
},
|
|
107
|
+
required: ['number_or_sysid'],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'get_grc_audit_dashboard',
|
|
112
|
+
description: 'Summarize the Audit Management posture: Engagement counts by state, Control Test counts by ' +
|
|
113
|
+
'design/operation effectiveness, and the highest-priority-issue open engagements.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
top: { type: 'number', description: 'How many top open engagements to include (default: 5, max: 50)' },
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
export async function executeGrcAuditToolCall(client, name, args) {
|
|
124
|
+
switch (name) {
|
|
125
|
+
case 'list_audit_engagements': {
|
|
126
|
+
const parts = [];
|
|
127
|
+
const sc = stateClause(args.state);
|
|
128
|
+
if (sc)
|
|
129
|
+
parts.push(sc);
|
|
130
|
+
if (args.engagement_type)
|
|
131
|
+
parts.push(`engagement_type=${queryValue(args.engagement_type)}`);
|
|
132
|
+
if (args.query)
|
|
133
|
+
parts.push(args.query);
|
|
134
|
+
const resp = await client.queryRecords({
|
|
135
|
+
table: 'sn_audit_engagement',
|
|
136
|
+
query: parts.join('^'),
|
|
137
|
+
fields: ENGAGEMENT_FIELDS,
|
|
138
|
+
orderBy: '-sys_updated_on',
|
|
139
|
+
limit: args.limit ?? 25,
|
|
140
|
+
display_value: args.display_value,
|
|
141
|
+
});
|
|
142
|
+
return { count: resp.count, records: resp.records, summary: `Found ${resp.count} audit engagement(s)` };
|
|
143
|
+
}
|
|
144
|
+
case 'get_audit_engagement': {
|
|
145
|
+
if (!args.number_or_sysid)
|
|
146
|
+
throw new ServiceNowError('number_or_sysid is required', 'INVALID_REQUEST');
|
|
147
|
+
if (SYS_ID_RE.test(args.number_or_sysid)) {
|
|
148
|
+
return await client.getRecord('sn_audit_engagement', args.number_or_sysid);
|
|
149
|
+
}
|
|
150
|
+
const resp = await client.queryRecords({
|
|
151
|
+
table: 'sn_audit_engagement',
|
|
152
|
+
query: `number=${queryValue(args.number_or_sysid)}`,
|
|
153
|
+
limit: 1,
|
|
154
|
+
});
|
|
155
|
+
if (resp.count === 0)
|
|
156
|
+
throw new ServiceNowError(`Audit Engagement not found: ${args.number_or_sysid}`, 'NOT_FOUND');
|
|
157
|
+
return resp.records[0];
|
|
158
|
+
}
|
|
159
|
+
case 'list_audit_control_tests': {
|
|
160
|
+
const parts = [];
|
|
161
|
+
const sc = stateClause(args.state);
|
|
162
|
+
if (sc)
|
|
163
|
+
parts.push(sc);
|
|
164
|
+
if (args.control)
|
|
165
|
+
parts.push(`control=${queryValue(args.control)}`);
|
|
166
|
+
if (args.test_plan)
|
|
167
|
+
parts.push(`test_plan=${queryValue(args.test_plan)}`);
|
|
168
|
+
if (args.design_effectiveness)
|
|
169
|
+
parts.push(`design_effectiveness=${queryValue(args.design_effectiveness)}`);
|
|
170
|
+
if (args.operation_effectiveness)
|
|
171
|
+
parts.push(`operation_effectiveness=${queryValue(args.operation_effectiveness)}`);
|
|
172
|
+
if (args.query)
|
|
173
|
+
parts.push(args.query);
|
|
174
|
+
const resp = await client.queryRecords({
|
|
175
|
+
table: 'sn_audit_control_test',
|
|
176
|
+
query: parts.join('^'),
|
|
177
|
+
fields: CONTROL_TEST_FIELDS,
|
|
178
|
+
orderBy: '-sys_updated_on',
|
|
179
|
+
limit: args.limit ?? 25,
|
|
180
|
+
display_value: args.display_value,
|
|
181
|
+
});
|
|
182
|
+
return { count: resp.count, records: resp.records, summary: `Found ${resp.count} control test(s)` };
|
|
183
|
+
}
|
|
184
|
+
case 'get_audit_control_test': {
|
|
185
|
+
if (!args.number_or_sysid)
|
|
186
|
+
throw new ServiceNowError('number_or_sysid is required', 'INVALID_REQUEST');
|
|
187
|
+
if (SYS_ID_RE.test(args.number_or_sysid)) {
|
|
188
|
+
return await client.getRecord('sn_audit_control_test', args.number_or_sysid);
|
|
189
|
+
}
|
|
190
|
+
const resp = await client.queryRecords({
|
|
191
|
+
table: 'sn_audit_control_test',
|
|
192
|
+
query: `number=${queryValue(args.number_or_sysid)}`,
|
|
193
|
+
limit: 1,
|
|
194
|
+
});
|
|
195
|
+
if (resp.count === 0)
|
|
196
|
+
throw new ServiceNowError(`Control Test not found: ${args.number_or_sysid}`, 'NOT_FOUND');
|
|
197
|
+
return resp.records[0];
|
|
198
|
+
}
|
|
199
|
+
case 'get_grc_audit_dashboard': {
|
|
200
|
+
const top = Math.min(Math.max(Math.trunc(Number(args.top) || 5), 1), 50);
|
|
201
|
+
const [engagementStats, testStats, topOpen] = await Promise.all([
|
|
202
|
+
client.runAggregateQuery('sn_audit_engagement', 'state', 'COUNT'),
|
|
203
|
+
client.runAggregateQuery('sn_audit_control_test', 'design_effectiveness', 'COUNT'),
|
|
204
|
+
client.queryRecords({
|
|
205
|
+
table: 'sn_audit_engagement',
|
|
206
|
+
query: 'stateIN-5,1,2,5,6',
|
|
207
|
+
fields: 'number,name,state,engagement_type,high_priority_issues',
|
|
208
|
+
orderBy: '-high_priority_issues',
|
|
209
|
+
limit: top,
|
|
210
|
+
display_value: 'all',
|
|
211
|
+
}),
|
|
212
|
+
]);
|
|
213
|
+
const engagementsByState = summarizeByState(engagementStats, ENGAGEMENT_STATE_LABELS);
|
|
214
|
+
const testsByEffectiveness = summarizeByState(testStats, { none: 'None', effective: 'Effective', ineffective: 'Ineffective' });
|
|
215
|
+
const total = (rows) => rows.reduce((s, r) => s + r.count, 0);
|
|
216
|
+
const openEngagements = engagementsByState
|
|
217
|
+
.filter(r => !['3', '4'].includes(r.state))
|
|
218
|
+
.reduce((s, r) => s + r.count, 0);
|
|
219
|
+
return {
|
|
220
|
+
engagements: { total: total(engagementsByState), open: openEngagements, by_state: engagementsByState },
|
|
221
|
+
control_tests: { total: total(testsByEffectiveness), by_effectiveness: testsByEffectiveness },
|
|
222
|
+
top_open_engagements_by_priority_issues: topOpen.records,
|
|
223
|
+
summary: `Engagements: ${total(engagementsByState)} total (${openEngagements} open) · ` +
|
|
224
|
+
`Control Tests: ${total(testsByEffectiveness)} total · ` +
|
|
225
|
+
`top ${topOpen.count} open engagement(s) by high-priority issues listed`,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
default:
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=grc-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grc-audit.js","sourceRoot":"","sources":["../../src/tools/grc-audit.ts"],"names":[],"mappings":"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"}
|