Workflows MCP tools reference

Every tool the Workflows MCP server exposes, with inputs, results, and errors, generated from @sanity/workflow-mcp 0.37, plus the embedding API.

This page lists every tool @sanity/workflow-mcp 0.37 exposes to an agent, with its inputs, result, and errors, plus the API for embedding the tools in another MCP server. It is generated from the package's tool definitions. To install the server and connect a client, follow Connect an agent over MCP.

Workflow environment address

The server has no default environment. Every tool that reads or writes workflow data takes the address of one deployment, the workflowResource and partition of a deployment in your sanity.workflow.ts. A deployment that omits partition uses default. workflows_list_partitions takes only workflow_resource, and the authoring guide and validation tools take no address.

  • workflow_resource

    string, required

    The resource holding the workflow documents, as a resource GDR <type>:<id>: dataset:<projectId>.<dataset>, canvas:<id>, media-library:<id>, or dashboard:<id>. A malformed value fails with Invalid resource GDR "<value>": expected "<type>:<id>" with no document part.

  • partition

    string, required

    The deployment partition within that resource. Lowercase letters, digits, and dashes. Call workflows_list_partitions to discover the partitions with deployed definitions, and confirm the intended one before calling another tool. A missing value fails with Use "partition" to address the workflow partition; "tag" is not supported. A tag key fails with [contract-violation] "tag" is not supported. Replace tag: "dev" with partition: "dev".

{
  "workflow_resource": "dataset:PROJECT_ID.DATASET_NAME",
  "partition": "dev"
}

Results and errors

A successful call returns one text content item holding the result as indented JSON. A failed call returns isError: true with one text item rendered by workflowErrorText: an engine error leads with its stable [kind] (for example [instance-not-found], [contract-violation], [reader-model-acknowledgement]), and an input that fails the schema lists every problem as ✖ <message> followed by → at <path>, prefixed with the tool name. Results that carry titles, descriptions, conditions, or subject titles mark them as untrusted authored data in the tool description.

