/preview
MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification.
$ npx -y skills add windmill-labs/windmill --skill preview --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/preview
Context preview
The summary Claude sees to decide when to auto-load this skill.
MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification.
SKILL.md
preview.SKILL.mdname: preview
description: MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification.
Windmill Preview Workflow
Use this skill any time the user wants to **see**, **open**, **navigate to**, **visualize**, or **preview** a flow, script, or app — and any time you've just finished writing one and want to offer visual verification.
The Windmill dev page renders the flow graph / script editor, lets the user step through steps, and live-reloads on every save. It runs locally via `wmill dev` and is reached on a localhost port.
Two independent decisions
1. Mode: proxy or direct?
`wmill dev` runs in two modes; pick by asking what kind of URL whatever will display the preview needs.
- **Proxy** (`--proxy-port <port>`) — exposes the dev page on `http://localhost:<port>/`. Use it when the embedder you'll hand the URL to **only accepts localhost URLs** (most in-IDE / in-chat preview embedders do, because they sandbox cross-origin loads).
- **Direct** (default) — the user's browser loads the dev page from the remote workspace's HTTPS URL; the local `wmill dev` only runs the WebSocket back-channel for live reload. Use it when the URL will be opened in a regular browser tab.
Default to **direct** unless you have a specific embedder that needs localhost.
2. Who starts the server?
- **You start it** in the background. Spawn `wmill dev …` (or `wmill app dev …`) yourself, capture the URL it prints, do whatever's next (open a tab, hand the URL to an embedder).
- **The runtime starts it from `.claude/launch.json`.** Some runtimes (currently the Claude Desktop / Claude Code MCP preview integration — tools prefixed with `mcp__Claude_Preview__`) can read a `launch.json` configuration and launch the dev server on demand when you invoke their preview tool. **Only take this path if you actually have such a tool** — otherwise nothing reads the file and `wmill dev` never starts.
The two decisions compose. The common cases:
| Embedder | Needs localhost? | launch.json runtime? | What to do | |---|---|---|---| | Regular browser tab | No | n/a | Direct mode, you start it, give URL to user | | IDE / chat preview pane that takes any URL | No | No | Direct mode, you start it, point the embedder at the printed URL | | IDE / chat preview pane that only accepts localhost | Yes | No | Proxy mode, you start it, point the embedder at `http://localhost:<port>/` | | Claude Desktop / Code MCP preview | Yes | Yes | Proxy mode, write a `launch.json` entry, invoke the MCP tool |
Never start the proxy "just in case" — it adds the localhost hop for no benefit when no embedder needs it.
Starting the server yourself
Use this when no `launch.json`-aware runtime is available, regardless of mode.
For flows / scripts:
# Direct mode — gives you the remote dev-page URL
wmill dev --path <wmill_path> --no-open
# Proxy mode — gives you a localhost URL that 302s to the remote dev page
wmill dev --proxy-port 4000 --path <wmill_path> --no-open
For apps:
cd <app_path>__raw_app && wmill app dev --no-open --port 4000
Each command prints the URL on stdout. Line shapes differ:
- `wmill dev --no-open` (direct) prints `Go to <url>` with the full remote URL (workspace, token, path baked in).
- `wmill dev --proxy-port` prints `Dev proxy listening on http://localhost:<port>` — the URL to hand to an embedder is `http://localhost:<port>/`.
- `wmill app dev --no-open` prints `🚀 Dev server running at <url>` — the local app server.
Capture the URL with a loose match (the first `https?://…` token after startup) and either hand it to your embedder or relay it to the user: *"Preview is running — open `<url>` in your browser."* Don't construct the URL yourself; you don't have the workspace ID or auth token.
These commands are long-running — start them in the background, don't block waiting.
Letting `launch.json` start the server (Claude Desktop / Code MCP only)
Take this path when **and only when** an `mcp__Claude_Preview__*` MCP tool is exposed in your tool list. Skip it otherwise — without an MCP tool reading the file, `wmill dev` never starts.
**Each flow / script / app gets its own named entry** in the user's `.claude/launch.json` so multiple previews coexist without colliding — each entry pins a different port + path. Never reuse a generic "windmill" entry for different targets.
Step 1 — Reuse or add a per-target entry in `.claude/launch.json`
Convention: name the entry `windmill: <wmill_path>` (e.g. `windmill: f/test/my_flow`).
- **Entry already exists** → reuse it; note its `port` for the next step.
- **Not there** → add one. Pick a port not already taken by another entry (start at 4000 and bump). Shape:
For flows / scripts:
{
"name": "windmill: f/test/my_flow",
"runtimeExecutable": "bash",
"runtimeArgs": ["-c", "wmill dev --proxy-port ${PORT:-4000} --path f/test/my_flow --no-open"],
"port": 4000,
"autoPort": true
}For apps (`*__raw_app/`), `wmill app dev` is the equivalent — runs from the app folder, no `--path`:
{
"name": "windmill: f/test/my_app",
"runtimeExecutable": "bash",
"runtimeArgs": ["-c", "cd f/test/my_app__raw_app && wmill app dev --no-open --port ${PORT:-4001}"],
"port": 4001,
"autoPort": true
}If `.claude/launch.json` doesn't exist yet, create it with the standard shell `{ "version": "0.0.1", "configurations": [...] }`.
Step 2 — Invoke the MCP preview tool
Point it at the entry you just added/found. Use `http://localhost:<port>/` as the URL — the proxy's redirect at `/` is what appends the workspace ID, the auth token, and the path. Do **NOT** construct a `/dev?...` URL yourself.
The MCP tool launches the configuration on demand, so you don't need to start the `wmill dev` process manually.
Non-visual alternative
If the user wants a
Read more
name: preview description: MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification.
Windmill Preview Workflow
Use this skill any time the user wants to **see**, **open**, **navigate to**, **visualize**, or **preview** a flow, script, or app — and any time you've just finished writing one and want to offer visual verification.
The Windmill dev page renders the flow graph / script editor, lets the user step through steps, and live-reloads on every save. It runs locally via `wmill dev` and is reached on a localhost port.
Two independent decisions
1. Mode: proxy or direct?
`wmill dev` runs in two modes; pick by asking what kind of URL whatever will display the preview needs.
- **Proxy** (`--proxy-port <port>`) — exposes the dev page on `http://localhost:<port>/`. Use it when the embedder you'll hand the URL to **only accepts localhost URLs** (most in-IDE / in-chat preview embedders do, because they sandbox cross-origin loads).
- **Direct** (default) — the user's browser loads the dev page from the remote workspace's HTTPS URL; the local `wmill dev` only runs the WebSocket back-channel for live reload. Use it when the URL will be opened in a regular browser tab.
Default to **direct** unless you have a specific embedder that needs localhost.
2. Who starts the server?
- **You start it** in the background. Spawn `wmill dev …` (or `wmill app dev …`) yourself, capture the URL it prints, do whatever's next (open a tab, hand the URL to an embedder).
- **The runtime starts it from `.claude/launch.json`.** Some runtimes (currently the Claude Desktop / Claude Code MCP preview integration — tools prefixed with `mcp__Claude_Preview__`) can read a `launch.json` configuration and launch the dev server on demand when you invoke their preview tool. **Only take this path if you actually have such a tool** — otherwise nothing reads the file and `wmill dev` never starts.
The two decisions compose. The common cases:
| Embedder | Needs localhost? | launch.json runtime? | What to do | |---|---|---|---| | Regular browser tab | No | n/a | Direct mode, you start it, give URL to user | | IDE / chat preview pane that takes any URL | No | No | Direct mode, you start it, point the embedder at the printed URL | | IDE / chat preview pane that only accepts localhost | Yes | No | Proxy mode, you start it, point the embedder at `http://localhost:<port>/` | | Claude Desktop / Code MCP preview | Yes | Yes | Proxy mode, write a `launch.json` entry, invoke the MCP tool |
Never start the proxy "just in case" — it adds the localhost hop for no benefit when no embedder needs it.
Starting the server yourself
Use this when no `launch.json`-aware runtime is available, regardless of mode.
For flows / scripts:
# Direct mode — gives you the remote dev-page URL wmill dev --path <wmill_path> --no-open # Proxy mode — gives you a localhost URL that 302s to the remote dev page wmill dev --proxy-port 4000 --path <wmill_path> --no-open
For apps:
cd <app_path>__raw_app && wmill app dev --no-open --port 4000
Each command prints the URL on stdout. Line shapes differ:
- `wmill dev --no-open` (direct) prints `Go to <url>` with the full remote URL (workspace, token, path baked in).
- `wmill dev --proxy-port` prints `Dev proxy listening on http://localhost:<port>` — the URL to hand to an embedder is `http://localhost:<port>/`.
- `wmill app dev --no-open` prints `🚀 Dev server running at <url>` — the local app server.
Capture the URL with a loose match (the first `https?://…` token after startup) and either hand it to your embedder or relay it to the user: *"Preview is running — open `<url>` in your browser."* Don't construct the URL yourself; you don't have the workspace ID or auth token.
These commands are long-running — start them in the background, don't block waiting.
Letting `launch.json` start the server (Claude Desktop / Code MCP only)
Take this path when **and only when** an `mcp__Claude_Preview__*` MCP tool is exposed in your tool list. Skip it otherwise — without an MCP tool reading the file, `wmill dev` never starts.
**Each flow / script / app gets its own named entry** in the user's `.claude/launch.json` so multiple previews coexist without colliding — each entry pins a different port + path. Never reuse a generic "windmill" entry for different targets.
Step 1 — Reuse or add a per-target entry in `.claude/launch.json`
Convention: name the entry `windmill: <wmill_path>` (e.g. `windmill: f/test/my_flow`).
- **Entry already exists** → reuse it; note its `port` for the next step.
- **Not there** → add one. Pick a port not already taken by another entry (start at 4000 and bump). Shape:
For flows / scripts:
{
"name": "windmill: f/test/my_flow",
"runtimeExecutable": "bash",
"runtimeArgs": ["-c", "wmill dev --proxy-port ${PORT:-4000} --path f/test/my_flow --no-open"],
"port": 4000,
"autoPort": true
}For apps (`*__raw_app/`), `wmill app dev` is the equivalent — runs from the app folder, no `--path`:
{
"name": "windmill: f/test/my_app",
"runtimeExecutable": "bash",
"runtimeArgs": ["-c", "cd f/test/my_app__raw_app && wmill app dev --no-open --port ${PORT:-4001}"],
"port": 4001,
"autoPort": true
}If `.claude/launch.json` doesn't exist yet, create it with the standard shell `{ "version": "0.0.1", "configurations": [...] }`.
Step 2 — Invoke the MCP preview tool
Point it at the entry you just added/found. Use `http://localhost:<port>/` as the URL — the proxy's redirect at `/` is what appends the workspace ID, the auth token, and the path. Do **NOT** construct a `/dev?...` URL yourself.
The MCP tool launches the configuration on demand, so you don't need to start the `wmill dev` process manually.
Non-visual alternative
If the user wants a
Windmill is fully open-sourced (AGPLv3) and Windmill Labs offers dedicated instances and commercial support and licenses.
Repo: windmill-labs/windmill
Other skills on windmill.
- /adding-a-trigger
../../../.agents/skills/adding-a-trigger/SKILL.md
Open skill - /ai-chat
../../../.agents/skills/ai-chat/SKILL.md
Open skill - /ai-evals
../../../.agents/skills/ai-evals/SKILL.md
Open skill - /commit
../../../.agents/skills/commit/SKILL.md
Open skill - /local-review-codex
../../../.agents/skills/local-review-codex/SKILL.md
Open skill - /local-review
../../../.agents/skills/local-review/SKILL.md
Open skill

