@sonisoft/now-sdk-ext-mcp 1.0.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/README.md +393 -0
- package/dist/common/connection.d.ts +42 -0
- package/dist/common/connection.d.ts.map +1 -0
- package/dist/common/connection.js +119 -0
- package/dist/common/connection.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/aggregate.d.ts +20 -0
- package/dist/tools/aggregate.d.ts.map +1 -0
- package/dist/tools/aggregate.js +271 -0
- package/dist/tools/aggregate.js.map +1 -0
- package/dist/tools/app-manager.d.ts +50 -0
- package/dist/tools/app-manager.d.ts.map +1 -0
- package/dist/tools/app-manager.js +756 -0
- package/dist/tools/app-manager.js.map +1 -0
- package/dist/tools/atf.d.ts +16 -0
- package/dist/tools/atf.d.ts.map +1 -0
- package/dist/tools/atf.js +246 -0
- package/dist/tools/atf.js.map +1 -0
- package/dist/tools/attachment.d.ts +20 -0
- package/dist/tools/attachment.d.ts.map +1 -0
- package/dist/tools/attachment.js +223 -0
- package/dist/tools/attachment.js.map +1 -0
- package/dist/tools/batch.d.ts +15 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +159 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cmdb.d.ts +14 -0
- package/dist/tools/cmdb.d.ts.map +1 -0
- package/dist/tools/cmdb.js +199 -0
- package/dist/tools/cmdb.js.map +1 -0
- package/dist/tools/codesearch.d.ts +31 -0
- package/dist/tools/codesearch.d.ts.map +1 -0
- package/dist/tools/codesearch.js +371 -0
- package/dist/tools/codesearch.js.map +1 -0
- package/dist/tools/discovery.d.ts +15 -0
- package/dist/tools/discovery.d.ts.map +1 -0
- package/dist/tools/discovery.js +204 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/execute-script.d.ts +9 -0
- package/dist/tools/execute-script.d.ts.map +1 -0
- package/dist/tools/execute-script.js +106 -0
- package/dist/tools/execute-script.js.map +1 -0
- package/dist/tools/find-atf-tests.d.ts +9 -0
- package/dist/tools/find-atf-tests.d.ts.map +1 -0
- package/dist/tools/find-atf-tests.js +152 -0
- package/dist/tools/find-atf-tests.js.map +1 -0
- package/dist/tools/health.d.ts +9 -0
- package/dist/tools/health.d.ts.map +1 -0
- package/dist/tools/health.js +137 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/lookup-app.d.ts +11 -0
- package/dist/tools/lookup-app.d.ts.map +1 -0
- package/dist/tools/lookup-app.js +242 -0
- package/dist/tools/lookup-app.js.map +1 -0
- package/dist/tools/lookup-columns.d.ts +10 -0
- package/dist/tools/lookup-columns.d.ts.map +1 -0
- package/dist/tools/lookup-columns.js +180 -0
- package/dist/tools/lookup-columns.js.map +1 -0
- package/dist/tools/lookup-table.d.ts +10 -0
- package/dist/tools/lookup-table.d.ts.map +1 -0
- package/dist/tools/lookup-table.js +150 -0
- package/dist/tools/lookup-table.js.map +1 -0
- package/dist/tools/query-batch.d.ts +16 -0
- package/dist/tools/query-batch.d.ts.map +1 -0
- package/dist/tools/query-batch.js +197 -0
- package/dist/tools/query-batch.js.map +1 -0
- package/dist/tools/query-syslog.d.ts +9 -0
- package/dist/tools/query-syslog.d.ts.map +1 -0
- package/dist/tools/query-syslog.js +127 -0
- package/dist/tools/query-syslog.js.map +1 -0
- package/dist/tools/query-table.d.ts +8 -0
- package/dist/tools/query-table.d.ts.map +1 -0
- package/dist/tools/query-table.js +137 -0
- package/dist/tools/query-table.js.map +1 -0
- package/dist/tools/schema.d.ts +24 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +321 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/scope.d.ts +25 -0
- package/dist/tools/scope.d.ts.map +1 -0
- package/dist/tools/scope.js +226 -0
- package/dist/tools/scope.js.map +1 -0
- package/dist/tools/scriptsync.d.ts +14 -0
- package/dist/tools/scriptsync.d.ts.map +1 -0
- package/dist/tools/scriptsync.js +167 -0
- package/dist/tools/scriptsync.js.map +1 -0
- package/dist/tools/task.d.ts +39 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +390 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/updateset.d.ts +46 -0
- package/dist/tools/updateset.d.ts.map +1 -0
- package/dist/tools/updateset.js +475 -0
- package/dist/tools/updateset.js.map +1 -0
- package/dist/tools/workflow.d.ts +9 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +164 -0
- package/dist/tools/workflow.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { QueryBatchOperations } from "@sonisoft/now-sdk-ext-core";
|
|
3
|
+
import { withConnectionRetry } from "../common/connection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Registers the query_update_records tool on the MCP server.
|
|
6
|
+
*
|
|
7
|
+
* Finds records matching an encoded query and updates them in bulk.
|
|
8
|
+
* Supports dry-run mode (confirm=false) to preview affected records before committing.
|
|
9
|
+
*/
|
|
10
|
+
export function registerQueryUpdateRecordsTool(server) {
|
|
11
|
+
server.registerTool("query_update_records", {
|
|
12
|
+
title: "Query Update Records",
|
|
13
|
+
description: "Find records matching an encoded query and update them all with the specified data. " +
|
|
14
|
+
"Supports a dry-run mode: set confirm=false (the default) to see how many records " +
|
|
15
|
+
"would be affected WITHOUT making changes, then set confirm=true to execute.\n\n" +
|
|
16
|
+
"IMPORTANT: When confirm=true, this modifies records on the ServiceNow instance. " +
|
|
17
|
+
"Always run a dry-run first to verify the match count before committing.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
instance: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("The ServiceNow instance auth alias (e.g., " +
|
|
23
|
+
'"dev224436", "prod"). If not provided, falls back ' +
|
|
24
|
+
"to the SN_AUTH_ALIAS environment variable."),
|
|
25
|
+
table: z
|
|
26
|
+
.string()
|
|
27
|
+
.describe('The ServiceNow table to update records on (e.g., "incident", "sys_user").'),
|
|
28
|
+
query: z
|
|
29
|
+
.string()
|
|
30
|
+
.describe("An encoded query string to find records to update. " +
|
|
31
|
+
'Examples: "active=true^priority=5", "state=1^assignment_group=NULL".'),
|
|
32
|
+
data: z
|
|
33
|
+
.record(z.unknown())
|
|
34
|
+
.describe('Field values to set on all matching records (e.g., {"priority": "3", "state": "2"}).'),
|
|
35
|
+
confirm: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.default(false)
|
|
38
|
+
.describe("When false (default), performs a dry-run that returns the match count " +
|
|
39
|
+
"without making changes. Set to true to actually execute the updates."),
|
|
40
|
+
limit: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.min(1)
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Maximum number of records to update. If omitted, updates all matches."),
|
|
46
|
+
},
|
|
47
|
+
}, async ({ instance, table, query, data, confirm, limit }) => {
|
|
48
|
+
try {
|
|
49
|
+
const result = await withConnectionRetry(instance, async (snInstance) => {
|
|
50
|
+
const qb = new QueryBatchOperations(snInstance);
|
|
51
|
+
return await qb.queryUpdate({
|
|
52
|
+
table,
|
|
53
|
+
query,
|
|
54
|
+
data,
|
|
55
|
+
confirm,
|
|
56
|
+
limit,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
const lines = [];
|
|
60
|
+
if (result.dryRun) {
|
|
61
|
+
lines.push("=== Query Update — DRY RUN ===");
|
|
62
|
+
lines.push(`Table: ${table}`);
|
|
63
|
+
lines.push(`Query: ${query}`);
|
|
64
|
+
lines.push(`Records that would be updated: ${result.matchCount}`);
|
|
65
|
+
lines.push("");
|
|
66
|
+
lines.push("No changes were made. Set confirm=true to execute the update.");
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
lines.push("=== Query Update Results ===");
|
|
70
|
+
lines.push(`Table: ${table}`);
|
|
71
|
+
lines.push(`Query: ${query}`);
|
|
72
|
+
lines.push(`Success: ${result.success}`);
|
|
73
|
+
lines.push(`Matched: ${result.matchCount}`);
|
|
74
|
+
lines.push(`Updated: ${result.updatedCount}`);
|
|
75
|
+
lines.push(`Execution Time: ${result.executionTimeMs}ms`);
|
|
76
|
+
if (result.errors && result.errors.length > 0) {
|
|
77
|
+
lines.push("");
|
|
78
|
+
lines.push("Errors:");
|
|
79
|
+
for (const err of result.errors) {
|
|
80
|
+
lines.push(` ${JSON.stringify(err)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
90
|
+
return {
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `Error in query update: ${message}`,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Registers the query_delete_records tool on the MCP server.
|
|
104
|
+
*
|
|
105
|
+
* Finds records matching an encoded query and deletes them in bulk.
|
|
106
|
+
* Supports dry-run mode (confirm=false) to preview affected records before committing.
|
|
107
|
+
*/
|
|
108
|
+
export function registerQueryDeleteRecordsTool(server) {
|
|
109
|
+
server.registerTool("query_delete_records", {
|
|
110
|
+
title: "Query Delete Records",
|
|
111
|
+
description: "Find records matching an encoded query and delete them all. " +
|
|
112
|
+
"Supports a dry-run mode: set confirm=false (the default) to see how many records " +
|
|
113
|
+
"would be deleted WITHOUT making changes, then set confirm=true to execute.\n\n" +
|
|
114
|
+
"IMPORTANT: When confirm=true, this PERMANENTLY DELETES records on the ServiceNow " +
|
|
115
|
+
"instance. Always run a dry-run first to verify the match count before committing. " +
|
|
116
|
+
"This operation cannot be undone.",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
instance: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe("The ServiceNow instance auth alias (e.g., " +
|
|
122
|
+
'"dev224436", "prod"). If not provided, falls back ' +
|
|
123
|
+
"to the SN_AUTH_ALIAS environment variable."),
|
|
124
|
+
table: z
|
|
125
|
+
.string()
|
|
126
|
+
.describe('The ServiceNow table to delete records from (e.g., "incident", "sys_user").'),
|
|
127
|
+
query: z
|
|
128
|
+
.string()
|
|
129
|
+
.describe("An encoded query string to find records to delete. " +
|
|
130
|
+
'Examples: "active=false^sys_created_on<javascript:gs.daysAgoStart(365)".'),
|
|
131
|
+
confirm: z
|
|
132
|
+
.boolean()
|
|
133
|
+
.default(false)
|
|
134
|
+
.describe("When false (default), performs a dry-run that returns the match count " +
|
|
135
|
+
"without deleting anything. Set to true to actually execute the deletes."),
|
|
136
|
+
limit: z
|
|
137
|
+
.number()
|
|
138
|
+
.int()
|
|
139
|
+
.min(1)
|
|
140
|
+
.optional()
|
|
141
|
+
.describe("Maximum number of records to delete. If omitted, deletes all matches."),
|
|
142
|
+
},
|
|
143
|
+
}, async ({ instance, table, query, confirm, limit }) => {
|
|
144
|
+
try {
|
|
145
|
+
const result = await withConnectionRetry(instance, async (snInstance) => {
|
|
146
|
+
const qb = new QueryBatchOperations(snInstance);
|
|
147
|
+
return await qb.queryDelete({
|
|
148
|
+
table,
|
|
149
|
+
query,
|
|
150
|
+
confirm,
|
|
151
|
+
limit,
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
const lines = [];
|
|
155
|
+
if (result.dryRun) {
|
|
156
|
+
lines.push("=== Query Delete — DRY RUN ===");
|
|
157
|
+
lines.push(`Table: ${table}`);
|
|
158
|
+
lines.push(`Query: ${query}`);
|
|
159
|
+
lines.push(`Records that would be deleted: ${result.matchCount}`);
|
|
160
|
+
lines.push("");
|
|
161
|
+
lines.push("No records were deleted. Set confirm=true to execute the deletion.");
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
lines.push("=== Query Delete Results ===");
|
|
165
|
+
lines.push(`Table: ${table}`);
|
|
166
|
+
lines.push(`Query: ${query}`);
|
|
167
|
+
lines.push(`Success: ${result.success}`);
|
|
168
|
+
lines.push(`Matched: ${result.matchCount}`);
|
|
169
|
+
lines.push(`Deleted: ${result.deletedCount}`);
|
|
170
|
+
lines.push(`Execution Time: ${result.executionTimeMs}ms`);
|
|
171
|
+
if (result.errors && result.errors.length > 0) {
|
|
172
|
+
lines.push("");
|
|
173
|
+
lines.push("Errors:");
|
|
174
|
+
for (const err of result.errors) {
|
|
175
|
+
lines.push(` ${JSON.stringify(err)}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
185
|
+
return {
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: "text",
|
|
189
|
+
text: `Error in query delete: ${message}`,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
isError: true,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=query-batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-batch.js","sourceRoot":"","sources":["../../src/tools/query-batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers the query_syslog tool on the MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Queries the ServiceNow syslog table for log entries. Designed to be
|
|
6
|
+
* called repeatedly by an agent to monitor for errors and debug output.
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerQuerySyslogTool(server: McpServer): void;
|
|
9
|
+
//# sourceMappingURL=query-syslog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-syslog.d.ts","sourceRoot":"","sources":["../../src/tools/query-syslog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6I/D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SyslogReader } from "@sonisoft/now-sdk-ext-core";
|
|
3
|
+
import { withConnectionRetry } from "../common/connection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Registers the query_syslog tool on the MCP server.
|
|
6
|
+
*
|
|
7
|
+
* Queries the ServiceNow syslog table for log entries. Designed to be
|
|
8
|
+
* called repeatedly by an agent to monitor for errors and debug output.
|
|
9
|
+
*/
|
|
10
|
+
export function registerQuerySyslogTool(server) {
|
|
11
|
+
server.registerTool("query_syslog", {
|
|
12
|
+
title: "Query Syslog",
|
|
13
|
+
description: "Query the ServiceNow system log (syslog) to check for errors, warnings, " +
|
|
14
|
+
"and debug output. Returns log entries with timestamps, levels, sources, " +
|
|
15
|
+
"and messages. Results are ordered newest-first.\n\n" +
|
|
16
|
+
"Useful for monitoring script execution results, checking for errors after " +
|
|
17
|
+
"deployments, and debugging issues. Can be called repeatedly to check for " +
|
|
18
|
+
"new entries. Use the 'syslog' table for system-level logs and " +
|
|
19
|
+
"'syslog_app_scope' for scoped application logs.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
instance: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("The ServiceNow instance auth alias (e.g., " +
|
|
25
|
+
'"dev224436", "prod"). If not provided, falls back ' +
|
|
26
|
+
"to the SN_AUTH_ALIAS environment variable."),
|
|
27
|
+
query: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("A ServiceNow encoded query string for additional filtering. " +
|
|
31
|
+
'Example: "messageLIKEscript error^source=sys_script". ' +
|
|
32
|
+
"This is combined with any level/source filters specified below."),
|
|
33
|
+
level: z
|
|
34
|
+
.enum(["error", "warning", "info", "debug"])
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Filter by log level. Only returns entries at the specified level."),
|
|
37
|
+
source: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("Filter by log source (e.g., \"sys_script\", \"workflow\"). " +
|
|
41
|
+
"Exact match."),
|
|
42
|
+
limit: z
|
|
43
|
+
.number()
|
|
44
|
+
.int()
|
|
45
|
+
.min(1)
|
|
46
|
+
.max(500)
|
|
47
|
+
.default(50)
|
|
48
|
+
.describe("Maximum number of syslog entries to return. Default is 50."),
|
|
49
|
+
table: z
|
|
50
|
+
.enum(["syslog", "syslog_app_scope"])
|
|
51
|
+
.default("syslog")
|
|
52
|
+
.describe('Which syslog table to query. Use "syslog" for the main system log, ' +
|
|
53
|
+
'or "syslog_app_scope" for scoped application logs which include ' +
|
|
54
|
+
"the application scope field."),
|
|
55
|
+
},
|
|
56
|
+
}, async ({ instance, query, level, source, limit, table }) => {
|
|
57
|
+
try {
|
|
58
|
+
const records = await withConnectionRetry(instance, async (snInstance) => {
|
|
59
|
+
const syslogReader = new SyslogReader(snInstance);
|
|
60
|
+
// Build encoded query from friendly parameters
|
|
61
|
+
const queryParts = [];
|
|
62
|
+
if (query)
|
|
63
|
+
queryParts.push(query);
|
|
64
|
+
if (level)
|
|
65
|
+
queryParts.push(`level=${level}`);
|
|
66
|
+
if (source)
|
|
67
|
+
queryParts.push(`source=${source}`);
|
|
68
|
+
queryParts.push("ORDERBYDESCsys_created_on");
|
|
69
|
+
const encodedQuery = queryParts.join("^");
|
|
70
|
+
return table === "syslog_app_scope"
|
|
71
|
+
? await syslogReader.querySyslogAppScope(encodedQuery, limit)
|
|
72
|
+
: await syslogReader.querySyslog(encodedQuery, limit);
|
|
73
|
+
});
|
|
74
|
+
const lines = [];
|
|
75
|
+
const filterInfo = [`Table: ${table}`];
|
|
76
|
+
if (level)
|
|
77
|
+
filterInfo.push(`Level: ${level}`);
|
|
78
|
+
if (source)
|
|
79
|
+
filterInfo.push(`Source: ${source}`);
|
|
80
|
+
filterInfo.push(`Records: ${records.length}`);
|
|
81
|
+
lines.push("=== Syslog Query Results ===");
|
|
82
|
+
lines.push(filterInfo.join(" | "));
|
|
83
|
+
if (records.length === 0) {
|
|
84
|
+
lines.push("");
|
|
85
|
+
lines.push("No syslog entries found matching the criteria.");
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
lines.push("");
|
|
89
|
+
records.forEach((record) => {
|
|
90
|
+
const timestamp = record.sys_created_on || "unknown";
|
|
91
|
+
const lvl = (record.level || "unknown").toUpperCase();
|
|
92
|
+
const src = record.source || "unknown";
|
|
93
|
+
const msg = record.message || "";
|
|
94
|
+
let logLine = `[${timestamp}] ${lvl} | ${src} | ${msg}`;
|
|
95
|
+
// For syslog_app_scope records, include the app_scope
|
|
96
|
+
if ("app_scope" in record && record.app_scope) {
|
|
97
|
+
logLine = `[${timestamp}] ${lvl} | ${src} (${record.app_scope}) | ${msg}`;
|
|
98
|
+
}
|
|
99
|
+
lines.push(logLine);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
lines.push("");
|
|
103
|
+
lines.push(`=== ${records.length} entries returned ===`);
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: lines.join("\n"),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: "text",
|
|
119
|
+
text: `Error querying syslog: ${message}`,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
isError: true,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=query-syslog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-syslog.js","sourceRoot":"","sources":["../../src/tools/query-syslog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers the query_table tool on the MCP server.
|
|
4
|
+
*
|
|
5
|
+
* General-purpose tool for querying any ServiceNow table via the Table API.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerQueryTableTool(server: McpServer): void;
|
|
8
|
+
//# sourceMappingURL=query-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-table.d.ts","sourceRoot":"","sources":["../../src/tools/query-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyJ9D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { TableAPIRequest } from "@sonisoft/now-sdk-ext-core";
|
|
3
|
+
import { withConnectionRetry, isRetryableResponse, } from "../common/connection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Registers the query_table tool on the MCP server.
|
|
6
|
+
*
|
|
7
|
+
* General-purpose tool for querying any ServiceNow table via the Table API.
|
|
8
|
+
*/
|
|
9
|
+
export function registerQueryTableTool(server) {
|
|
10
|
+
server.registerTool("query_table", {
|
|
11
|
+
title: "Query ServiceNow Table",
|
|
12
|
+
description: "Query any ServiceNow table using the Table API. Returns records matching " +
|
|
13
|
+
"the specified criteria. Supports encoded query strings, field selection, " +
|
|
14
|
+
"and display value resolution.\n\n" +
|
|
15
|
+
"Use this for general-purpose data retrieval from any table (incident, " +
|
|
16
|
+
"sys_user, cmdb_ci, change_request, etc.).",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
instance: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("The ServiceNow instance auth alias (e.g., " +
|
|
22
|
+
'"dev224436", "prod"). If not provided, falls back ' +
|
|
23
|
+
"to the SN_AUTH_ALIAS environment variable."),
|
|
24
|
+
table: z
|
|
25
|
+
.string()
|
|
26
|
+
.describe("The ServiceNow table name to query (e.g., \"incident\", " +
|
|
27
|
+
'"sys_user", "cmdb_ci_server"). This is the internal ' +
|
|
28
|
+
"table name, not the label."),
|
|
29
|
+
query: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("A ServiceNow encoded query string to filter records. " +
|
|
33
|
+
'Examples: "active=true^priority=1", ' +
|
|
34
|
+
'"short_descriptionLIKEnetwork^state!=7", ' +
|
|
35
|
+
'"sys_created_on>javascript:gs.daysAgoStart(7)". ' +
|
|
36
|
+
"If omitted, returns all records up to the limit."),
|
|
37
|
+
fields: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("Comma-separated list of field names to return (e.g., " +
|
|
41
|
+
'"sys_id,number,short_description,state"). ' +
|
|
42
|
+
"If omitted, all fields are returned. Specifying fields " +
|
|
43
|
+
"improves performance and readability."),
|
|
44
|
+
limit: z
|
|
45
|
+
.number()
|
|
46
|
+
.int()
|
|
47
|
+
.min(1)
|
|
48
|
+
.max(1000)
|
|
49
|
+
.default(20)
|
|
50
|
+
.describe("Maximum number of records to return. Default is 20, max is 1000."),
|
|
51
|
+
display_value: z
|
|
52
|
+
.boolean()
|
|
53
|
+
.default(false)
|
|
54
|
+
.describe("When true, returns display values instead of internal values for " +
|
|
55
|
+
"reference and choice fields. For example, assignment_group returns " +
|
|
56
|
+
"the group name instead of the sys_id."),
|
|
57
|
+
},
|
|
58
|
+
}, async ({ instance, table, query, fields, limit, display_value }) => {
|
|
59
|
+
try {
|
|
60
|
+
const response = await withConnectionRetry(instance, async (snInstance) => {
|
|
61
|
+
const tableApi = new TableAPIRequest(snInstance);
|
|
62
|
+
const queryParams = {
|
|
63
|
+
sysparm_limit: limit,
|
|
64
|
+
};
|
|
65
|
+
if (query)
|
|
66
|
+
queryParams.sysparm_query = query;
|
|
67
|
+
if (fields)
|
|
68
|
+
queryParams.sysparm_fields = fields;
|
|
69
|
+
if (display_value)
|
|
70
|
+
queryParams.sysparm_display_value = "true";
|
|
71
|
+
const resp = await tableApi.get(table, queryParams);
|
|
72
|
+
// If the response looks like a dead session, throw so
|
|
73
|
+
// withConnectionRetry can evict the cache and retry.
|
|
74
|
+
if (isRetryableResponse(resp)) {
|
|
75
|
+
const status = resp?.status ?? "unknown";
|
|
76
|
+
const statusText = resp?.statusText ?? "No response";
|
|
77
|
+
throw new Error(`HTTP ${status} ${statusText} querying table "${table}"`);
|
|
78
|
+
}
|
|
79
|
+
return resp;
|
|
80
|
+
});
|
|
81
|
+
if (response.status !== 200) {
|
|
82
|
+
return {
|
|
83
|
+
content: [
|
|
84
|
+
{
|
|
85
|
+
type: "text",
|
|
86
|
+
text: `Error querying table "${table}": HTTP ${response.status} ${response.statusText}`,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
isError: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const records = response.bodyObject?.result ?? [];
|
|
93
|
+
const lines = [];
|
|
94
|
+
lines.push("=== Query Results ===");
|
|
95
|
+
lines.push(`Table: ${table}`);
|
|
96
|
+
if (query)
|
|
97
|
+
lines.push(`Query: ${query}`);
|
|
98
|
+
if (fields)
|
|
99
|
+
lines.push(`Fields: ${fields}`);
|
|
100
|
+
lines.push(`Records returned: ${records.length}`);
|
|
101
|
+
if (records.length === 0) {
|
|
102
|
+
lines.push("");
|
|
103
|
+
lines.push("No records found matching the query.");
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
records.forEach((record, index) => {
|
|
107
|
+
lines.push("");
|
|
108
|
+
lines.push(`--- Record ${index + 1} ---`);
|
|
109
|
+
lines.push(JSON.stringify(record, null, 2));
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
lines.push("");
|
|
113
|
+
lines.push(`=== ${records.length} record(s) returned ===`);
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
text: lines.join("\n"),
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
125
|
+
return {
|
|
126
|
+
content: [
|
|
127
|
+
{
|
|
128
|
+
type: "text",
|
|
129
|
+
text: `Error querying table: ${message}`,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
isError: true,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=query-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-table.js","sourceRoot":"","sources":["../../src/tools/query-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers the discover_table_schema tool on the MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Discovers the full schema of a ServiceNow table including all fields,
|
|
6
|
+
* types, references, and optionally choice values, relationships,
|
|
7
|
+
* UI policies, and business rules.
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerDiscoverTableSchemaTool(server: McpServer): void;
|
|
10
|
+
/**
|
|
11
|
+
* Registers the explain_field tool on the MCP server.
|
|
12
|
+
*
|
|
13
|
+
* Gets a detailed explanation of a specific field on a table, including
|
|
14
|
+
* type, constraints, help text, and available choice values.
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerExplainFieldTool(server: McpServer): void;
|
|
17
|
+
/**
|
|
18
|
+
* Registers the validate_catalog tool on the MCP server.
|
|
19
|
+
*
|
|
20
|
+
* Validates a catalog item's configuration, checking variables for
|
|
21
|
+
* duplicates, missing names, inactive mandatory vars, and UI policy issues.
|
|
22
|
+
*/
|
|
23
|
+
export declare function registerValidateCatalogTool(server: McpServer): void;
|
|
24
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/tools/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuLvE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiGhE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgGnE"}
|