Discovery and operations

  • workflows_list_partitions(workflow_resource): read

    Lists the partitions that have deployed definitions in workflow_resource, sorted ascending. A partition with nothing deployed does not appear, and an empty list means the resource holds no deployed workflows.

    Takes only workflow_resource. Read-only. Result: {partitions: string[]}. The stdio server registers it; it is not in WORKFLOW_TOOLS.

    Parameters

    • workflow_resource

      string

      The resource to list partitions for.

  • workflows_list_definitions(workflow_resource, partition): read

    The catalog of deployed workflow types, latest version per name. Each entry reports startable (false for child workflows that only run under a parent) and startKind: interactive (a person starts runs from a picker) or autonomous (a system starts runs in reaction to a document). startKind is a classification, not a restriction.

    Requires the address. Read-only. Result: {definitions: {name, title, description?, version, startable, startKind}[]}.

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

  • workflows_get_definition(workflow_resource, partition, definition, version): read

    One deployed definition's full content, by name, defaulting to the latest version. The returned definition is the stored form with the document envelope stripped, and is valid input for workflows_validate_definition and workflows_deploy_definition as-is: to edit a workflow, read it, modify it, validate, and deploy the next version.

    Requires the address. Read-only. Result: {name, version, definition}.

    Error, unknown definition: no deployed definition "nope" in this workflow environment — workflows_list_definitions shows what is deployed

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • definition

      string (non-empty)

      The definition's name (as listed by workflows_list_definitions).

    • version

      integer (minimum 1)

      A specific deployed version to read. Defaults to the latest.

  • workflows_list_instances(workflow_resource, partition, definition, document, include_completed, assignment_user_id, assignment_roles, assignment_states, limit, cursor): read

    Lists instances in the addressed partition, most recently changed first, with optional definition, document, and include_completed filters. Assignment inputs filter to one person and add per-instance counts of active activities in the current stage: held (assigned directly to the person), routed (offered through one of their roles with no person assigned), and unrouted (no person or role selected). Counts do not promise that an action is available. Defensive document verification can leave a page underfilled. When has_more is true, call again with the same filters and next_cursor as cursor.

    Requires the address. Read-only. Result: {instances: {instanceId, definition, workflowTitle?, currentStage, currentStageTitle?, lastChangedAt, done, subject?: {ref, title?}, assignment?: {unrouted, routed, held}}[], has_more, next_cursor?}.

    Error, assignment filters without a user: workflows_list_instances: assignment_roles and assignment_states require assignment_user_id

    Error, malformed cursor: workflows_list_instances: invalid cursor

    Error, limit out of range: workflows_list_instances: ✖ Number must be less than or equal to 100

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • definition

      string

      Restrict to instances of this workflow definition, by its name (for example 'article-review').

    • document

      string

      Only instances that reference this document, the workflow's subject or any other doc its fields point at, as a resource-qualified GDR URI (for example "dataset:proj:ds:article-1"). Use this to answer "which workflows are about this document?".

    • include_completed

      boolean (default false)

      true includes completed/aborted instances. Defaults to false; in-flight instances only.

    • assignment_user_id

      string (non-empty)

      Account-global user id for viewer-scoped assignment filtering and per-instance unrouted/routed/held counts.

    • assignment_roles

      string[] (non-empty items)

      Literal project roles held by assignment_user_id. Role aliases do not change inbox ownership.

    • assignment_states

      ('unrouted' | 'routed' | 'held')[] (at least 1 item)

      Assignment states to include: unrouted work, routed work offered through assignment_roles, or work held directly by assignment_user_id.

    • limit

      integer (1 to 100, default 25)

      Results per page, from 1 to 100. Defaults to 25.

    • cursor

      string

      Opaque next_cursor from the previous response. Reuse the same filters and workflow environment when continuing.

  • workflows_get_state(workflow_resource, partition, instance_id): read

    Everything actionable about one instance: current stage, subject, a workflow-level autonomy narrative, recent history, and each in-scope activity on the current stage. Per activity: classification (interactive, autonomous, off-system, or hybrid), a causal completesWithoutCaller verdict (yes, no, or conditional) with narrated waitsOn lines when it is not yes, invocable actions with an allowed or disabled verdict and their declared params, and automations the engine fires on its own. Activities and actions scoped out for this visit or caller are absent.

    Requires the address. Read-only. Result: {instanceId, definition, workflowTitle?, currentStage, currentStageTitle?, done, subject?, activities, autonomy, recentHistory}.

    Error, unknown instance: [instance-not-found] Workflow instance dev.wf-instance.missing not found

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • instance_id

      string (non-empty)

      The workflow instance id.

  • workflows_diagnose(workflow_resource, partition, instance_id): read

    Explains why an instance is or is not progressing. state is progressing, waiting, blocked, completed, aborted, or stuck. Waiting distinguishes an action available to the caller, a manual action that caller cannot fire, and automation. A stuck instance adds a cause and remediations; remediations are advisory and none can run through this server.

    Requires the address. Read-only. Result: {instanceId, state, summary, cause?, explanations?, remediations}.

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • instance_id

      string (non-empty)

      The workflow instance id.

  • workflows_start(workflow_resource, partition, definition, version, initial_fields, instance_id): write

    Starts a deployed definition. Only definitions with startable: true start here; child workflows are spawn-only. Supply input-sourced field values in initial_fields. Every ordered start requirement must pass. The engine's cascade has already run when the result returns, so the instance can be past its initial stage. Pass the same instance_id to retry a failed start without creating a duplicate; a start whose first auto-advance failed still returns the instance, with a startNotSettled note.

    Requires the address. Writes; not idempotent. Result: Same shape as workflows_get_state, plus startNotSettled?.

    Error, unknown definition: no deployed definition "nope" in this workflow environment — workflows_list_definitions shows what is deployed

    Error, missing definition: workflows_start: ✖ Required

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • definition

      string (non-empty)

      The workflow definition name to start (as listed by workflows_list_definitions).

    • version

      integer (minimum 1)

      The deployed definition version to start from. Defaults to the highest.

    • initial_fields

      object

      Values for the workflow's input-sourced field entries, keyed by field name (for example {"subject": {"id": "dataset:proj:ds:article-1", "type": "article"}}). doc.ref values take an object with a GDR id and doc type. workflows_get_definition shows a workflow's declared fields; only input-sourced entries accept a value here.

    • instance_id

      string (non-empty)

      Start under this instance id; for retries. The id is the start's idempotency key: pass the SAME id when retrying a start that errored and the engine resumes that start instead of creating a duplicate instance (an already-settled start replays as a no-op). A failed start names the id to retry with in its error message. Omit to mint a fresh id.

  • workflows_fire_action(workflow_resource, partition, instance_id, activity, action, params): write

    The instance write: fires an invocable action on a current-stage activity, exactly as an editor would, with values for the action's declared params. Pick the activity and action from workflows_get_state. Cascade-fired triggers are listed as automations and this tool rejects them. Auto-transitions that become eligible cascade in the same call. Not idempotent: a second call can land elsewhere.

    Requires the address. Writes; not idempotent. Result: Same shape as workflows_get_state.

    Error, activity not on the current stage: [contract-violation] Activity "write" not found in current stage "review" of article-review

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • instance_id

      string (non-empty)

      The workflow instance id.

    • activity

      string (non-empty)

      The id of the activity on the current stage. Must be one of the activities returned by workflows_get_state.

    • action

      string (non-empty)

      The id of the action on that activity. Must be one of the actions listed as allowed=true on the activity.

    • params

      object

      Values for the action's declared params, keyed by param name (for example {"note": "Unsupported claim in paragraph 3."}). Required when the action declares a required param; workflows_get_state lists each action's params and whether they are required. The shape is per-action, so this is a free-form object; the engine validates the supplied values against the action's declared params and rejects the call if a required one is missing.

