@sanity/workflow-mcp 0.24.0 → 0.25.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/dist/index.d.ts CHANGED
@@ -7,13 +7,26 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
7
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
8
8
  import type { ServerNotification } from "@modelcontextprotocol/sdk/types.js";
9
9
  import type { ServerRequest } from "@modelcontextprotocol/sdk/types.js";
10
+ import type { StartKind } from "@sanity/workflow-engine";
10
11
  import type { StuckCause } from "@sanity/workflow-engine";
11
12
  import type { SuggestedRemediation } from "@sanity/workflow-engine";
12
13
  import type { TelemetryLogger } from "@sanity/telemetry";
13
14
  import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
14
15
  import type { WorkflowDefinition } from "@sanity/workflow-engine";
15
16
  import { WorkflowResource } from "@sanity/workflow-engine";
16
- import { ZodRawShape } from "zod";
17
+ import { ZodRawShape } from "zod/v3";
18
+
19
+ export declare const deployWorkflowDefinitionTool: WorkflowToolDef;
20
+
21
+ export declare const diagnoseWorkflowTool: WorkflowToolDef;
22
+
23
+ export declare const fireActionTool: WorkflowToolDef;
24
+
25
+ export declare const getWorkflowAuthoringGuideTool: WorkflowToolDef;
26
+
27
+ export declare const getWorkflowDefinitionTool: WorkflowToolDef;
28
+
29
+ export declare const getWorkflowStateTool: WorkflowToolDef;
17
30
 
18
31
  /**
19
32
  * The host seam: produce the {@link WorkflowToolContext} for one tool
@@ -30,6 +43,25 @@ export declare type GetWorkflowToolContext = (
30
43
  input: unknown,
31
44
  ) => WorkflowToolContext | Promise<WorkflowToolContext>;
32
45
 
46
+ /**
47
+ * The model-facing description of the tag-discovery capability. Hosts can't
48
+ * share the implementation — each owns its client and its resource spelling —
49
+ * so what the model is told about the answer lives here instead: what the list
50
+ * means, and that finding a tag is not the same as being allowed to choose one.
51
+ */
52
+ export declare const LIST_WORKFLOW_TAGS_DESCRIPTION: string;
53
+
54
+ /**
55
+ * The wire name of the tag-discovery tool. Declared here rather than at the
56
+ * registration site because the address vocabulary refers to it in prose a model
57
+ * reads — a rename must not leave that prose naming a tool nobody registers.
58
+ */
59
+ export declare const LIST_WORKFLOW_TAGS_TOOL_NAME = "list_workflow_tags";
60
+
61
+ export declare const listWorkflowDefinitionsTool: WorkflowToolDef;
62
+
63
+ export declare const listWorkflowInstancesTool: WorkflowToolDef;
64
+
33
65
  /**
34
66
  * One invocable (fireAction-fired) action. Two whole classes of action never
35
67
  * appear here: an action whose `filter` scoped it out for this actor is
@@ -38,7 +70,7 @@ export declare type GetWorkflowToolContext = (
38
70
  * {@link ProjectedAutomation} instead — the engine fires it, no caller can.
39
71
  */
