@tenonhq/dovetail-servicenow 0.0.16 → 0.0.17

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.
@@ -7,8 +7,8 @@
7
7
  * a client is injected via RegistryDeps (used by tests).
8
8
  */
9
9
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
- import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
11
10
  import { z } from "zod";
11
+ import type { ToolAnnotations } from "@tenonhq/dovetail-mcp-kit";
12
12
  import type { ServiceNowClient } from "../client";
13
13
  export declare var TOOL_NAMES: readonly ["create_view", "set_list_layout", "set_form_layout", "set_related_lists", "add_choices_to_field", "flow_view", "action_view", "flow_publish", "flow_copy", "flow_create", "flow_test", "flow_edit"];
14
14
  export type ToolName = typeof TOOL_NAMES[number];
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.TOOL_NAMES = void 0;
12
12
  exports.buildDescriptors = buildDescriptors;
13
13
  exports.registerAllTools = registerAllTools;
14
+ const dovetail_mcp_kit_1 = require("@tenonhq/dovetail-mcp-kit");
14
15
  const client_1 = require("../client");
15
16
  const views_1 = require("../layout/views");
16
17
  const listLayout_1 = require("../layout/listLayout");
@@ -39,20 +40,9 @@ exports.TOOL_NAMES = [
39
40
  "flow_test",
40
41
  "flow_edit"
41
42
  ];
42
- // MCP tool annotations (spec 2025-11-25) untrusted behavioural hints that let a
43
- // host parallelize reads and gate writes; never a security boundary. Five presets
44
- // cover every tool's safety profile:
45
- // READ_ONLY — no writes; safe to auto-approve and run concurrently.
46
- // WRITE_ADDITIVE_IDEMPOTENT — additive write, safe to repeat (idempotent upsert/create).
47
- // WRITE_CREATE — additive write, NOT idempotent (each call mints a new record).
48
- // WRITE_OVERWRITE — destructive but idempotent (prune/overwrite: same end state).
49
- // WRITE_EXECUTE — destructive AND non-idempotent (runs a flow; repeating repeats the effect).
43
+ // Annotation presets (READ_ONLY / WRITE_ADDITIVE_IDEMPOTENT / WRITE_CREATE /
44
+ // WRITE_OVERWRITE / WRITE_EXECUTE) come from @tenonhq/dovetail-mcp-kit.
50
45
  // openWorldHint is left at its spec default (true) — every tool reaches a ServiceNow instance.