Authoring

  • workflows_get_authoring_guide(): read

    The DSL guide an agent reads before writing a definition: the definition shape, GROQ condition built-ins, sugars, the rules the validator enforces, and two worked JSON examples.

    Takes no address and never reads the Content Lake. Read-only. Result: The guide, as one Markdown string.

  • workflows_validate_definition(definitions): read

    Runs structure, cross-field, and GROQ syntax checks on a definitions array without reading the Content Lake. A single workflow is a one-element array; validate a parent and its children together. Each result is the desugared definition that would deploy, or a path-prefixed list of every problem. Deploy also checks duplicate names, spawn dependencies, resource bindings, project roles, and the reader-model acknowledgement, so a valid result does not guarantee a deploy succeeds. sanity-workflows definitions validate <file...> --json prints the same report.

    Takes no address and never reads the Content Lake. Read-only. Result: {valid, results: ({valid: true, definition} | {valid: false, error})[]}.

    Error, empty array: workflows_validate_definition: ✖ Array must contain at least 1 element(s)

    Parameters

    • definitions

      object[] (at least 1 item)

      The workflow definitions to validate, as JSON objects in authoring shape. See workflows_get_authoring_guide for the shape and examples.

  • workflows_deploy_definition(workflow_resource, partition, definitions, expectedMinReaderModel): write

    Publishes definitions into the addressed partition. Pass a parent and the children it spawns in one call; children deploy first. Deploys are create-only and content-addressed: content identical to the latest version returns unchanged, any change returns created with the next version, a new name starts at version 1, and running instances keep the version they started under. Runs the same checks as workflows_validate_definition but throws instead of returning the problem list.

    Requires the address. Writes; idempotent. Result: {results: {name, version, status}[], deployId}.

    Error, invalid definition: definitions[0] ("x"): defineWorkflow("x") failed validation (3 issues):

    Error, acknowledgement below the floor: [reader-model-acknowledgement] Deployment acknowledges reader model 4; the submitted definitions require at least 10, and this writer supports acknowledgements through 11.

    Parameters

    • workflow_resource

      string

      The workflow resource GDR, for example dataset:PROJECT_ID.DATASET_NAME. See the address.

    • partition

      string

      The deployment partition, for example dev. See the address.

    • definitions

      object[] (at least 1 item)

      The workflow definitions to deploy, as JSON objects in authoring shape; the same values workflows_validate_definition takes. A single workflow is a one-element array; a parent and its child workflows belong in one call. See workflows_get_authoring_guide for the shape and examples.

    • expectedMinReaderModel

      integer (minimum 0)

      Highest reader model already verified across every runtime sharing this workflow resource. Omit to retain the model-4 baseline. Definitions with role-constrained assignment fields require model 8; singular assignment fields require model 9. Pass the highest applicable floor only after upgrading all shared Studio, CLI, MCP, Function, and other runtimes. Definitions with required subject, doc.ref, or doc.refs fields need 10, and an abort block needs 11; see Reader-model acknowledgement and follow Upgrade Workflows packages.

Embedding API

