mcpbeat Sign in

Migrating To Workflow SDK Agent Skill

Migrates Temporal, Inngest, Trigger.dev, and AWS Step Functions workflows to the Workflow SDK. Use when porting Activities, Workers, Signals, step.run(), step.waitForEvent(), Trigger.dev tasks / wait.forToken / triggerAndWait, ASL JSON state machines, Task/Choice/Wait/Parallel states, task tokens, or child workflows.

14k tokens
context cost
the whole folder, loaded on every use
15
files
instructions only
0
copies elsewhere
how many repositories repackaged it
2277
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/vercel/workflow --skill migrating-to-workflow-sdk

What comes with it

48 624 bytes besides the instruction
evals/README.md
evals/aws-task-token-parallel.md
evals/callback-url-default-response.md
evals/inngest-timeout-streaming.md
evals/non-vercel-runtime-branch.md
evals/temporal-signal-child-run.md
references/aws-step-functions.md
references/inngest.md
references/resume-routing.md
references/retries.md
references/runtime-targets.md
references/shared-patterns.md
references/temporal.md
references/trigger-dev.md

The instruction itself

10 sections, as written by the author

Migrating to the Workflow SDK

Use this skill when converting an existing orchestration system to the Workflow SDK.

Intake

  • Identify the source system:
  • Temporal
  • Inngest
  • Trigger.dev
  • AWS Step Functions
  • Identify the target runtime:
  • Managed hosting -> keep examples focused on start(), getRun(), hooks/webhooks, and route handlers.
  • Self-hosted -> also read references/runtime-targets.md and explicitly say the workflow/step code can stay the same, but deployment still needs a World implementation and startup bootstrap.
  • Extract the source constructs:
  • entrypoint
  • waits / timers
  • external callbacks / approvals
  • retries / failure handling
  • child workflows / fan-out
  • progress streaming
  • external side effects

Default migration rules

  • Put orchestration in "use workflow" functions.
  • Put side effects, SDK calls, DB calls, HTTP calls, and stream I/O in "use step" functions.
  • Use sleep() only in workflow context.
  • For Signals, step.waitForEvent(), and .waitForTaskToken, choose exactly one resume surface:
  • resume/internal -> createHook() + resumeHook() when the app resumes from server-side code with a deterministic business token.
  • resume/url/default -> createWebhook() when the external system needs a generated callback URL and the default 202 Accepted response is fine.
  • resume/url/manual -> createWebhook({ respondWith: 'manual' }) only when the prompt explicitly requires a custom response body, status, or headers.
  • If a callback-URL prompt does not specify response semantics, default to resume/url/default and make the assumption explicit in ## Open Questions.
  • Never pair createWebhook() with resumeHook(), and never pass token: to createWebhook().
  • Wrap start() and getRun() inside "use step" functions for child runs.
  • Use getStepMetadata().stepId as the idempotency key for external writes.
  • Use getWritable() in workflow context to obtain the stream, but interact with it (write, close) only inside "use step" functions.
  • Prefer rollback stacks for multi-step compensation.
  • Choose app-boundary syntax in this order:
  • If the prompt explicitly asks for framework-agnostic app-boundary code, use plain Request / Response even when a framework like Hono is named.
  • Otherwise, if the target framework is named, shape app-boundary examples to that framework.
  • Otherwise, keep examples framework-agnostic with Request / Response. Do not default to Next.js-only route signatures unless Next.js is explicitly named.

> Fast memory aid:

> - Callback URL + default ack -> createWebhook()

> - Callback URL + custom ack -> createWebhook({ respondWith: 'manual' })

> - Deterministic server-side resume -> createHook() + resumeHook()

Fast-path router

Load references/resume-routing.md when the source pauses for Signals, step.waitForEvent(), or .waitForTaskToken.

Fast defaults:

  • callback URL only -> resume/url/default
  • callback URL + explicit custom response -> resume/url/manual
  • deterministic server-side resume -> resume/internal
  • self-hosted -> add runtime/self-hosted
  • named framework -> add boundary/named-framework
  • explicit framework-agnostic request -> add boundary/framework-agnostic

Before drafting ## Migrated Code, write the selected route keys in ## Migration Plan.

Source references

  • Temporal -> references/temporal.md
  • Inngest -> references/inngest.md
  • Trigger.dev -> references/trigger-dev.md
  • AWS Step Functions -> references/aws-step-functions.md

Shared references

  • references/shared-patterns.md — reusable code templates for hooks, child workflows, idempotency, streaming, and rollback.
  • references/runtime-targets.md — Managed vs custom World guidance.
  • references/resume-routing.md — route-key selection, obligations, and exact ## Migration Plan shape.
  • references/retries.md — canonical retry mechanics: stepFn.maxRetries, RetryableError({ retryAfter }), FatalError.

