Webflow Cloud Apps
Use data_apps_tool to create GitHub-source apps, answer operational questions,
and manage environments for Webflow Cloud apps. Start from the user's outcome,
gather only the evidence needed, and distinguish observations from conclusions.
Use the webflow-cli:cloud skill when the task requires CLI/local-source app
creation or deployment, or creating or updating environment variables.
Client-side build output is not sent to Webflow and cannot be recovered through
MCP.
Instructions
1. Establish scope
- Call
webflow_guide_tool before any other Webflow MCP tool. The live guide
and action schemas are authoritative for current arguments and responses.
- Use Webflow MCP tools for Webflow operations except the explicit CLI handoff
for environment-variable values. Never call Webflow APIs directly.
- Include the required
context parameter in every tool call. Write 15-25
words in third-person perspective.
- Route by the capability the task requires:
- Use
data_apps_tool to create GitHub-source apps; inspect apps,
environments, domains, deployment records, logs, and variable metadata;
manage GitHub sources and environments; and enqueue GitHub deployments.
- Use
data_variable_tool for Designer color, size, font, and CSS variables.
- Use
webflow-cli:cloud for CLI/local-source apps, local builds and
deployments, or creating and updating environment-variable values.
- If
data_apps_tool is unavailable, report that the Cloud Apps MCP
capability is not enabled. Do not bypass it with a direct API request.
Never ask the user to paste an environment-variable value or secret into chat.
For a create or update, delegate to webflow-cli:cloud and require a hidden
prompt, stdin, or protected file. Never pass a secret as a positional argument.
2. Resolve the target
Discover identifiers in this order:
list_apps -> app_id
list_environments(app_id) -> env_id
list_deployments(app_id, env_id) -> deployment_id
App names are unique only within a site, so resolve a named app with
site_id + name. If multiple resources match, present distinguishing metadata
and require the user to select one before any mutation. Use the live guide for
filter, pagination, cursor, and action-batching mechanics.
3. Follow the matching user story
Create a GitHub-source app
- Establish the app name, canonical GitHub repository URL, branch, optional
description, and whether it is standalone or attached to an existing site.
- For a site-attached app, resolve the site ID. Omit
site_id for standalone.
- Apply the mount contract before previewing:
- A standalone app always mounts at
/; omit mount or use /.
- A site-attached app defaults to
/app, rejects /, and requires a valid
non-root mount when overriding the default.
- Explain that standalone creation requires a workspace-scoped user token.
Webflow derives the GitHub installation and validates repository access; do
not request an installation ID.
- Call
create_app with its default dry run. Show the repository, branch,
attachment, site when applicable, mount, and initial-deployment attempt.
- Require
confirm. Immediately after confirmation and before execution,
record the start time and generate one stable idempotency_key; execute with
dry_run: false, then record the completion time. Reuse that key only for
exact retries of this creation.
- Treat creation and initial deployment as separate outcomes. A returned app
means creation succeeded even if
deployStatus is skipped or failed.
For triggered, inspect the environment and deployment; for skipped, check
the branch or push a commit; for failed, preserve the app and inspect or
retry deployment separately.
- If the app or outcome is unreadable, reconcile before retrying:
- For a site-attached app, collect candidates with
site_id + name; for a
standalone app, collect candidates by name.
- In both cases, compare each candidate's name,
sourceUrl, and createdAt
with the requested repository and recorded execution window.
- Continue to environments and deployments only when exactly one candidate
matches. Do not retry while the created app remains ambiguous.
- Never delete a created app automatically because deployment failed. Do not
treat an initial deployment dashboard link as the environment's public URL.
Which app and environment am I looking at?
- Use
list_apps to find the app and get_app for its metadata, including
sourceUrl and siteAttached.
- Use
list_environments to report the branch, mount, publicUrl, and latest
deployment status. If publicUrl is null, report that no user-facing
environment address is available; do not construct one.
- Use
get_app_domains when the user asks where the app is reachable.
- Explain that custom-domain results exclude the default
*.webflow.io
hostname. Domains for an app attached to a regular Webflow site may belong
to the parent site and be shared by sibling apps.
What is deployed, and is it healthy?
- Use
list_environments for the environment's latest deployment status.
- Use
list_deployments, newest first, then get_deployment for the selected
deployment's detailed timeline and version metadata.
- Treat
starting, building, and deploying as active states. Report any
other status exactly rather than guessing its meaning.
- A failed phase sets
buildFailedAt or deployFailedAt while its matching
finished timestamp remains null. A null finished timestamp by itself does
not prove the phase is still running.
- Report what is observable: selected app and environment, deployment status,
version or commit metadata if returned, phase timestamps, and evidence gaps.
Why did the deployment fail?
- Fetch the deployment with
get_deployment and identify the failed phase
from its status and timestamps.
- Call
get_build_logs only when logsAvailable is true. Start with a narrow
since window or q filter, then broaden only if needed.
- Page until
nextCursor is null when a complete result is required.
- Treat
logsAvailable as a retention and retrieval signal, not proof that
every phase produced log entries.
- Treat an empty result as "no matching retrievable server-side logs," not as
proof that the build succeeded or produced no errors.
- Build output produced on a user's machine is outside MCP. Mention this only
when the user says the deployment was built with the CLI; direct them to the
originating CLI output for local build failures.
- Report the failed phase, relevant timestamps, the smallest useful evidence,
the inferred cause, and any uncertainty. Do not merely restate raw logs.
Why is the running app failing?
- Resolve the exact environment and call
get_runtime_logs.
- Narrow by
since and q before retrieving a broad window. Page completely
when the conclusion depends on absence.
- Runtime logs may be unavailable because of retention. Treat an empty result
as no retrievable logs and report the limitation.
- Correlate runtime evidence with the latest deployment record when useful,
but do not claim causation from timing alone.
- Report the observed error pattern, affected interval, likely cause, evidence,
and limitations.
Is required configuration present?
- Establish the required key set from an authoritative source: a user-provided
key list, a project configuration schema or documented requirement, or a
reference environment the user explicitly designates as complete.
- If the source is a protected file containing values, run deterministic
key-only extraction locally and emit only key names. Never open the source
through a model-visible read or include its values in chat or tool output.
- Obtain an authoritative secrecy designation for every required key from the
user, a project schema or documented requirement, or a reference environment
explicitly designated as authoritative for secrecy. An
.env file or plain
key list establishes names only; never infer secrecy from key names.
- Resolve the environment, call
list_variables, and compare its keys and
secrecy metadata with the established requirements. It proves what is
configured, not what is required. Exhaust pagination before concluding that
a key is missing.
- Report keys and metadata only. Secret entries have
isSecret: true and no
value; a missing secret value is expected.
- If the required set or any secrecy designation is unresolved, stop before a
CLI mutation or dependent deployment unless the user explicitly establishes
that no configuration is required.
- For missing or misclassified keys, route to
webflow-cli:cloud without
requesting values in chat. After the write, verify required keys and secrecy
with list_variables. If it partially fails, report failed keys without
values and stop before deployment; preserve successful keys and the
environment.
Why is this environment serving the wrong branch or route?
- Resolve the exact environment and report its current branch, mount,
publicUrl, and latest deployment status. Report a null publicUrl without
constructing an address.
- Compare the current branch and mount with the user's intended mapping. If
the request is only diagnostic, stop after reporting the mismatch.
- If the correction changes the mount, call
get_app and use siteAttached:
/ is valid only when false; a site-attached app requires a non-root mount.
Do not infer attachment from siteId.
- For a correction, show the exact before-and-after mapping. Explain that
update_environment is immediate, has no dry run, and does not deploy code.
- Require
confirm, call update_environment once, and report the returned
environment, publicUrl, and mountRefreshStatus.
- For an unreadable or uncertain result, locate the original
env_id. If using
the expected new branch as a filter, accept a returned environment only when
its ID equals that original env_id, then compare its branch and mount with
the requested values. A different ID or no uniquely matched original target
is ambiguous: do not continue or retry. Never reuse the old branch filter
after a branch-changing update.
- A failed or unknown mount refresh does not mean the environment update was
rolled back. Report routing as uncertain and do not retry solely because the
refresh failed.
- If the branch changed and the user wants its code deployed, treat
trigger_deployment as a separate previewed and confirmed mutation.
Create an isolated environment for a branch and deploy it
- Resolve the existing app, call
get_app, and validate the proposed mount
with siteAttached before previewing the mutation.
- Page through
list_environments to check whether the requested branch or
mount is already in use.
- Show the proposed branch and mount. Explain that
create_environment is
immediate, has no dry run, and creates a mapping without deploying code.
- Generate one stable
idempotency_key, require confirm, and call
create_environment. Reuse that key only for exact retries.
- Report the returned environment,
publicUrl, and mountRefreshStatus. If the
result is uncertain, search for the expected branch and compare the
environment ID, branch, and mount; use a returned ID to distinguish concurrent
creations. Do not retry while the created environment remains ambiguous.
- A failed refresh means creation succeeded but routing may be incomplete. Do
not retry creation or delete the environment automatically.
- Before deploying this new environment, follow "Is required configuration
present?" as a mandatory gate. Continue only after requirements and secrecy
are verified, or the user explicitly establishes that none are required.
Then use the deployment workflow below for preview, confirmation,
attribution, and monitoring.
Can this deployment be retried, rolled back, or rebuilt from branch HEAD?
Use the mutation's default dry run as the capability check. Do not infer
eligibility from missing logs, app metadata, or deployment metadata.
For a new deployment from the connected branch or a prior exact commit:
- Resolve the environment. For a retry or rollback, also resolve the exact
prior deployment.
- Perform configuration discovery only when the user requests it, deployment
evidence indicates missing or misclassified variables, the selected commit
has documented configuration requirements, or the server rejects the
deployment for configuration reasons. Follow "Is required configuration
present?" when one of these conditions applies. If a preview or execution
rejection creates the condition, resolve it before retrying. Otherwise add
no configuration prerequisite.
- Preview
trigger_deployment for branch HEAD or redeploy for a prior commit.
If preview rejects the source, make no mutation and route local-source
deployment to webflow-cli:cloud.
- For
redeploy, explain that the older commit runs with the environment's
current configuration, so compatibility is not guaranteed.
- Show the returned branch or commit and explain that execution creates a new
GitHub build, not a deployment of local files.
- Require
confirm. Immediately after confirmation, record the newest
deployment as the correlation baseline, then execute with dry_run: false
and one stable idempotency_key. Reuse the key only for exact retries of this
request.
- Interpret the execution result before monitoring:
queued: this call enqueued a deployment.
skipped from trigger_deployment: the branch has no commit, so no
deployment was enqueued.
processing: an earlier call with this key is already in flight; this call
did not enqueue a duplicate.
- An unknown or unreadable status leaves the outcome uncertain.
- The action returns no deployment ID. For
queued or an existing in-flight
request, poll list_deployments and get_deployment for a record appearing
above the baseline captured before the first execution attempt. If that
baseline is unavailable, report that attribution may be ambiguous. Do not
assume the newest record belongs to this request when deployments are
concurrent.
- Stop when the attributed deployment leaves an active state or the bounded
monitoring period ends. If monitoring ends first, report the last status and
timestamp; do not call it failed or enqueue a replacement for that reason.
- For a retry or rollback, preview the prior deployment's exact commit hash
and message. A rollback creates a new build at that commit; it does not move
the environment branch.
4. Apply shared evidence and safety rules
- Treat build, deploy, and runtime logs as potentially sensitive customer
output. Inspect for tokens, credentials, cookies, authorization headers, and
presigned URLs before quoting or saving them.
- Quote only the minimum log evidence needed. Redact sensitive values and URLs.
- A request to inspect, diagnose, or preview does not authorize a mutation.
- Require an itemized preview and the exact word
confirm before every
mutation.
- Reconcile an uncertain mutation through observable state before retrying it.
- Reuse an idempotency key only for exact retries of the same logical request.
- Never delete a newly created app or environment automatically when
configuration or deployment fails. Report the partial state.
5. Handle explicit administrative requests
These operations are supported but are not the skill's primary workflow.
For update_app:
- Fetch the current app with
get_app.
- For a name or description change, prepare and show the exact change. Pass
description: null to clear a description.
- For
source_url, compare the current sourceUrl with the requested canonical
GitHub repository URL. Explain that the immediate update requires a
user-authorized token; machine tokens return 403.
- Require
confirm, call update_app once, and verify with get_app. An
unreadable response requires reconciliation before retrying.
- A source update does not change an environment branch or deploy code. Treat
those as separate confirmed mutations.
- Renaming a standalone app also attempts to rename its backing site; a sync
failure can leave the old site name. Site-attached parent names are unchanged.
For delete_variable:
- Preview with the default dry run.
- If
exists is false, report that nothing was deleted and stop.
- If
exists is true, show the app, environment, and key; warn that deletion
is permanent and require confirm.
- Call once with
dry_run: false. Treat deleted: true as success. Reconcile
an uncertain response with an exact key lookup before retrying.
For delete_environment:
- Preview with the default dry run. Identify the app, environment, branch, and
mount, and explain that its worker, KV/D1/R2 storage, deployments, and
variables will be permanently removed.
- Explain that deletion is irreversible and is rejected for the app's last
environment. Require
confirm.
- Call once with
dry_run: false. Treat deleted: true as success.
- A failed or null
mountRefreshStatus means deletion succeeded but routing
cleanup is failed or uncertain. Report it and never retry the delete.
- For an uncertain response, page until the original
env_id is found or the
listing ends. Do not use a branch filter whose value may have changed.
For delete_app:
- Preview with the default dry run and report
deletionMode.
- Explain that
archive unpublishes the app and removes it from the dashboard,
while hard_delete permanently deletes the app and all its environments and
cannot be undone.
- Require
confirm, then call once with dry_run: false.
- Treat
deleted: true as success. Reconcile uncertainty with get_app or the
app's exact site-and-name lookup before retrying.
6. Handle errors and report
- Duplicate environment branch or mount: report the conflicting environment;
do not silently update or delete it.
- Partial CLI variable write: report failed keys without values and stop before
deployment. Do not roll back successful keys or delete the environment.
GITHUB_APP_NOT_INSTALLED or GITHUB_REPO_NOT_CONNECTED: provide the returned
installUrl and retry only after the user completes the connection.
- An unsupported deployment preview is a capability boundary, not a reason to
bypass MCP with a direct API call.
For each final-report field below, include it only when applicable: the selected
app; a resolved environment; evidence inspected; observed status; supported
cause; limitations; mutations performed; partial state; and, when blocked, the
next required user action.
Examples
Create a site-attached GitHub app
User: "Create search-app from https://github.com/acme/search on the
main branch and attach it to my marketing site at /search."
Resolve the site, preview create_app with its site ID and non-root mount, and
use the GitHub-source creation workflow. Report creation separately from the
automatic initial-deployment outcome.
Diagnose a failed deployment
User: "Why did the latest production deployment fail?"
Use the deployment-diagnostics workflow for the latest production deployment.
Retrieve logs only when available and report empty results as unavailable
evidence, not success.
Correct an environment mapping
User: "Production is serving the preview branch at /app. Point it back to
main at /."
Use the environment-mapping workflow and validate / against siteAttached.
Treat a requested deployment as a separate mutation.
Provision, configure, and deploy a branch environment
User: "Create a /preview environment for feature/search and deploy it.
It needs the variables in .env.preview."
Use the new-environment workflow, then apply its mandatory configuration gate
before routing to deployment. Preserve the environment if a later step fails.
Guidelines
- Start from the user's operational question, not the action inventory.
- Prefer observable evidence over assumptions about how an app was built.
- Use mutation previews and returned errors as capability checks.
- Use CLI for local-source apps and deployments, and for variable values.
- Never use
data_apps_tool for Designer variables.
- Never expose secrets from variables, logs, errors, or URLs.
- Never mutate without an exact preview and explicit
confirm.
- Never retry an uncertain mutation before reconciling observable state.
- Keep repository, environment, configuration, and deployment changes separate.
- Preserve partial resources unless the user explicitly requests deletion.
1---2name: webflow-mcp-cloud-apps3description: Create GitHub-source Webflow Cloud apps and monitor, troubleshoot, or manage existing apps through Webflow MCP. Use when creating a standalone or site-attached app from GitHub; identifying apps or environments; checking public URLs, domains, configuration keys, or deployed versions; diagnosing failures; changing a GitHub source, branch, or mount; provisioning environments; or previewing a deployment, retry, or rollback. Do not use for Designer/CSS variables, CLI/local-source app creation or deployment, or passing environment-variable values through MCP.4---5
6# Webflow Cloud Apps
7
8Use `data_apps_tool` to create GitHub-source apps, answer operational questions,
9and manage environments for Webflow Cloud apps. Start from the user's outcome,
10gather only the evidence needed, and distinguish observations from conclusions.
11
12Use the `webflow-cli:cloud` skill when the task requires CLI/local-source app
13creation or deployment, or creating or updating environment variables.
14Client-side build output is not sent to Webflow and cannot be recovered through
15MCP.
16
17## Instructions
18
19### 1. Establish scope
20
211. Call `webflow_guide_tool` before any other Webflow MCP tool. The live guide
22 and action schemas are authoritative for current arguments and responses.
232. Use Webflow MCP tools for Webflow operations except the explicit CLI handoff
24 for environment-variable values. Never call Webflow APIs directly.
253. Include the required `context` parameter in every tool call. Write 15-25
26 words in third-person perspective.
274. Route by the capability the task requires:
28 - Use `data_apps_tool` to create GitHub-source apps; inspect apps,
29 environments, domains, deployment records, logs, and variable metadata;
30 manage GitHub sources and environments; and enqueue GitHub deployments.
31 - Use `data_variable_tool` for Designer color, size, font, and CSS variables.
32 - Use `webflow-cli:cloud` for CLI/local-source apps, local builds and
33 deployments, or creating and updating environment-variable values.
345. If `data_apps_tool` is unavailable, report that the Cloud Apps MCP
35 capability is not enabled. Do not bypass it with a direct API request.
36
37Never ask the user to paste an environment-variable value or secret into chat.
38For a create or update, delegate to `webflow-cli:cloud` and require a hidden
39prompt, stdin, or protected file. Never pass a secret as a positional argument.
40
41### 2. Resolve the target
42
43Discover identifiers in this order:
44
45```text
46list_apps -> app_id
47list_environments(app_id) -> env_id
48list_deployments(app_id, env_id) -> deployment_id
49```
50
51App names are unique only within a site, so resolve a named app with
52`site_id + name`. If multiple resources match, present distinguishing metadata
53and require the user to select one before any mutation. Use the live guide for
54filter, pagination, cursor, and action-batching mechanics.
55
56### 3. Follow the matching user story
57
58#### Create a GitHub-source app
59
601. Establish the app name, canonical GitHub repository URL, branch, optional
61 description, and whether it is standalone or attached to an existing site.
622. For a site-attached app, resolve the site ID. Omit `site_id` for standalone.
633. Apply the mount contract before previewing:
64 - A standalone app always mounts at `/`; omit `mount` or use `/`.
65 - A site-attached app defaults to `/app`, rejects `/`, and requires a valid
66 non-root mount when overriding the default.
674. Explain that standalone creation requires a workspace-scoped user token.
68 Webflow derives the GitHub installation and validates repository access; do
69 not request an installation ID.
705. Call `create_app` with its default dry run. Show the repository, branch,
71 attachment, site when applicable, mount, and initial-deployment attempt.
726. Require `confirm`. Immediately after confirmation and before execution,
73 record the start time and generate one stable `idempotency_key`; execute with
74 `dry_run: false`, then record the completion time. Reuse that key only for
75 exact retries of this creation.
767. Treat creation and initial deployment as separate outcomes. A returned app
77 means creation succeeded even if `deployStatus` is `skipped` or `failed`.
78 For `triggered`, inspect the environment and deployment; for `skipped`, check
79 the branch or push a commit; for `failed`, preserve the app and inspect or
80 retry deployment separately.
818. If the app or outcome is unreadable, reconcile before retrying:
82 - For a site-attached app, collect candidates with `site_id + name`; for a
83 standalone app, collect candidates by name.
84 - In both cases, compare each candidate's name, `sourceUrl`, and `createdAt`
85 with the requested repository and recorded execution window.
86 - Continue to environments and deployments only when exactly one candidate
87 matches. Do not retry while the created app remains ambiguous.
889. Never delete a created app automatically because deployment failed. Do not
89 treat an initial deployment dashboard link as the environment's public URL.
90
91#### Which app and environment am I looking at?
92
931. Use `list_apps` to find the app and `get_app` for its metadata, including
94 `sourceUrl` and `siteAttached`.
952. Use `list_environments` to report the branch, mount, `publicUrl`, and latest
96 deployment status. If `publicUrl` is null, report that no user-facing
97 environment address is available; do not construct one.
983. Use `get_app_domains` when the user asks where the app is reachable.
994. Explain that custom-domain results exclude the default `*.webflow.io`
100 hostname. Domains for an app attached to a regular Webflow site may belong
101 to the parent site and be shared by sibling apps.
102
103#### What is deployed, and is it healthy?
104
1051. Use `list_environments` for the environment's latest deployment status.
1062. Use `list_deployments`, newest first, then `get_deployment` for the selected
107 deployment's detailed timeline and version metadata.
1083. Treat `starting`, `building`, and `deploying` as active states. Report any
109 other status exactly rather than guessing its meaning.
1104. A failed phase sets `buildFailedAt` or `deployFailedAt` while its matching
111 finished timestamp remains null. A null finished timestamp by itself does
112 not prove the phase is still running.
1135. Report what is observable: selected app and environment, deployment status,
114 version or commit metadata if returned, phase timestamps, and evidence gaps.
115
116#### Why did the deployment fail?
117
1181. Fetch the deployment with `get_deployment` and identify the failed phase
119 from its status and timestamps.
1202. Call `get_build_logs` only when `logsAvailable` is true. Start with a narrow
121 `since` window or `q` filter, then broaden only if needed.
1223. Page until `nextCursor` is null when a complete result is required.
1234. Treat `logsAvailable` as a retention and retrieval signal, not proof that
124 every phase produced log entries.
1255. Treat an empty result as "no matching retrievable server-side logs," not as
126 proof that the build succeeded or produced no errors.
1276. Build output produced on a user's machine is outside MCP. Mention this only
128 when the user says the deployment was built with the CLI; direct them to the
129 originating CLI output for local build failures.
1307. Report the failed phase, relevant timestamps, the smallest useful evidence,
131 the inferred cause, and any uncertainty. Do not merely restate raw logs.
132
133#### Why is the running app failing?
134
1351. Resolve the exact environment and call `get_runtime_logs`.
1362. Narrow by `since` and `q` before retrieving a broad window. Page completely
137 when the conclusion depends on absence.
1383. Runtime logs may be unavailable because of retention. Treat an empty result
139 as no retrievable logs and report the limitation.
1404. Correlate runtime evidence with the latest deployment record when useful,
141 but do not claim causation from timing alone.
1425. Report the observed error pattern, affected interval, likely cause, evidence,
143 and limitations.
144
145#### Is required configuration present?
146
1471. Establish the required key set from an authoritative source: a user-provided
148 key list, a project configuration schema or documented requirement, or a
149 reference environment the user explicitly designates as complete.
1502. If the source is a protected file containing values, run deterministic
151 key-only extraction locally and emit only key names. Never open the source
152 through a model-visible read or include its values in chat or tool output.
1533. Obtain an authoritative secrecy designation for every required key from the
154 user, a project schema or documented requirement, or a reference environment
155 explicitly designated as authoritative for secrecy. An `.env` file or plain
156 key list establishes names only; never infer secrecy from key names.
1574. Resolve the environment, call `list_variables`, and compare its keys and
158 secrecy metadata with the established requirements. It proves what is
159 configured, not what is required. Exhaust pagination before concluding that
160 a key is missing.
1615. Report keys and metadata only. Secret entries have `isSecret: true` and no
162 value; a missing secret value is expected.
1636. If the required set or any secrecy designation is unresolved, stop before a
164 CLI mutation or dependent deployment unless the user explicitly establishes
165 that no configuration is required.
1667. For missing or misclassified keys, route to `webflow-cli:cloud` without
167 requesting values in chat. After the write, verify required keys and secrecy
168 with `list_variables`. If it partially fails, report failed keys without
169 values and stop before deployment; preserve successful keys and the
170 environment.
171
172#### Why is this environment serving the wrong branch or route?
173
1741. Resolve the exact environment and report its current branch, mount,
175 `publicUrl`, and latest deployment status. Report a null `publicUrl` without
176 constructing an address.
1772. Compare the current branch and mount with the user's intended mapping. If
178 the request is only diagnostic, stop after reporting the mismatch.
1793. If the correction changes the mount, call `get_app` and use `siteAttached`:
180 `/` is valid only when false; a site-attached app requires a non-root mount.
181 Do not infer attachment from `siteId`.
1824. For a correction, show the exact before-and-after mapping. Explain that
183 `update_environment` is immediate, has no dry run, and does not deploy code.
1845. Require `confirm`, call `update_environment` once, and report the returned
185 environment, `publicUrl`, and `mountRefreshStatus`.
1866. For an unreadable or uncertain result, locate the original `env_id`. If using
187 the expected new branch as a filter, accept a returned environment only when
188 its ID equals that original `env_id`, then compare its branch and mount with
189 the requested values. A different ID or no uniquely matched original target
190 is ambiguous: do not continue or retry. Never reuse the old branch filter
191 after a branch-changing update.
1927. A failed or unknown mount refresh does not mean the environment update was
193 rolled back. Report routing as uncertain and do not retry solely because the
194 refresh failed.
1958. If the branch changed and the user wants its code deployed, treat
196 `trigger_deployment` as a separate previewed and confirmed mutation.
197
198#### Create an isolated environment for a branch and deploy it
199
2001. Resolve the existing app, call `get_app`, and validate the proposed mount
201 with `siteAttached` before previewing the mutation.
2022. Page through `list_environments` to check whether the requested branch or
203 mount is already in use.
2043. Show the proposed branch and mount. Explain that `create_environment` is
205 immediate, has no dry run, and creates a mapping without deploying code.
2064. Generate one stable `idempotency_key`, require `confirm`, and call
207 `create_environment`. Reuse that key only for exact retries.
2085. Report the returned environment, `publicUrl`, and `mountRefreshStatus`. If the
209 result is uncertain, search for the expected branch and compare the
210 environment ID, branch, and mount; use a returned ID to distinguish concurrent
211 creations. Do not retry while the created environment remains ambiguous.
2126. A failed refresh means creation succeeded but routing may be incomplete. Do
213 not retry creation or delete the environment automatically.
2147. Before deploying this new environment, follow "Is required configuration
215 present?" as a mandatory gate. Continue only after requirements and secrecy
216 are verified, or the user explicitly establishes that none are required.
217 Then use the deployment workflow below for preview, confirmation,
218 attribution, and monitoring.
219
220#### Can this deployment be retried, rolled back, or rebuilt from branch HEAD?
221
222Use the mutation's default dry run as the capability check. Do not infer
223eligibility from missing logs, app metadata, or deployment metadata.
224
225For a new deployment from the connected branch or a prior exact commit:
226
2271. Resolve the environment. For a retry or rollback, also resolve the exact
228 prior deployment.
2292. Perform configuration discovery only when the user requests it, deployment
230 evidence indicates missing or misclassified variables, the selected commit
231 has documented configuration requirements, or the server rejects the
232 deployment for configuration reasons. Follow "Is required configuration
233 present?" when one of these conditions applies. If a preview or execution
234 rejection creates the condition, resolve it before retrying. Otherwise add
235 no configuration prerequisite.
2363. Preview `trigger_deployment` for branch HEAD or `redeploy` for a prior commit.
237 If preview rejects the source, make no mutation and route local-source
238 deployment to `webflow-cli:cloud`.
2394. For `redeploy`, explain that the older commit runs with the environment's
240 current configuration, so compatibility is not guaranteed.
2415. Show the returned branch or commit and explain that execution creates a new
242 GitHub build, not a deployment of local files.
2436. Require `confirm`. Immediately after confirmation, record the newest
244 deployment as the correlation baseline, then execute with `dry_run: false`
245 and one stable `idempotency_key`. Reuse the key only for exact retries of this
246 request.
2477. Interpret the execution result before monitoring:
248 - `queued`: this call enqueued a deployment.
249 - `skipped` from `trigger_deployment`: the branch has no commit, so no
250 deployment was enqueued.
251 - `processing`: an earlier call with this key is already in flight; this call
252 did not enqueue a duplicate.
253 - An unknown or unreadable status leaves the outcome uncertain.
2548. The action returns no deployment ID. For `queued` or an existing in-flight
255 request, poll `list_deployments` and `get_deployment` for a record appearing
256 above the baseline captured before the first execution attempt. If that
257 baseline is unavailable, report that attribution may be ambiguous. Do not
258 assume the newest record belongs to this request when deployments are
259 concurrent.
2609. Stop when the attributed deployment leaves an active state or the bounded
261 monitoring period ends. If monitoring ends first, report the last status and
262 timestamp; do not call it failed or enqueue a replacement for that reason.
26310. For a retry or rollback, preview the prior deployment's exact commit hash
264 and message. A rollback creates a new build at that commit; it does not move
265 the environment branch.
266
267### 4. Apply shared evidence and safety rules
268
269- Treat build, deploy, and runtime logs as potentially sensitive customer
270 output. Inspect for tokens, credentials, cookies, authorization headers, and
271 presigned URLs before quoting or saving them.
272- Quote only the minimum log evidence needed. Redact sensitive values and URLs.
273- A request to inspect, diagnose, or preview does not authorize a mutation.
274- Require an itemized preview and the exact word `confirm` before every
275 mutation.
276- Reconcile an uncertain mutation through observable state before retrying it.
277- Reuse an idempotency key only for exact retries of the same logical request.
278- Never delete a newly created app or environment automatically when
279 configuration or deployment fails. Report the partial state.
280
281### 5. Handle explicit administrative requests
282
283These operations are supported but are not the skill's primary workflow.
284
285For `update_app`:
286
2871. Fetch the current app with `get_app`.
2882. For a name or description change, prepare and show the exact change. Pass
289 `description: null` to clear a description.
2903. For `source_url`, compare the current `sourceUrl` with the requested canonical
291 GitHub repository URL. Explain that the immediate update requires a
292 user-authorized token; machine tokens return `403`.
2934. Require `confirm`, call `update_app` once, and verify with `get_app`. An
294 unreadable response requires reconciliation before retrying.
2955. A source update does not change an environment branch or deploy code. Treat
296 those as separate confirmed mutations.
2976. Renaming a standalone app also attempts to rename its backing site; a sync
298 failure can leave the old site name. Site-attached parent names are unchanged.
299
300For `delete_variable`:
301
3021. Preview with the default dry run.
3032. If `exists` is false, report that nothing was deleted and stop.
3043. If `exists` is true, show the app, environment, and key; warn that deletion
305 is permanent and require `confirm`.
3064. Call once with `dry_run: false`. Treat `deleted: true` as success. Reconcile
307 an uncertain response with an exact key lookup before retrying.
308
309For `delete_environment`:
310
3111. Preview with the default dry run. Identify the app, environment, branch, and
312 mount, and explain that its worker, KV/D1/R2 storage, deployments, and
313 variables will be permanently removed.
3142. Explain that deletion is irreversible and is rejected for the app's last
315 environment. Require `confirm`.
3163. Call once with `dry_run: false`. Treat `deleted: true` as success.
3174. A failed or null `mountRefreshStatus` means deletion succeeded but routing
318 cleanup is failed or uncertain. Report it and never retry the delete.
3195. For an uncertain response, page until the original `env_id` is found or the
320 listing ends. Do not use a branch filter whose value may have changed.
321
322For `delete_app`:
323
3241. Preview with the default dry run and report `deletionMode`.
3252. Explain that `archive` unpublishes the app and removes it from the dashboard,
326 while `hard_delete` permanently deletes the app and all its environments and
327 cannot be undone.
3283. Require `confirm`, then call once with `dry_run: false`.
3294. Treat `deleted: true` as success. Reconcile uncertainty with `get_app` or the
330 app's exact site-and-name lookup before retrying.
331
332### 6. Handle errors and report
333
334- Duplicate environment branch or mount: report the conflicting environment;
335 do not silently update or delete it.
336- Partial CLI variable write: report failed keys without values and stop before
337 deployment. Do not roll back successful keys or delete the environment.
338- `GITHUB_APP_NOT_INSTALLED` or `GITHUB_REPO_NOT_CONNECTED`: provide the returned
339 `installUrl` and retry only after the user completes the connection.
340- An unsupported deployment preview is a capability boundary, not a reason to
341 bypass MCP with a direct API call.
342
343For each final-report field below, include it only when applicable: the selected
344app; a resolved environment; evidence inspected; observed status; supported
345cause; limitations; mutations performed; partial state; and, when blocked, the
346next required user action.
347
348## Examples
349
350### Create a site-attached GitHub app
351
352**User:** "Create `search-app` from `https://github.com/acme/search` on the
353`main` branch and attach it to my marketing site at `/search`."
354
355Resolve the site, preview `create_app` with its site ID and non-root mount, and
356use the GitHub-source creation workflow. Report creation separately from the
357automatic initial-deployment outcome.
358
359### Diagnose a failed deployment
360
361**User:** "Why did the latest production deployment fail?"
362
363Use the deployment-diagnostics workflow for the latest production deployment.
364Retrieve logs only when available and report empty results as unavailable
365evidence, not success.
366
367### Correct an environment mapping
368
369**User:** "Production is serving the preview branch at `/app`. Point it back to
370`main` at `/`."
371
372Use the environment-mapping workflow and validate `/` against `siteAttached`.
373Treat a requested deployment as a separate mutation.
374
375### Provision, configure, and deploy a branch environment
376
377**User:** "Create a `/preview` environment for `feature/search` and deploy it.
378It needs the variables in `.env.preview`."
379
380Use the new-environment workflow, then apply its mandatory configuration gate
381before routing to deployment. Preserve the environment if a later step fails.
382
383## Guidelines
384
385- Start from the user's operational question, not the action inventory.
386- Prefer observable evidence over assumptions about how an app was built.
387- Use mutation previews and returned errors as capability checks.
388- Use CLI for local-source apps and deployments, and for variable values.
389- Never use `data_apps_tool` for Designer variables.
390- Never expose secrets from variables, logs, errors, or URLs.
391- Never mutate without an exact preview and explicit `confirm`.
392- Never retry an uncertain mutation before reconciling observable state.
393- Keep repository, environment, configuration, and deployment changes separate.
394- Preserve partial resources unless the user explicitly requests deletion.