Exports for hosts that add the Workflows tools to their own MCP server. registerWorkflowTools is the bundled path; a host with its own registration, error handling, or result envelopes iterates WORKFLOW_TOOLS instead. The library entry (.) contains no MCP runtime code; the ./stdio entry exports runStdioServer(), the server the workflow-mcp binary runs, and also loads from CommonJS through its require condition.

  • registerWorkflowTools(server, getContext, options?)(): void

    Registers every WORKFLOW_TOOLS entry on an McpServer. Tools with requiresAddress get workflow_resource and partition merged into their schema, and a tag argument is rejected. getContext(extra, input) returns {engine} (or a promise of it) for the requested environment; it runs only for tools that need an engine, never for the authoring guide or validation. Thrown errors become isError results through workflowErrorText. options.telemetry records one adoption event per call. Partition discovery is not registered; to offer it, register your own tool with LIST_WORKFLOW_PARTITIONS_TOOL_NAME and LIST_WORKFLOW_PARTITIONS_DESCRIPTION.

  • workflowAddressFromInput(input)(): WorkflowEnvironmentAddress

    Reads {workflowResource, partition} from a tool call's input, ignoring other keys. Throws Invalid workflow environment address: with every problem listed, or ContractViolationError for a tag key.

  • workflowClientConfig({resource, token?, base})(): Base & WorkflowClientPolicy & WorkflowResourceAddressing

    Layers the engine's client policy over the host's own config (base; pass {} if none): keeps its requester, headers, and apiHost, then pins the engine API version, useCdn: false, request-tag prefix sanity.workflows-mcp, and the published perspective, and sets either projectId/dataset or resource for the target while removing the other addressing style.

  • createWorkflowEngine({address, client, executionContext?, telemetry?})(): Engine

    Creates an engine bound to one resource and partition, without caching; a long-lived host can cache engines itself. The client's token identifies the actor, so keep its authentication unchanged for the engine's lifetime. executionContext adds an advisory host label to history entries. Runtime field values may reference only the addressed workflow resource; to accept references to other resources, build the engine with createEngine from @sanity/workflow-engine and a resourceClients resolver, and return it from getContext.

  • createMcpSessionTelemetry({clientFor, denied, nodeEnv?, sessionId?})(): McpSessionTelemetry

    Opt-in telemetry for an embedding host; embedding the tools does not enable it. clientFor(resource) returns an authenticated client; denied: true sends nothing. Create one per MCP session, pass its logger to the engine factory and to registerWorkflowTools, and call bind(resource) from each tool call's address before logging. The first dataset binding owns the session; later calls do not retarget it. Logs before binding are dropped and traces before binding throw. Await flush() before end() when the session closes.

  • WORKFLOW_TOOLS(): readonly WorkflowToolDef[]

    Every tool definition in the order an agent should read them. Each has name, description, inputSchema (a raw zod/v3 shape), requiresAddress, annotations, and handler(context, input), which parses input itself and returns plain data. When requiresAddress is true, merge your host's environment parameters into the registered schema.

  • toolInputJsonSchema(def)(): ToolInputJsonSchema

    The JSON Schema for a definition's own inputs, for consumers that do not use Zod (for example an Anthropic Messages API input_schema). It excludes the address fields; add your own.

  • workflowErrorText(error)(): string

    The text a failed tool call should show: [<kind>] <message> for a WorkflowError, otherwise the message.

  • WORKFLOW_PARTITION_DESCRIPTION(): string

    The model-facing description to use verbatim for your partition parameter.

  • LIST_WORKFLOW_PARTITIONS_TOOL_NAME(): 'workflows_list_partitions'

    The name to register a partition-discovery tool under. WORKFLOW_PARTITION_DESCRIPTION tells the model to call it.

  • LIST_WORKFLOW_PARTITIONS_DESCRIPTION(): string

    The model-facing description to register verbatim for that tool.

Each wire tool also has a camel-case *Tool export: listWorkflowDefinitionsTool, getWorkflowDefinitionTool, listWorkflowInstancesTool, getWorkflowStateTool, diagnoseWorkflowTool, startWorkflowTool, fireActionTool, getWorkflowAuthoringGuideTool, validateWorkflowDefinitionTool, and deployWorkflowDefinitionTool. Result types are exported as ProjectedDefinitionSummary, ProjectedDefinition, ProjectedInstanceSummary, ProjectedInstanceState, ProjectedActivity, ProjectedActionVerdict, ProjectedAutomation, ProjectedHistoryEntry, ProjectedSubject, ProjectedDiagnosis, ValidateDefinitionResult, and ValidateDefinitionsResult. See TypeDoc for their fields.

Tool schemas are built with zod/v3, which both Zod 3 and Zod 4 ship. When you merge parameters into them, build those with zod/v3 too; a Zod 4 schema in the same object fails type checking. zod (^3.25.28 || ^4) and @modelcontextprotocol/sdk (^1.29.0) are peer dependencies the host provides.

Was this page helpful?

sanity.ioAll Systems Operational© Sanity 2026
Change site theme