51
- var READ_ONLY = { readOnlyHint: true };
52
- var WRITE_ADDITIVE_IDEMPOTENT = { readOnlyHint: false, destructiveHint: false, idempotentHint: true };
53
- var WRITE_CREATE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false };
54
- var WRITE_OVERWRITE = { readOnlyHint: false, destructiveHint: true, idempotentHint: true };
55
- var WRITE_EXECUTE = { readOnlyHint: false, destructiveHint: true, idempotentHint: false };
56
46
  function buildDescriptors(deps = {}) {
57
47
  function client() {
58
48
  return deps.client || (0, client_1.createClient)({});
@@ -60,7 +50,7 @@ function buildDescriptors(deps = {}) {
60
50
  return [
61
51
  {
62
52
  name: "create_view",
63
- annotations: WRITE_ADDITIVE_IDEMPOTENT,
53
+ annotations: dovetail_mcp_kit_1.WRITE_ADDITIVE_IDEMPOTENT,
64
54
  description: "Create a ServiceNow custom view (sys_ui_view). Idempotent — an existing view of the "
65
55
  + "same name is returned unchanged. Every write is captured in the supplied update set.",
66
56
  shape: schemas_1.createViewSchema.shape,
@@ -70,7 +60,7 @@ function buildDescriptors(deps = {}) {
70
60
  },
71
61
  {
72
62
  name: "set_list_layout",
73
- annotations: WRITE_OVERWRITE,
63
+ annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
74
64
  description: "Declaratively set a ServiceNow list layout — which columns appear in a list, and their "
75
65
  + "order — for a table + view. Idempotent; prune (default true) removes columns not in "
76
66
  + "the spec; dryRun previews without writing. Writes are captured in the update set.",
@@ -81,7 +71,7 @@ function buildDescriptors(deps = {}) {
81
71
  },
82
72
  {
83
73
  name: "set_form_layout",
84
- annotations: WRITE_OVERWRITE,
74
+ annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
85
75
  description: "Declaratively set a ServiceNow form layout — sections and the fields within them — for "
86
76
  + "a table + view. The first section is the primary section (omit its caption). "
87
77
  + "Idempotent; prune (default true) removes sections/fields not in the spec; dryRun "
@@ -93,7 +83,7 @@ function buildDescriptors(deps = {}) {
93
83
  },
94
84
  {
95
85
  name: "set_related_lists",
96
- annotations: WRITE_OVERWRITE,
86
+ annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
97
87
  description: "Declaratively set which related lists appear on a ServiceNow form for a table + view. "
98
88
  + "Related-list ids are \"<table>.<field>\" or \"REL:<sys_relationship>\". Idempotent; "
99
89
  + "prune (default true); dryRun previews. Writes are captured in the update set.",
@@ -104,7 +94,7 @@ function buildDescriptors(deps = {}) {
104
94
  },
105
95
  {
106
96
  name: "add_choices_to_field",
107
- annotations: WRITE_ADDITIVE_IDEMPOTENT,
97
+ annotations: dovetail_mcp_kit_1.WRITE_ADDITIVE_IDEMPOTENT,
108
98
  description: "Upsert sys_choice values for a ServiceNow table.column and (optionally) flip "
109
99
  + "sys_dictionary.choice so the field renders as a dropdown. Idempotent. Writes are "
110
100
  + "captured in the supplied update set.",
@@ -115,7 +105,7 @@ function buildDescriptors(deps = {}) {
115
105
  },
116
106
  {
117
107
  name: "flow_view",
118
- annotations: READ_ONLY,
108
+ annotations: dovetail_mcp_kit_1.READ_ONLY,
119
109
  description: "Read a ServiceNow Flow Designer flow or subflow's compiled step graph, headless. "
120
110
  + "Returns the ordered, nesting-aware list of action + flow-logic steps plus the flow "
121
111
  + "variables, via GET /api/now/processflow/flow/{sysId}. Read-only. Pass raw:true to "
@@ -128,7 +118,7 @@ function buildDescriptors(deps = {}) {
128
118
  },
129
119
  {
130
120
  name: "action_view",
131
- annotations: READ_ONLY,
121
+ annotations: dovetail_mcp_kit_1.READ_ONLY,
132
122
  description: "Read a ServiceNow Custom Action Type's compiled model (identity, inputs, outputs), "
133
123
  + "headless, via GET /api/now/processflow/action/action_types/{sysId}. Read-only. "
134
124
  + "sysId is the sys_hub_action_type_definition sys_id; scopeSysId is the application "
@@ -141,7 +131,7 @@ function buildDescriptors(deps = {}) {
141
131
  },
142
132
  {
143
133
  name: "flow_publish",
144
- annotations: WRITE_OVERWRITE,
134
+ annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
145
135
  description: "Publish (compile the snapshot of) a ServiceNow Flow Designer flow or subflow via "
146
136
  + "POST /api/now/processflow/flow/{sysId}/snapshot. This is a WRITE that recompiles the "
147
137
  + "flow's current design — use after editing in the Designer. sysId is the sys_hub_flow "
@@ -154,7 +144,7 @@ function buildDescriptors(deps = {}) {
154
144
  },
155
145
  {
156
146
  name: "flow_copy",
157
- annotations: WRITE_CREATE,
147
+ annotations: dovetail_mcp_kit_1.WRITE_CREATE,
158
148
  description: "Copy a ServiceNow flow/subflow via the Designer's Copy endpoint — a complete, faithful "
159
149
  + "clone created as an INACTIVE DRAFT in the target scope. sourceSysId is the sys_hub_flow "
160
150
  + "to copy; newName is the copy's name; scopeSysId defaults to the source's scope. Publish "
@@ -168,7 +158,7 @@ function buildDescriptors(deps = {}) {
168
158
  },
169
159
  {
170
160
  name: "flow_create",
171
- annotations: WRITE_CREATE,
161
+ annotations: dovetail_mcp_kit_1.WRITE_CREATE,
172
162
  description: "Create a NEW ServiceNow Flow Designer flow (sys_hub_flow, type=flow) from scratch and "
173
163
  + "PUBLISH it, headless. Mints a fresh flow via POST /processflow/flow, grafts the trigger + "
174
164
  + "action graph from an existing published template flow (templateSysId), then compiles the "
@@ -198,7 +188,7 @@ function buildDescriptors(deps = {}) {
198
188
  },
199
189
  {
200
190
  name: "flow_test",
201
- annotations: WRITE_EXECUTE,
191
+ annotations: dovetail_mcp_kit_1.WRITE_EXECUTE,
202
192
  description: "Test or run a ServiceNow flow/subflow. mode='validate' (default) is a safe, read-only "
203
193
  + "pre-flight — checks the flow is published and that supplied inputs match its declared "
204
194
  + "variables; it never runs the flow. mode='execute' actually runs it via the server-side "
@@ -219,7 +209,7 @@ function buildDescriptors(deps = {}) {
219
209
  },
220
210
  {
221
211
  name: "flow_edit",
222
- annotations: WRITE_OVERWRITE,
212
+ annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
223
213
  description: "Edit a ServiceNow flow/subflow in place. Supports rename (name/internalName), description, "
224
214
  + "and patchStepInputs (set named input values on steps by uiId or label). apply=false "
225
215
  + "(default) is a dry-run that returns the diff; apply=true persists the edit (a write). "
@@ -241,25 +231,7 @@ function buildDescriptors(deps = {}) {
241
231
  ];
242
232
  }
243
233
  function registerAllTools(server, deps = {}) {
244
- var descriptors = buildDescriptors(deps);
245
- for (var i = 0; i < descriptors.length; i += 1) {
246
- registerOne(server, descriptors[i]);
247
- }
248
- }
249
- function registerOne(server, desc) {
250
- server.registerTool(desc.name, { description: desc.description, inputSchema: desc.shape, annotations: desc.annotations }, async function (args) {
251
- try {
252
- var result = await desc.handler(args);
253
- return { content: [{ type: "text", text: JSON.stringify(result) }] };
254
- }
255
- catch (err) {
256
- var message = err instanceof Error ? err.message : String(err);
257
- return {
258
- isError: true,
259
- content: [
260
- { type: "text", text: JSON.stringify({ error: message, tool: desc.name }) }
261
- ]
262
- };
263
- }
264
- });
234
+ // registerKitTools owns serialization + the { error, retryable, tool } contract.
235
+ // No telemetry recorder is injected here (telemetry parity is a P2 follow-on).
236
+ (0, dovetail_mcp_kit_1.registerKitTools)(server, buildDescriptors(deps));
265
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenonhq/dovetail-servicenow",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -19,6 +19,7 @@
19
19
  "license": "GPL-3.0",
20
20
  "dependencies": {
21
21
  "@modelcontextprotocol/sdk": "^1.29.0",
22
+ "@tenonhq/dovetail-mcp-kit": "~0.0.1",
22
23
  "axios": "^1.5.1",
23
24
  "dotenv": "^16.3.1",
24
25
  "zod": "^3.23.0"