Required output shape

Return the migration in this structure:

## Migration Plan
## Source -> Target Mapping
## Migrated Code
## App Boundary / Resume Endpoints
## Verification Checklist
## Open Questions

Verification checklist

Fail the draft if any of these are true:

  • [ ] ## Migration Plan omits Route keys
  • [ ] ## Migration Plan omits Why these route keys
  • [ ] ## Migration Plan lists route keys that do not match the prompt
  • [ ] ## Migration Plan lists required code obligations that do not match the selected route keys
  • [ ] Source-framework primitives remain in the migrated code
  • [ ] Side effects remain in workflow context
  • [ ] sleep() appears inside a step
  • [ ] Stream interaction (getWriter(), write(), close()) appears inside a workflow function
  • [ ] Child workflows call start() / getRun() directly from workflow context
  • [ ] External writes omit idempotency keys
  • [ ] Hooks/webhooks are missing where the source used signals, waitForEvent, or task tokens
  • [ ] A callback-URL flow uses createHook() + resumeHook() instead of createWebhook()
  • [ ] A resume/url/default or resume/url/manual migration invents a user-authored callback route or resumeWebhook() wrapper when webhook.url should be the only resume surface
  • [ ] createWebhook() is given a custom token or paired with resumeHook()

Validation note:

  • Reading webhook request data in workflow context is allowed. Only request.respondWith() is step-only.

Additional fail conditions:

  • resume/internal output omits resumeHook() in app-boundary code
  • resume/internal output omits a deterministic business token
  • resume/internal output emits createWebhook() or webhook.url
  • resume/url/default output does not pass webhook.url to the external system
  • resume/url/default output emits resumeHook(), respondWith: 'manual', or RequestWithResponse without a custom-response requirement in the prompt
  • resume/url/default output invents a user-authored callback route or resumeWebhook() wrapper when webhook.url is the intended resume surface
  • resume/url/manual output does not pass webhook.url to the external system
  • resume/url/manual output omits RequestWithResponse or await request.respondWith(...)
  • resume/url/manual output calls request.respondWith(...) outside a "use step" function
  • resume/url/manual output invents a user-authored callback route or resumeWebhook() wrapper when webhook.url is the intended resume surface
  • createWebhook() is paired with resumeHook()
  • self-hosted output omits World extends Queue, Streamer, Storage, startWorkflowWorld(), or the explicit note that the workflow and step code can stay the same while the app still needs a custom World
  • named-framework output mixes framework syntax with plain Request / Response app-boundary code without a framework-agnostic override

For concrete passing code, load:

  • references/shared-patterns.md -> ## Generated callback URL (default response)
  • references/shared-patterns.md -> ## Generated callback URL (manual response)
  • references/runtime-targets.md -> ## Self-hosted output block
  • references/aws-step-functions.md -> ## Combined recipe: callback URL on self-hosted Hono

Sample prompt

Migrate this Inngest workflow to the Workflow SDK.
It uses step.waitForEvent() with a timeout and step.realtime.publish().

Expected response shape:

## Migration Plan
## Source -> Target Mapping
## Migrated Code
## App Boundary / Resume Endpoints
## Verification Checklist
## Open Questions

Example references

Load a worked example only when the prompt needs concrete code:

  • references/shared-patterns.md -> ## Named-framework internal resume example (Hono)
  • references/shared-patterns.md -> ## Generated callback URL (default response)
  • references/shared-patterns.md -> ## Generated callback URL (manual response)
  • references/runtime-targets.md -> ## Self-hosted output block
  • references/aws-step-functions.md -> ## Combined recipe: callback URL on self-hosted Hono

Reject these counterexamples:

  • resume/url/default or resume/url/manual + user-authored callback route when webhook.url is the intended resume surface
  • createWebhook() paired with resumeHook()
  • named-framework app-boundary output mixed with plain Request / Response without a framework-agnostic override

Other skills for the same job

different authors, same section of the catalogue
MCP Builder
by anthropics
vendor ×13

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

30k tokens scripts
Changelog Generator
by frostant
×9

Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.

774 tokens
Finishing A Development Branch
by ZhanlinCui
×7

Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup

1k tokens
MCP Builder
by JayZeeDesign
×7

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

37k tokens scripts
Vercel React Native Skills
by vercel-labs
vendor ×6

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

39k tokens
Vercel React Best Practices
by ratacat
×5

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

34k tokens
Next Best Practices
by vercel-labs
vendor ×4

Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling

20k tokens
Using Git Worktrees
by ZhanlinCui
×4

Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification

1k tokens

How to use it

Copy the folder

Take vercel/migrating-to-workflow-sdk from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.