40
72
  export declare interface ProjectedActionVerdict {
41
- /** Action name — what to pass to `fire_action` as `action`. */
73
+ /** Action name — what to pass to `fire_workflow_action` as `action`. */
42
74
  action: string;
43
75
  /** Human label for the action, if the definition provides one. */
44
76
  title?: string;
@@ -46,14 +78,14 @@ export declare interface ProjectedActionVerdict {
46
78
  allowed: boolean;
47
79
  /** When `allowed` is false, a short reason describing why. */
48
80
  disabledReason?: string;
49
- /** The action's declared params — what `fire_action`'s `params` object must
81
+ /** The action's declared params — what `fire_workflow_action`'s `params` object must
50
82
  * satisfy (each entry names the param and whether it is required). Absent
51
83
  * when the action declares none. */
52
84
  params?: ActionParam[];
53
85
  }
54
86
 
55
87
  export declare interface ProjectedActivity {
56
- /** Activity name — what to pass to `fire_action` as `activity`. */
88
+ /** Activity name — what to pass to `fire_workflow_action` as `activity`. */
57
89
  activity: string;
58
90
  /** Human label, if provided. */
59
91
  title?: string;
@@ -94,10 +126,10 @@ export declare interface ProjectedActivity {
94
126
  /**
95
127
  * One cascade-fired (`when`) action, narrated as automation: the engine fires
96
128
  * it on its own the moment the trigger holds — it is never invocable via
97
- * `fire_action`, so it must not read as a button.
129
+ * `fire_workflow_action`, so it must not read as a button.
98
130
  */
99
131
  export declare interface ProjectedAutomation {
100
- /** The cascade-fired action's name. Not accepted by `fire_action`. */
132
+ /** The cascade-fired action's name. Not accepted by `fire_workflow_action`. */
101
133
  action: string;
102
134
  /** Human label, if provided. */
103
135
  title?: string;
@@ -126,6 +158,30 @@ export declare interface ProjectedDefinition {
126
158
  definition: WorkflowDefinition;
127
159
  }
128
160
 
161
+ /**
162
+ * One deployed workflow definition, latest version only — what
163
+ * `list_workflow_definitions` returns per name. Deploys are create-only
164
+ * (every deploy mints a new version), but the LLM only ever needs the
165
+ * head: it's the version `startInstance` picks by default.
166
+ */
167
+ export declare interface ProjectedDefinitionSummary {
168
+ /** Definition `name` — the value `list_workflow_instances` filters on. */
169
+ name: string;
170
+ /** Human-readable workflow title. */
171
+ title: string;
172
+ /** Author-supplied description, when the definition carries one. */
173
+ description?: string;
174
+ /** Latest deployed version. */
175
+ version: number;
176
+ /** Whether new instances can be started directly. `false` for spawn-only
177
+ * child workflows — those only come to exist under a parent instance. */
178
+ startable: boolean;
179
+ /** Who initiates standalone runs: `'interactive'` (a person, from a start
180
+ * surface) or `'autonomous'` (a system reacting to a document).
181
+ * Classification only — the engine starts either kind for any caller. */
182
+ startKind: StartKind;
183
+ }
184
+
129
185
  /**
130
186
  * The diagnosis projection — why an instance is or isn't progressing.
131
187
  *
@@ -242,6 +298,8 @@ export declare function registerWorkflowTools(
242
298
  },
243
299
  ): void;
244
300
 
301
+ export declare const startWorkflowTool: WorkflowToolDef;
302
+
245
303
  /**
246
304
  * JSON-schema descriptor for consumers that don't speak zod — e.g. the
247
305
  * Anthropic Messages API `input_schema` field. `properties`/`required`
@@ -255,7 +313,16 @@ export declare interface ToolInputJsonSchema {
255
313
  [key: string]: unknown;
256
314
  }
257
315
 
258
- /** Derive the JSON-schema descriptor from a def's zod shape. */
316
+ /**
317
+ * Derive the JSON-schema descriptor from a def's own zod shape. The converter
318
+ * options mirror the ones the MCP SDK derives its wire schema with, so one
319
+ * shape can't derive two ways.
320
+ *
321
+ * A def's own shape is not the whole advertised input: a consumer of a def
322
+ * declaring {@link WorkflowToolDef.requiresAddress} merges its own workflow
323
+ * environment parameters in, the way {@link registerWorkflowTools} does for
324
+ * this package's host.
325
+ */
259
326
  export declare function toolInputJsonSchema(
260
327
  def: WorkflowToolDef,
261
328
  ): ToolInputJsonSchema;
@@ -285,6 +352,8 @@ export declare interface ValidateDefinitionsResult {
285
352
  results: ValidateDefinitionResult[];
286
353
  }
287
354
 
355
+ export declare const validateWorkflowDefinitionTool: WorkflowToolDef;
356
+
288
357
  export declare const WORKFLOW_TOOLS: readonly WorkflowToolDef[];
289
358
 
290
359
  /**
@@ -339,6 +408,15 @@ export declare interface WorkflowToolDef {
339
408
  * descriptor for non-MCP consumers.
340
409
  */
341
410
  readonly inputSchema: ZodRawShape;
411
+ /**
412
+ * Whether this tool operates on a workflow environment, and so needs the
413
+ * engine it is handed to address the one the caller means. How a host
414
+ * satisfies that is its own choice: one that names an environment per call
415
+ * adds its own address parameters to this tool's schema, one that binds a
416
+ * single environment when it builds the engine adds nothing. `false` marks
417
+ * an engine-independent tool — there is no environment to name.
418
+ */
419
+ readonly requiresAddress: boolean;
342
420
  readonly annotations: ToolAnnotations;
343
421
  /**
344
422
  * Returns plain projected data (the `Projected*` shapes) — hosts own
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { WORKFLOW_TOOLS, registerWorkflowTools, toolInputJsonSchema, workflowAddressFromInput } from "./_chunks-es/index.js";
1
+ import { LIST_WORKFLOW_TAGS_DESCRIPTION, LIST_WORKFLOW_TAGS_TOOL_NAME, WORKFLOW_TOOLS, deployWorkflowDefinitionTool, diagnoseWorkflowTool, fireActionTool, getWorkflowAuthoringGuideTool, getWorkflowDefinitionTool, getWorkflowStateTool, listWorkflowDefinitionsTool, listWorkflowInstancesTool, registerWorkflowTools, startWorkflowTool, toolInputJsonSchema, validateWorkflowDefinitionTool, workflowAddressFromInput } from "./_chunks-es/index.js";
2
2
 
3
- export { WORKFLOW_TOOLS, registerWorkflowTools, toolInputJsonSchema, workflowAddressFromInput };
3
+ export { LIST_WORKFLOW_TAGS_DESCRIPTION, LIST_WORKFLOW_TAGS_TOOL_NAME, WORKFLOW_TOOLS, deployWorkflowDefinitionTool, diagnoseWorkflowTool, fireActionTool, getWorkflowAuthoringGuideTool, getWorkflowDefinitionTool, getWorkflowStateTool, listWorkflowDefinitionsTool, listWorkflowInstancesTool, registerWorkflowTools, startWorkflowTool, toolInputJsonSchema, validateWorkflowDefinitionTool, workflowAddressFromInput };
package/dist/stdio.js CHANGED
@@ -2,13 +2,13 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
 
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
 
5
- import { ENGINE_API_VERSION, clientConfigFromResource, resourceGdr, createEngine, datasetResourceParts, EXECUTION_KINDS } from "@sanity/workflow-engine";
5
+ import { ENGINE_API_VERSION, clientConfigFromResource, resourceGdr, createEngine, deployedTagsGroq, parseResourceGdr, datasetResourceParts, EXECUTION_KINDS } from "@sanity/workflow-engine";
6
6
 
7
- import { registerWorkflowTools, workflowAddressFromInput, createMcpTelemetry } from "./_chunks-es/index.js";
7
+ import { LIST_WORKFLOW_TAGS_TOOL_NAME, workflowAddressFields, LIST_WORKFLOW_TAGS_DESCRIPTION, withToolTelemetry, registerWorkflowTools, workflowAddressFromInput, createMcpTelemetry } from "./_chunks-es/index.js";
8
8
 
9
9
  import { createClient } from "@sanity/client";
10
10
 
11
- var version = "0.24.0", packageJson = {
11
+ var version = "0.25.0", packageJson = {
12
12
  version: version
13
13
  };
14
14
 
@@ -54,6 +54,41 @@ function requireEnv(env, name) {
54
54
  return value;
55
55
  }
56
56
 
57
+ const readDeployedTags = ({resource: resource, token: token, apiHost: apiHost}) => clientForResource({
58
+ resource: resource,
59
+ token: token,
60
+ apiHost: apiHost
61
+ }).fetch(deployedTagsGroq(), {}, {
62
+ tag: "definition.tags"
63
+ });
64
+
65
+ function registerListWorkflowTagsTool(server, {token: token, apiHost: apiHost, readTags: readTags = readDeployedTags, telemetry: telemetry, onResource: onResource}) {
66
+ server.registerTool(LIST_WORKFLOW_TAGS_TOOL_NAME, {
67
+ description: LIST_WORKFLOW_TAGS_DESCRIPTION,
68
+ inputSchema: {
69
+ workflow_resource: workflowAddressFields.workflow_resource
70
+ },
71
+ annotations: {
72
+ readOnlyHint: !0
73
+ }
74
+ }, args => withToolTelemetry({
75
+ tool: LIST_WORKFLOW_TAGS_TOOL_NAME,
76
+ input: args,
77
+ ...telemetry !== void 0 ? {
78
+ telemetry: telemetry
79
+ } : {}
80
+ }, async () => {
81
+ const resource = parseResourceGdr(args.workflow_resource);
82
+ return onResource?.(resource), {
83
+ tags: await readTags({
84
+ resource: resource,
85
+ token: token,
86
+ apiHost: apiHost
87
+ })
88
+ };
89
+ }));
90
+ }
91
+
57
92
  async function runStdioServer() {
58
93
  const token = requireEnv(process.env, "SANITY_AUTH_TOKEN"), apiHost = process.env.SANITY_API_HOST ?? "https://api.sanity.io";
59
94
  process.stderr.write(`workflow-mcp MCP starting against ${apiHost} (org-authed; workflow environments are addressed per tool call)\n`);
@@ -66,12 +101,12 @@ async function runStdioServer() {
66
101
  if (telemetry === void 0) throw new Error("workflow-mcp: telemetry trace before any environment was addressed");
67
102
  return telemetry.logger.trace(event, context);
68
103
  }
69
- }, initTelemetry = address => {
70
- if (telemetry !== void 0 || address.workflowResource.type !== "dataset") return;
71
- const {projectId: projectId, dataset: dataset} = datasetResourceParts(address.workflowResource.id);
104
+ }, initTelemetry = resource => {
105
+ if (telemetry !== void 0 || resource.type !== "dataset") return;
106
+ const {projectId: projectId, dataset: dataset} = datasetResourceParts(resource.id);
72
107
  telemetry = createMcpTelemetry({
73
108
  client: clientForResource({
74
- resource: address.workflowResource,
109
+ resource: resource,
75
110
  token: token,
76
111
  apiHost: apiHost
77
112
  }),
@@ -94,11 +129,16 @@ async function runStdioServer() {
94
129
  });
95
130
  registerWorkflowTools(server, (_extra, input) => {
96
131
  const address = workflowAddressFromInput(input);
97
- return initTelemetry(address), {
132
+ return initTelemetry(address.workflowResource), {
98
133
  engine: engineFor(address)
99
134
  };
100
135
  }, {
101
136
  telemetry: logger
137
+ }), registerListWorkflowTagsTool(server, {
138
+ token: token,
139
+ apiHost: apiHost,
140
+ telemetry: logger,
141
+ onResource: initTelemetry
102
142
  });
103
143
  const FLUSH_DEADLINE_MS = 3e3;
104
144
  let shuttingDown = !1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/workflow-mcp",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "MCP server exposing Sanity workflow tools to agents — operate running workflow instances and author new definitions.",
5
5
  "keywords": [
6
6
  "agent",
@@ -52,21 +52,24 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@modelcontextprotocol/sdk": "^1.29.0",
56
55
  "@sanity/client": "^7.22.1",
57
56
  "@sanity/telemetry": "^1.1.0",
58
- "zod": "^4.4.3"
57
+ "zod-to-json-schema": "^3.25.2"
59
58
  },
60
59
  "devDependencies": {
60
+ "@modelcontextprotocol/sdk": "^1.29.0",
61
61
  "@sanity/pkg-utils": "^10.5.2",
62
62
  "@types/node": "^24.12.4",
63
63
  "vitest": "^4.1.8",
64
- "@sanity/workflow-engine": "0.24.0",
65
- "@sanity/workflow-engine-test": "0.24.0",
66
- "@sanity/workflow-examples": "0.10.3"
64
+ "zod": "^4.4.3",
65
+ "@sanity/workflow-engine": "0.25.0",
66
+ "@sanity/workflow-engine-test": "0.25.0",
67
+ "@sanity/workflow-examples": "0.10.4"
67
68
  },
68
69
  "peerDependencies": {
69
- "@sanity/workflow-engine": "0.24.0"
70
+ "@modelcontextprotocol/sdk": "^1.29.0",
71
+ "zod": "^3.25.28 || ^4",
72
+ "@sanity/workflow-engine": "0.25.0"
70
73
  },
71
74
  "engines": {
72
75
  "node": ">=20"