From cf4b368060ee183375654c252dfe51c0514d4ae3 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Thu, 13 Aug 2026 12:07:32 -0300 Subject: [PATCH 01/10] CLD-2297 Add Webflow Cloud apps MCP skill --- .cursor-plugin/plugin.json | 6 +- README.md | 1 + .../webflow-skills/.claude-plugin/plugin.json | 4 +- .../webflow-skills/.codex-plugin/plugin.json | 13 +- .../webflow-skills/skills/cloud-apps/SKILL.md | 272 ++++++++++++++++++ 5 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 plugins/webflow-skills/skills/cloud-apps/SKILL.md diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 896fcfb..4c4ad3d 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webflow", - "version": "1.0.7", - "description": "Production-ready agent skills for Webflow - CMS management, site auditing, Designer tools, Code Components, CLI workflows, and safe publishing", + "version": "1.0.8", + "description": "Production-ready agent skills for Webflow - CMS management, Cloud app operations, site auditing, Designer tools, Code Components, CLI workflows, and safe publishing", "author": { "name": "Webflow", "email": "developers@webflow.com", @@ -27,6 +27,8 @@ "cli", "devlink", "webflow-cloud", + "cloud-apps", + "deployments", "designer-extensions", "page-structure", "flowkit" diff --git a/README.md b/README.md index 31f3a93..afacd12 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ All skills ship from the single `webflow-skills` plugin. | webflow-mcp:flowkit-naming | Apply Webflow's official FlowKit CSS naming conventions | | webflow-mcp:designer-tools | Build and manage page structure, elements, components, and styles in Webflow Designer | | webflow-mcp:figma-to-webflow | Build pages, sections, components, or full sites from Figma designs using Figma MCP and Webflow MCP | +| webflow-mcp:cloud-apps | Inspect and operate existing Webflow Cloud apps, environments, deployments, variables, domains, and logs | ### Webflow CLI Skills diff --git a/plugins/webflow-skills/.claude-plugin/plugin.json b/plugins/webflow-skills/.claude-plugin/plugin.json index 0f6e08b..54327cb 100644 --- a/plugins/webflow-skills/.claude-plugin/plugin.json +++ b/plugins/webflow-skills/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "webflow-skills", - "description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes", - "version": "1.0.7", + "description": "Production-ready skills for managing Webflow CMS content, operating Webflow Cloud apps, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes", + "version": "1.0.8", "skills": "./skills/" } diff --git a/plugins/webflow-skills/.codex-plugin/plugin.json b/plugins/webflow-skills/.codex-plugin/plugin.json index 03c8ee3..077e236 100644 --- a/plugins/webflow-skills/.codex-plugin/plugin.json +++ b/plugins/webflow-skills/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webflow-skills", - "version": "1.0.7", - "description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes.", + "version": "1.0.8", + "description": "Production-ready skills for managing Webflow CMS content, operating Webflow Cloud apps, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes.", "author": { "name": "Webflow", "email": "developers@webflow.com", @@ -29,6 +29,8 @@ "cli", "devlink", "webflow-cloud", + "cloud-apps", + "deployments", "designer-extensions", "page-structure", "flowkit" @@ -37,8 +39,8 @@ "mcpServers": "./.mcp.json", "interface": { "displayName": "Webflow Skills", - "shortDescription": "Manage CMS, Designer, Code Components, and CLI workflows", - "longDescription": "Use Webflow Skills in Codex to manage CMS content, audit site health, optimize assets, check links, apply FlowKit naming, manage custom code, build and inspect Designer pages and components, create and deploy Code Components, run Webflow CLI workflows, and prepare safe publishing workflows with Webflow MCP.", + "shortDescription": "Manage CMS, Cloud apps, Designer, components, and CLI workflows", + "longDescription": "Use Webflow Skills in Codex to manage CMS content, inspect and operate Webflow Cloud apps, audit site health, optimize assets, check links, apply FlowKit naming, manage custom code, build and inspect Designer pages and components, create and deploy Code Components, run Webflow CLI workflows, and prepare safe publishing workflows with Webflow MCP.", "developerName": "Webflow", "category": "Productivity", "capabilities": ["Interactive", "Read", "Write"], @@ -52,7 +54,8 @@ "Inspect the current Designer page structure", "Build this Figma design in Webflow", "Create a new Webflow Code Component", - "Deploy a Webflow Cloud app" + "Deploy a Webflow Cloud app", + "Inspect the latest deployment for my Webflow Cloud app" ], "brandColor": "#146EF5", "composerIcon": "./assets/logo.svg", diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md new file mode 100644 index 0000000..b6d91de --- /dev/null +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -0,0 +1,272 @@ +--- +name: webflow-mcp:cloud-apps +description: Inspect and operate existing Webflow Cloud apps through Webflow MCP. Use when listing Cloud apps, checking app metadata or domains, inspecting environments or environment-variable names, reviewing deployments, diagnosing build or runtime failures, triggering or re-running GitHub deployments, updating app metadata, deleting environment variables, or removing apps. Do not use for design/CSS variables, creating Cloud apps, CLI-driven builds or deployments from local source, or creating/updating environment-variable values. +--- + +# Webflow Cloud Apps + +Inspect and manage existing Webflow Cloud apps with `data_apps_tool`. Use the +Webflow CLI skill for project creation, building local source and deploying it +to Webflow Cloud, and environment-variable writes that this tool does not +support. + +## Instructions + +### Phase 1: Establish scope + +1. Call `webflow_guide_tool` before any other Webflow MCP tool. +2. Use only Webflow MCP tools for Webflow operations. Do not call Webflow APIs + directly. +3. Include the required `context` parameter in every tool call. Write 15-25 + words in third-person perspective. +4. Confirm that the request concerns a Webflow Cloud app: + - Use `data_apps_tool` for existing Cloud apps, environments, deployments, + logs, domains, and environment-variable metadata. + - Use `data_variable_tool` for Designer color, size, font, and CSS variables. + - Use the `webflow-cli:cloud` skill to create an app, build or deploy local + source, or create/update an environment variable. +5. 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. +When a value must be created or changed, direct the user to the installed +Webflow CLI's built-in help and require a hidden prompt, stdin, or protected +file. Do not guess a CLI command. + +### Phase 2: Resolve identifiers + +Discover identifiers in this order: + +```text +list_apps -> app_id +list_environments(app_id) -> env_id +list_deployments(app_id, env_id) -> deployment_id +``` + +Use an identifier supplied by the user only after verifying it through the +corresponding get or list action. If a list action returns `nextCursor`, pass it +back as `cursor` until `nextCursor` is null. One page is not proof that a +resource is absent. + +If multiple resources match, present identifying metadata and require the user +to choose before any mutation. Auto-select only when exactly one unambiguous +resource matches. + +### Phase 3: Route the request + +| Intent | Action sequence | +|---|---| +| Find apps | `list_apps` | +| Inspect one app | `get_app` | +| Find live custom hostnames | `get_app_domains` | +| Rename or describe an app | `get_app` -> confirm -> `update_app` -> `get_app` | +| Remove an app | `delete_app` dry run -> confirm -> `delete_app` with `dry_run: false` | +| Find environments | `list_environments` | +| Inspect variable names | `list_variables` | +| Delete one variable | `delete_variable` dry run -> confirm -> `delete_variable` with `dry_run: false` | +| Review deployment history | `list_deployments` -> `get_deployment` | +| Deploy the connected branch HEAD | `trigger_deployment` dry run -> confirm -> execute -> poll | +| Retry or roll back an exact commit | Select deployment -> `redeploy` dry run -> confirm -> execute -> poll | +| Diagnose a build or deploy failure | `get_deployment` -> `get_build_logs` | +| Diagnose the running app | `get_runtime_logs` | + +The action's live schema is authoritative for arguments and response fields. Do +not invent fields from this table. + +### Phase 4: Execute read-only workflows + +For app inspection: + +1. Locate the app with `list_apps`. +2. Use `get_app` for app metadata or `get_app_domains` for custom hostnames. +3. Explain that `get_app_domains` excludes the default `*.webflow.io` hostname. + For an app attached to a regular Webflow site, returned domains belong to the + parent site and may be shared by sibling apps. + +For environment variables: + +1. Locate the environment with `list_environments`. +2. Call `list_variables`. +3. Report keys and metadata. Secret entries have `isSecret: true` and no value; + never imply that a missing secret value is an error. + +For deployment inspection: + +1. Use `list_environments` for the environment and its + `latestDeploymentStatus`. +2. Use `list_deployments`, which returns newest first. +3. Use `get_deployment` for the selected deployment's full timeline. +4. Treat `starting`, `building`, and `deploying` as active states. Report any + other value rather than guessing what it means. +5. A failed phase sets `buildFailedAt` or `deployFailedAt` while its matching + finished timestamp remains null. A null finished timestamp alone does not + prove that the phase is still running. + +For logs: + +1. Prefer a deployment whose `logsAvailable` value is true before calling + `get_build_logs`. +2. Use `since` and `q` to narrow results before retrieving broad log windows. +3. Page until `nextCursor` is null when completeness matters. +4. Treat build-phase and runtime logs as raw, potentially sensitive customer + output. Inspect lines for tokens, credentials, cookies, authorization + headers, and presigned URLs before quoting or saving them. +5. Explain that runtime logs are retained for approximately one hour on the + base plan. An empty result for an older window is valid. + +### Phase 5: Preview and execute mutations + +Require the user to explicitly type `confirm` after showing the exact target and +effect. A prior request to inspect, diagnose, or preview does not authorize a +mutation. + +For `update_app`: + +1. Fetch the current app with `get_app`. +2. Show the exact name and description change. Explain that this cannot change + source configuration or deployments. +3. Require confirmation, call `update_app`, then verify with `get_app`. +4. Pass `description: null` to clear a description. Do not use an empty string. + +For `delete_variable`: + +1. Call `delete_variable` with the default dry run. The preview confirms whether + the exact key exists and returns no value. +2. If `exists` is false, report that no variable was deleted. Do not request + confirmation or call the destructive operation. +3. If the preview cannot confirm existence, stop and report the error. Do not + treat an incomplete paginated read as a missing key. +4. If `exists` is true, show the app, environment, and key, then warn that the + action permanently deletes the variable. +5. Require confirmation, then call `delete_variable` with `dry_run: false` + exactly once. Treat its successful `deleted: true` response as success even + when the backend body has no readable message. + +For `trigger_deployment`: + +1. Call it with the default dry run and show the connected branch. +2. Explain that execution deploys the branch's latest commit, not local files. +3. Require confirmation. +4. Generate one stable `idempotency_key` before the first call with + `dry_run: false`. Reuse the same key for every retry. +5. The action returns no deployment ID. Poll `list_deployments`, identify the + new record, and use `get_deployment` until it leaves an active state or the + bounded monitoring period ends. + +For `redeploy`: + +1. Select the previous deployment and call `redeploy` with the default dry run. +2. Show its exact commit hash and message. Explain that this creates a fresh + build at that commit. +3. Require confirmation. +4. Execute with `dry_run: false` and a stable `idempotency_key`, then poll as + described for `trigger_deployment`. + +For `delete_app`: + +1. Call it with the default dry run. +2. Report the returned `deletionMode`: + - `archive`: reversible archival of the Cloud app. + - `hard_delete`: permanent deletion of the attached app's project and + environments. +3. Require confirmation after the mode-specific warning. +4. Call with `dry_run: false` exactly once. A successful `deleted: true` + response remains success even when the backend body has no readable message. + Do not infer failure from an unavailable post-delete resource. + +### Phase 6: Handle errors + +- `401` or `403`: report the authentication or permission problem; do not + retry. +- `404`: verify the complete app -> environment -> deployment chain; do not + silently switch targets. +- `429`: honor the backoff signal before a bounded retry. +- `5xx` on a read: retry a bounded number of times. +- `5xx` on a mutation: treat the outcome as uncertain. Reconcile with list/get + actions before considering a retry. +- A successful mutation response with sparse or unreadable backend content is + not a failure. Do not retry a deletion; poll deployment records when a deploy + action cannot report its final status. +- Rejected cursor: restart that listing without the cursor and page again. +- `GITHUB_APP_NOT_INSTALLED`: provide the returned `installUrl`, require the + user to reconnect GitHub, then retry only after reconnection. + +An empty list is a valid success. Do not translate it into a tool failure. + +### Phase 7: Report + +State: + +- The app and environment selected +- The actions performed +- The deployment status or mutation outcome +- Any pagination, retention, permission, or uncertainty limitation +- The next required user action only when the workflow cannot continue + +Do not expose sensitive log content or environment-variable values. + +## Examples + +### Inspect a failed deployment + +**User:** "Why did the latest production deployment fail?" + +1. Call `webflow_guide_tool`. +2. Resolve the app with `list_apps`. +3. Resolve production with `list_environments`. +4. Fetch the latest record with `list_deployments`, then `get_deployment`. +5. If logs are available, call `get_build_logs` with a narrow error query. +6. Redact sensitive values and report the failed phase, relevant timestamps, + concise root cause, and evidence. + +### Trigger a deployment + +**User:** "Deploy the latest commit for production." + +1. Resolve the app and production environment. +2. Call `trigger_deployment` as a dry run. +3. Report the exact connected branch and request `confirm`. +4. After confirmation, execute with a stable idempotency key. +5. Poll the deployment list and report the resulting status. + +### Set a secret + +**User:** "Set `DATABASE_URL` in production." + +Do not request the value and do not call `data_apps_tool`. State that MCP cannot +create or update environment variables. Route the task to +`webflow-cli:cloud`, using the installed CLI's help and a secret-safe input +method. + +### Delete an environment variable + +**User:** "Delete `OLD_FEATURE_FLAG` from staging." + +1. Resolve the app and staging environment. +2. Call `delete_variable` with its default dry run. +3. If the preview confirms the key exists, disclose the exact target and stop + until the user types `confirm`. +4. Call `delete_variable` with `dry_run: false` once, then report the result. + +### Delete an app + +**User:** "Delete my staging Cloud app." + +1. Resolve the exact app. +2. Call `delete_app` as a dry run. +3. Explain whether the operation archives or permanently deletes it. +4. Stop until the user types `confirm`. +5. Execute once and report the returned outcome. + +## Guidelines + +- Call `webflow_guide_tool` first. +- Prefer MCP over CLI for supported operations on existing Cloud apps. +- Use CLI only for app creation, building local source and deploying it to + Webflow Cloud, and environment-variable creation or updates. +- Never use `data_apps_tool` for Designer variables. +- Never mutate without an itemized preview and explicit `confirm`. +- Never retry an uncertain mutation before reconciling observable state. +- Never expose secrets from variables, logs, errors, or URLs. +- Never conclude that a paginated resource is absent after one page. +- Never fabricate IDs, deployment status, action arguments, or live URLs. From b9a865e88c6a5fbae3a16555ec18d6f92f348057 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Thu, 13 Aug 2026 19:43:51 -0300 Subject: [PATCH 02/10] Refine Cloud apps skill around troubleshooting --- README.md | 2 +- .../webflow-skills/skills/cloud-apps/SKILL.md | 397 +++++++++--------- 2 files changed, 197 insertions(+), 202 deletions(-) diff --git a/README.md b/README.md index afacd12..c6a2c89 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ All skills ship from the single `webflow-skills` plugin. | webflow-mcp:flowkit-naming | Apply Webflow's official FlowKit CSS naming conventions | | webflow-mcp:designer-tools | Build and manage page structure, elements, components, and styles in Webflow Designer | | webflow-mcp:figma-to-webflow | Build pages, sections, components, or full sites from Figma designs using Figma MCP and Webflow MCP | -| webflow-mcp:cloud-apps | Inspect and operate existing Webflow Cloud apps, environments, deployments, variables, domains, and logs | +| webflow-mcp:cloud-apps | Monitor and troubleshoot existing Webflow Cloud apps, deployments, configuration, domains, and runtime behavior | ### Webflow CLI Skills diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index b6d91de..58080f2 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -1,39 +1,42 @@ --- name: webflow-mcp:cloud-apps -description: Inspect and operate existing Webflow Cloud apps through Webflow MCP. Use when listing Cloud apps, checking app metadata or domains, inspecting environments or environment-variable names, reviewing deployments, diagnosing build or runtime failures, triggering or re-running GitHub deployments, updating app metadata, deleting environment variables, or removing apps. Do not use for design/CSS variables, creating Cloud apps, CLI-driven builds or deployments from local source, or creating/updating environment-variable values. +description: Monitor and troubleshoot existing Webflow Cloud apps through Webflow MCP. Use when identifying apps or environments, checking domains or deployed versions, reviewing deployment health and history, diagnosing build, deploy, or runtime failures, verifying environment-variable keys, or previewing a retry, rollback, or GitHub branch deployment. Do not use for design/CSS variables, creating Cloud apps, deploying local source, or creating/updating environment-variable values. --- # Webflow Cloud Apps -Inspect and manage existing Webflow Cloud apps with `data_apps_tool`. Use the -Webflow CLI skill for project creation, building local source and deploying it -to Webflow Cloud, and environment-variable writes that this tool does not -support. +Use `data_apps_tool` to answer operational questions about existing 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 creating an app, +building or deploying local source, or creating or updating environment +variables. Client-side build output is not sent to Webflow and cannot be +recovered through MCP. ## Instructions -### Phase 1: Establish scope +### 1. Establish scope 1. Call `webflow_guide_tool` before any other Webflow MCP tool. -2. Use only Webflow MCP tools for Webflow operations. Do not call Webflow APIs +2. Use only Webflow MCP tools for Webflow operations. Never call Webflow APIs directly. 3. Include the required `context` parameter in every tool call. Write 15-25 words in third-person perspective. -4. Confirm that the request concerns a Webflow Cloud app: - - Use `data_apps_tool` for existing Cloud apps, environments, deployments, - logs, domains, and environment-variable metadata. +4. Route by the capability the task requires: + - Use `data_apps_tool` to inspect existing apps, environments, domains, + deployment records, available server-side logs, and variable metadata. - Use `data_variable_tool` for Designer color, size, font, and CSS variables. - - Use the `webflow-cli:cloud` skill to create an app, build or deploy local - source, or create/update an environment variable. -5. 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. + - Use `webflow-cli:cloud` for app creation, local builds and deployments, or + creating and updating environment-variable values. +5. 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. -When a value must be created or changed, direct the user to the installed -Webflow CLI's built-in help and require a hidden prompt, stdin, or protected -file. Do not guess a CLI command. +For a create or update, route to the installed Webflow CLI's built-in help and +require a hidden prompt, stdin, or protected file. Do not guess a CLI command. -### Phase 2: Resolve identifiers +### 2. Resolve the target Discover identifiers in this order: @@ -44,137 +47,154 @@ list_deployments(app_id, env_id) -> deployment_id ``` Use an identifier supplied by the user only after verifying it through the -corresponding get or list action. If a list action returns `nextCursor`, pass it -back as `cursor` until `nextCursor` is null. One page is not proof that a -resource is absent. - -If multiple resources match, present identifying metadata and require the user -to choose before any mutation. Auto-select only when exactly one unambiguous -resource matches. - -### Phase 3: Route the request - -| Intent | Action sequence | -|---|---| -| Find apps | `list_apps` | -| Inspect one app | `get_app` | -| Find live custom hostnames | `get_app_domains` | -| Rename or describe an app | `get_app` -> confirm -> `update_app` -> `get_app` | -| Remove an app | `delete_app` dry run -> confirm -> `delete_app` with `dry_run: false` | -| Find environments | `list_environments` | -| Inspect variable names | `list_variables` | -| Delete one variable | `delete_variable` dry run -> confirm -> `delete_variable` with `dry_run: false` | -| Review deployment history | `list_deployments` -> `get_deployment` | -| Deploy the connected branch HEAD | `trigger_deployment` dry run -> confirm -> execute -> poll | -| Retry or roll back an exact commit | Select deployment -> `redeploy` dry run -> confirm -> execute -> poll | -| Diagnose a build or deploy failure | `get_deployment` -> `get_build_logs` | -| Diagnose the running app | `get_runtime_logs` | - -The action's live schema is authoritative for arguments and response fields. Do -not invent fields from this table. - -### Phase 4: Execute read-only workflows - -For app inspection: - -1. Locate the app with `list_apps`. -2. Use `get_app` for app metadata or `get_app_domains` for custom hostnames. -3. Explain that `get_app_domains` excludes the default `*.webflow.io` hostname. - For an app attached to a regular Webflow site, returned domains belong to the - parent site and may be shared by sibling apps. - -For environment variables: - -1. Locate the environment with `list_environments`. -2. Call `list_variables`. -3. Report keys and metadata. Secret entries have `isSecret: true` and no value; - never imply that a missing secret value is an error. - -For deployment inspection: - -1. Use `list_environments` for the environment and its - `latestDeploymentStatus`. -2. Use `list_deployments`, which returns newest first. -3. Use `get_deployment` for the selected deployment's full timeline. -4. Treat `starting`, `building`, and `deploying` as active states. Report any - other value rather than guessing what it means. -5. A failed phase sets `buildFailedAt` or `deployFailedAt` while its matching - finished timestamp remains null. A null finished timestamp alone does not - prove that the phase is still running. - -For logs: - -1. Prefer a deployment whose `logsAvailable` value is true before calling - `get_build_logs`. -2. Use `since` and `q` to narrow results before retrieving broad log windows. -3. Page until `nextCursor` is null when completeness matters. -4. Treat build-phase and runtime logs as raw, potentially sensitive customer - output. Inspect lines for tokens, credentials, cookies, authorization - headers, and presigned URLs before quoting or saving them. -5. Explain that runtime logs are retained for approximately one hour on the - base plan. An empty result for an older window is valid. - -### Phase 5: Preview and execute mutations - -Require the user to explicitly type `confirm` after showing the exact target and -effect. A prior request to inspect, diagnose, or preview does not authorize a -mutation. +corresponding get or list action. Use exact filters when available. If a list +action returns `nextCursor`, pass it back as `cursor` until `nextCursor` is null +whenever absence or completeness matters. + +If multiple resources match, present distinguishing metadata and require the +user to select one before any mutation. Auto-select only when one resource is +unambiguous. + +### 3. Follow the matching user story + +#### Which app and environment am I looking at? + +1. Use `list_apps` to find the app and `get_app` for its metadata. +2. Use `list_environments` to report the branch, mount, deploy URL, and latest + deployment status exposed by the live response. +3. Use `get_app_domains` when the user asks where the app is reachable. +4. 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? + +1. Use `list_environments` for the environment's latest deployment status. +2. Use `list_deployments`, newest first, then `get_deployment` for the selected + deployment's detailed timeline and version metadata. +3. Treat `starting`, `building`, and `deploying` as active states. Report any + other status exactly rather than guessing its meaning. +4. 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. +5. 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? + +1. Fetch the deployment with `get_deployment` and identify the failed phase + from its status and timestamps. +2. Call `get_build_logs` only when `logsAvailable` is true. Start with a narrow + `since` window or `q` filter, then broaden only if needed. +3. Page until `nextCursor` is null when a complete result is required. +4. Treat `logsAvailable` as a retention and retrieval signal, not proof that + every phase produced log entries. +5. Treat an empty result as "no matching retrievable server-side logs," not as + proof that the build succeeded or produced no errors. +6. 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. +7. 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? + +1. Resolve the exact environment and call `get_runtime_logs`. +2. Narrow by `since` and `q` before retrieving a broad window. Page completely + when the conclusion depends on absence. +3. Runtime logs are retained for approximately one hour on the base plan. An + empty result outside the retained window is expected. +4. Correlate runtime evidence with the latest deployment record when useful, + but do not claim causation from timing alone. +5. Report the observed error pattern, affected interval, likely cause, evidence, + and limitations. + +#### Is required configuration present? + +1. Resolve the environment and call `list_variables`. +2. Report keys and metadata only. Secret entries have `isSecret: true` and no + value; a missing secret value is expected. +3. If a key is absent, exhaust pagination before concluding it is missing. +4. If the value must be created or changed, stop the MCP workflow and route to + `webflow-cli:cloud` without requesting the value in chat. + +#### 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: + +1. Resolve the environment and call `trigger_deployment` with its default dry + run. +2. If preview rejects the target as unsupported, make no mutation and route the + user to a fresh CLI deployment. +3. If preview succeeds, show the returned branch and explain that execution + deploys its latest commit, not local files. +4. Require the user to type `confirm`. +5. Generate one stable `idempotency_key`, execute with `dry_run: false`, and + reuse that key for every retry. +6. The action returns no deployment ID. Poll `list_deployments`, identify the + new record, and use `get_deployment` until it leaves an active state or the + bounded monitoring period ends. + +For a retry or rollback: + +1. Select the exact prior deployment and call `redeploy` with its default dry + run. +2. If preview rejects the target as unsupported, make no mutation and route the + user to a fresh CLI deployment. +3. If preview succeeds, show the returned commit hash and message. Explain that + this creates a fresh build at that commit. +4. Require `confirm`, execute with `dry_run: false` and a stable + `idempotency_key`, then poll as described above. + +### 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. +- Never conclude that a paginated resource is absent after one page. +- Never translate an empty list into a tool failure. +- The live action schema is authoritative for arguments and response fields. + Never fabricate IDs, fields, statuses, branches, commits, or live 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. + +### 5. Handle explicit administrative requests + +These operations are supported but are not the skill's primary workflow. For `update_app`: 1. Fetch the current app with `get_app`. -2. Show the exact name and description change. Explain that this cannot change - source configuration or deployments. -3. Require confirmation, call `update_app`, then verify with `get_app`. +2. Show the exact name or description change and require `confirm`. +3. Call `update_app`, then verify with `get_app`. 4. Pass `description: null` to clear a description. Do not use an empty string. For `delete_variable`: -1. Call `delete_variable` with the default dry run. The preview confirms whether - the exact key exists and returns no value. -2. If `exists` is false, report that no variable was deleted. Do not request - confirmation or call the destructive operation. -3. If the preview cannot confirm existence, stop and report the error. Do not - treat an incomplete paginated read as a missing key. -4. If `exists` is true, show the app, environment, and key, then warn that the - action permanently deletes the variable. -5. Require confirmation, then call `delete_variable` with `dry_run: false` - exactly once. Treat its successful `deleted: true` response as success even - when the backend body has no readable message. - -For `trigger_deployment`: - -1. Call it with the default dry run and show the connected branch. -2. Explain that execution deploys the branch's latest commit, not local files. -3. Require confirmation. -4. Generate one stable `idempotency_key` before the first call with - `dry_run: false`. Reuse the same key for every retry. -5. The action returns no deployment ID. Poll `list_deployments`, identify the - new record, and use `get_deployment` until it leaves an active state or the - bounded monitoring period ends. - -For `redeploy`: - -1. Select the previous deployment and call `redeploy` with the default dry run. -2. Show its exact commit hash and message. Explain that this creates a fresh - build at that commit. -3. Require confirmation. -4. Execute with `dry_run: false` and a stable `idempotency_key`, then poll as - described for `trigger_deployment`. +1. Preview with the default dry run. +2. If `exists` is false, report that nothing was deleted and stop. +3. If `exists` is true, show the app, environment, and key; warn that deletion + is permanent and require `confirm`. +4. Call once with `dry_run: false`. Treat `deleted: true` as success even if the + backend message is absent. For `delete_app`: -1. Call it with the default dry run. -2. Report the returned `deletionMode`: - - `archive`: reversible archival of the Cloud app. - - `hard_delete`: permanent deletion of the attached app's project and - environments. -3. Require confirmation after the mode-specific warning. -4. Call with `dry_run: false` exactly once. A successful `deleted: true` - response remains success even when the backend body has no readable message. - Do not infer failure from an unavailable post-delete resource. +1. Preview with the default dry run and report `deletionMode`. +2. 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. +3. Require `confirm`, then call once with `dry_run: false`. +4. Treat `deleted: true` as success even when the resource cannot be fetched + afterward. -### Phase 6: Handle errors +### 6. Handle errors and report - `401` or `403`: report the authentication or permission problem; do not retry. @@ -182,91 +202,66 @@ For `delete_app`: silently switch targets. - `429`: honor the backoff signal before a bounded retry. - `5xx` on a read: retry a bounded number of times. -- `5xx` on a mutation: treat the outcome as uncertain. Reconcile with list/get - actions before considering a retry. -- A successful mutation response with sparse or unreadable backend content is - not a failure. Do not retry a deletion; poll deployment records when a deploy - action cannot report its final status. +- `5xx` on a mutation: treat the outcome as uncertain and reconcile it before + considering a retry. - Rejected cursor: restart that listing without the cursor and page again. - `GITHUB_APP_NOT_INSTALLED`: provide the returned `installUrl`, require the - user to reconnect GitHub, then retry only after reconnection. - -An empty list is a valid success. Do not translate it into a tool failure. - -### Phase 7: Report - -State: - -- The app and environment selected -- The actions performed -- The deployment status or mutation outcome -- Any pagination, retention, permission, or uncertainty limitation -- The next required user action only when the workflow cannot continue + user to reconnect GitHub, and retry only after reconnection. +- An unsupported deployment preview is a capability boundary, not a reason to + bypass MCP with a direct API call. -Do not expose sensitive log content or environment-variable values. +Final reports must state the selected app and environment, evidence inspected, +observed status, inferred cause when supported, confidence or limitations, any +remediation performed, and the next required user action only when blocked. ## Examples -### Inspect a failed deployment +### Diagnose a failed deployment **User:** "Why did the latest production deployment fail?" -1. Call `webflow_guide_tool`. -2. Resolve the app with `list_apps`. -3. Resolve production with `list_environments`. -4. Fetch the latest record with `list_deployments`, then `get_deployment`. -5. If logs are available, call `get_build_logs` with a narrow error query. -6. Redact sensitive values and report the failed phase, relevant timestamps, - concise root cause, and evidence. - -### Trigger a deployment - -**User:** "Deploy the latest commit for production." - 1. Resolve the app and production environment. -2. Call `trigger_deployment` as a dry run. -3. Report the exact connected branch and request `confirm`. -4. After confirmation, execute with a stable idempotency key. -5. Poll the deployment list and report the resulting status. +2. Fetch the latest deployment and inspect its status and timeline. +3. If `logsAvailable` is true, retrieve narrowly filtered build/deploy logs. +4. Redact sensitive content and report the failed phase, evidence, likely root + cause, and limitations. +5. If the logs are empty, report that no matching server-side logs are + retrievable; do not call that evidence of success. -### Set a secret +### Diagnose a known CLI build failure -**User:** "Set `DATABASE_URL` in production." +**User:** "I deployed with the CLI and the build failed. What went wrong?" -Do not request the value and do not call `data_apps_tool`. State that MCP cannot -create or update environment variables. Route the task to -`webflow-cli:cloud`, using the installed CLI's help and a secret-safe input -method. +Explain that the client-side build output is not sent to Webflow. Inspect the +deployment record and any available server-side deployment evidence, then use +the originating CLI output for the local build failure. Do not infer the local +failure from empty MCP logs. -### Delete an environment variable +### Retry a failed deployment -**User:** "Delete `OLD_FEATURE_FLAG` from staging." +**User:** "Retry the failed production deployment." -1. Resolve the app and staging environment. -2. Call `delete_variable` with its default dry run. -3. If the preview confirms the key exists, disclose the exact target and stop - until the user types `confirm`. -4. Call `delete_variable` with `dry_run: false` once, then report the result. +1. Resolve the exact failed deployment. +2. Preview `redeploy` with its default dry run. +3. If supported, show the exact commit and require `confirm` before executing. +4. If unsupported, make no mutation and route to a fresh CLI deployment. +5. After execution, poll and report the new deployment's status. -### Delete an app +### Check or set configuration -**User:** "Delete my staging Cloud app." +**User:** "Is `DATABASE_URL` configured in production?" -1. Resolve the exact app. -2. Call `delete_app` as a dry run. -3. Explain whether the operation archives or permanently deletes it. -4. Stop until the user types `confirm`. -5. Execute once and report the returned outcome. +List variable metadata and report whether the key exists without exposing a +value. If the user then asks to set it, route to `webflow-cli:cloud` and keep the +value outside chat. ## Guidelines -- Call `webflow_guide_tool` first. -- Prefer MCP over CLI for supported operations on existing Cloud apps. -- Use CLI only for app creation, building local source and deploying it to - Webflow Cloud, and environment-variable creation or updates. +- 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 app creation, local builds and deployments, and variable writes. - Never use `data_apps_tool` for Designer variables. -- Never mutate without an itemized preview and explicit `confirm`. -- Never retry an uncertain mutation before reconciling observable state. - Never expose secrets from variables, logs, errors, or URLs. -- Never conclude that a paginated resource is absent after one page. -- Never fabricate IDs, deployment status, action arguments, or live URLs. +- Never mutate without an exact preview and explicit `confirm`. +- Never retry an uncertain mutation before reconciling observable state. From 40246a9e9cb4721c449d938e25a9d6634eed40b1 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Mon, 24 Aug 2026 20:58:34 -0300 Subject: [PATCH 03/10] CLD-2297 Add Cloud environment management workflows --- .../webflow-skills/skills/cloud-apps/SKILL.md | 114 ++++++++++++++++-- 1 file changed, 104 insertions(+), 10 deletions(-) diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index 58080f2..ea512e1 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -1,13 +1,13 @@ --- name: webflow-mcp:cloud-apps -description: Monitor and troubleshoot existing Webflow Cloud apps through Webflow MCP. Use when identifying apps or environments, checking domains or deployed versions, reviewing deployment health and history, diagnosing build, deploy, or runtime failures, verifying environment-variable keys, or previewing a retry, rollback, or GitHub branch deployment. Do not use for design/CSS variables, creating Cloud apps, deploying local source, or creating/updating environment-variable values. +description: Monitor, troubleshoot, and manage environments for existing Webflow Cloud apps through Webflow MCP. Use when identifying apps or environments, checking domains or deployed versions, diagnosing failures, verifying environment-variable keys, correcting branch or mount mappings, provisioning branch environments, or previewing a retry, rollback, or GitHub branch deployment. Do not use for design/CSS variables, creating Cloud apps, deploying local source, or passing environment-variable values through MCP. --- # Webflow Cloud Apps -Use `data_apps_tool` to answer operational questions about existing Webflow -Cloud apps. Start from the user's outcome, gather only the evidence needed, and -distinguish observations from conclusions. +Use `data_apps_tool` to answer operational questions and manage environments for +existing 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 creating an app, building or deploying local source, or creating or updating environment @@ -19,13 +19,14 @@ recovered through MCP. ### 1. Establish scope 1. Call `webflow_guide_tool` before any other Webflow MCP tool. -2. Use only Webflow MCP tools for Webflow operations. Never call Webflow APIs - directly. +2. Use Webflow MCP tools for Webflow operations except the explicit CLI handoff + for environment-variable values. Never call Webflow APIs directly. 3. Include the required `context` parameter in every tool call. Write 15-25 words in third-person perspective. 4. Route by the capability the task requires: - Use `data_apps_tool` to inspect existing apps, environments, domains, - deployment records, available server-side logs, and variable metadata. + deployment records, available server-side logs, and variable metadata; to + create, update, or delete environments; and to enqueue deployments. - Use `data_variable_tool` for Designer color, size, font, and CSS variables. - Use `webflow-cli:cloud` for app creation, local builds and deployments, or creating and updating environment-variable values. @@ -33,8 +34,9 @@ recovered through 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, route to the installed Webflow CLI's built-in help and -require a hidden prompt, stdin, or protected file. Do not guess a CLI command. +For a create or update, use the installed Webflow CLI's `apps env-vars` help and +require a hidden prompt, stdin, or protected file. Never pass a secret as a +positional argument. ### 2. Resolve the target @@ -118,6 +120,58 @@ unambiguous. 4. If the value must be created or changed, stop the MCP workflow and route to `webflow-cli:cloud` without requesting the value in chat. +#### Why is this environment serving the wrong branch or route? + +1. Resolve the exact environment and report its current branch, mount, deploy + URL, and latest deployment status. +2. Compare the current branch and mount with the user's intended mapping. If + the request is only diagnostic, stop after reporting the mismatch. +3. 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. +4. Require `confirm`, call `update_environment` once, and report the returned + environment and `mountRefreshStatus`. +5. If the response is unreadable or the outcome is uncertain, reconcile with + `list_environments`, filtering by the expected new branch when available and + keeping the selected filters unchanged while paging, before considering a + retry. +6. A failed or unknown mount refresh does not mean the environment update was + rolled back. Report routing as uncertain and do not retry the update solely + because the refresh failed. +7. 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 + +1. Resolve the existing app. Page through `list_environments` to check whether + the requested branch or mount is already in use. +2. Show the proposed branch and mount. Explain that `create_environment` is + immediate, has no dry run, and creates a mapping without deploying code. +3. Generate one stable `idempotency_key`, require `confirm`, and call + `create_environment`. Reuse that key for retries of the same creation. +4. Report the returned environment and `mountRefreshStatus`. A failed refresh + means creation succeeded but routing may be incomplete; do not retry the + creation. If the environment is null or the outcome is otherwise uncertain, + reconcile through a complete `list_environments` search before retrying. +5. Determine whether configuration is required before deployment. Use only + user-identified keys, a protected local file, or keys inspected from a + user-selected reference environment. Never copy values returned by MCP. +6. If values are required, switch to the installed Webflow CLI and inspect + `webflow apps env-vars --help`. Pass the resolved app and environment IDs + explicitly. Use `set` with stdin or a hidden prompt, or `import` with a + protected `.env` file. A secret import marks every key in that file secret, + so use separate inputs when secrecy is mixed. +7. Run the CLI operation with `--dry-run` first. Show only target IDs, keys, and + intended secrecy, then require a separate `confirm` before executing it. +8. Verify the required keys and secrecy through paginated `list_variables`. + Never quote or report plaintext values. If a write or import partially + fails, stop before deployment and leave the environment intact. +9. Call `trigger_deployment` with its default dry run. If supported, show the + branch, explain that branch HEAD rather than local files will deploy, and + require a separate `confirm`. +10. Execute with `dry_run: false` and a stable deployment `idempotency_key`. + Reuse that key for retries of the same deployment request, then monitor the + new deployment as described below. + #### 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 @@ -163,6 +217,8 @@ For a retry or rollback: - Require an itemized preview and the exact word `confirm` before every mutation. - Reconcile an uncertain mutation through observable state before retrying it. +- Never delete a newly created environment automatically when configuration or + deployment fails. Report the partial state and wait for an explicit request. ### 5. Handle explicit administrative requests @@ -184,6 +240,17 @@ For `delete_variable`: 4. Call once with `dry_run: false`. Treat `deleted: true` as success even if the backend message is absent. +For `delete_environment`: + +1. 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. +2. Explain that deletion is irreversible and is rejected for the app's last + environment. Require `confirm`. +3. Call once with `dry_run: false`. Treat `deleted: true` as success. +4. A failed or null `mountRefreshStatus` means deletion succeeded but routing + cleanup is failed or uncertain. Report it and never retry the delete. + For `delete_app`: 1. Preview with the default dry run and report `deletionMode`. @@ -204,6 +271,10 @@ For `delete_app`: - `5xx` on a read: retry a bounded number of times. - `5xx` on a mutation: treat the outcome as uncertain and reconcile it before considering a retry. +- Duplicate environment branch or mount: report the conflicting environment; + do not silently update or delete it. +- Partial CLI variable import: report the failed keys without values and stop + before deployment. Do not roll back successful keys or delete the environment. - Rejected cursor: restart that listing without the cursor and page again. - `GITHUB_APP_NOT_INSTALLED`: provide the returned `installUrl`, require the user to reconnect GitHub, and retry only after reconnection. @@ -247,6 +318,27 @@ failure from empty MCP logs. 4. If unsupported, make no mutation and route to a fresh CLI deployment. 5. After execution, poll and report the new deployment's status. +### Correct an environment mapping + +**User:** "Production is serving the preview branch at `/app`. Point it back to +`main` at `/`." + +Resolve production, show its current and proposed branch and mount, explain +that the update does not deploy `main`, and require `confirm`. Apply the update, +reconcile the environment, and preview a separate branch-HEAD deployment only +if the user also asked to deploy it. + +### 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`." + +Check for branch and mount conflicts, confirm and create the environment, then +use the CLI to dry-run and import the protected file without displaying values. +Confirm the import separately, verify its keys through MCP, and only then +preview and confirm the branch-HEAD deployment. Stop before deployment if any +required variable fails and leave the environment in place. + ### Check or set configuration **User:** "Is `DATABASE_URL` configured in production?" @@ -260,8 +352,10 @@ value outside chat. - 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 app creation, local builds and deployments, and variable writes. +- Use CLI for app creation, local builds and deployments, and 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. +- Never deploy a newly created environment until required configuration has + been verified or the user has established that none is needed. From 6d3b3c3e89b8cca00cfffacd6c911cb674feccdb Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Wed, 26 Aug 2026 14:26:09 -0300 Subject: [PATCH 04/10] fix(skills): avoid fixed Cloud log retention --- plugins/webflow-skills/.codex-plugin/plugin.json | 2 +- plugins/webflow-skills/skills/cloud-apps/SKILL.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/webflow-skills/.codex-plugin/plugin.json b/plugins/webflow-skills/.codex-plugin/plugin.json index 077e236..74a2bb2 100644 --- a/plugins/webflow-skills/.codex-plugin/plugin.json +++ b/plugins/webflow-skills/.codex-plugin/plugin.json @@ -39,7 +39,7 @@ "mcpServers": "./.mcp.json", "interface": { "displayName": "Webflow Skills", - "shortDescription": "Manage CMS, Cloud apps, Designer, components, and CLI workflows", + "shortDescription": "Manage CMS, Cloud apps, Designer, Code Components, and CLI workflows", "longDescription": "Use Webflow Skills in Codex to manage CMS content, inspect and operate Webflow Cloud apps, audit site health, optimize assets, check links, apply FlowKit naming, manage custom code, build and inspect Designer pages and components, create and deploy Code Components, run Webflow CLI workflows, and prepare safe publishing workflows with Webflow MCP.", "developerName": "Webflow", "category": "Productivity", diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index ea512e1..a84321e 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -104,8 +104,8 @@ unambiguous. 1. Resolve the exact environment and call `get_runtime_logs`. 2. Narrow by `since` and `q` before retrieving a broad window. Page completely when the conclusion depends on absence. -3. Runtime logs are retained for approximately one hour on the base plan. An - empty result outside the retained window is expected. +3. Runtime logs may be unavailable because of retention. Treat an empty result + as no retrievable logs and report the limitation. 4. Correlate runtime evidence with the latest deployment record when useful, but do not claim causation from timing alone. 5. Report the observed error pattern, affected interval, likely cause, evidence, From 446ea9f56f11c291df894603403b96f81b1766c1 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Fri, 28 Aug 2026 18:20:31 -0300 Subject: [PATCH 05/10] fix(skills): validate Cloud environment mounts --- .../webflow-skills/skills/cloud-apps/SKILL.md | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index a84321e..cf8bdfb 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -126,49 +126,55 @@ unambiguous. URL, and latest deployment status. 2. Compare the current branch and mount with the user's intended mapping. If the request is only diagnostic, stop after reporting the mismatch. -3. For a correction, show the exact before-and-after mapping. Explain that +3. If the correction changes the mount, call `get_app` and apply the live mount + guidance before previewing the mutation. Stop before confirmation when the + proposed mount is invalid. +4. 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. -4. Require `confirm`, call `update_environment` once, and report the returned +5. Require `confirm`, call `update_environment` once, and report the returned environment and `mountRefreshStatus`. -5. If the response is unreadable or the outcome is uncertain, reconcile with +6. If the response is unreadable or the outcome is uncertain, reconcile with `list_environments`, filtering by the expected new branch when available and keeping the selected filters unchanged while paging, before considering a retry. -6. A failed or unknown mount refresh does not mean the environment update was +7. A failed or unknown mount refresh does not mean the environment update was rolled back. Report routing as uncertain and do not retry the update solely because the refresh failed. -7. If the branch changed and the user wants its code deployed, treat +8. 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 -1. Resolve the existing app. Page through `list_environments` to check whether - the requested branch or mount is already in use. -2. Show the proposed branch and mount. Explain that `create_environment` is +1. Resolve the existing app, call `get_app`, and apply the live mount guidance + before previewing the mutation. Stop before confirmation when the proposed + mount is invalid. +2. Page through `list_environments` to check whether the requested branch or + mount is already in use. +3. Show the proposed branch and mount. Explain that `create_environment` is immediate, has no dry run, and creates a mapping without deploying code. -3. Generate one stable `idempotency_key`, require `confirm`, and call +4. Generate one stable `idempotency_key`, require `confirm`, and call `create_environment`. Reuse that key for retries of the same creation. -4. Report the returned environment and `mountRefreshStatus`. A failed refresh +5. Report the returned environment and `mountRefreshStatus`. A failed refresh means creation succeeded but routing may be incomplete; do not retry the creation. If the environment is null or the outcome is otherwise uncertain, reconcile through a complete `list_environments` search before retrying. -5. Determine whether configuration is required before deployment. Use only +6. Determine whether configuration is required before deployment. Use only user-identified keys, a protected local file, or keys inspected from a user-selected reference environment. Never copy values returned by MCP. -6. If values are required, switch to the installed Webflow CLI and inspect +7. If values are required, switch to the installed Webflow CLI and inspect `webflow apps env-vars --help`. Pass the resolved app and environment IDs explicitly. Use `set` with stdin or a hidden prompt, or `import` with a protected `.env` file. A secret import marks every key in that file secret, so use separate inputs when secrecy is mixed. -7. Run the CLI operation with `--dry-run` first. Show only target IDs, keys, and +8. Run the CLI operation with `--dry-run` first. Show only target IDs, keys, and intended secrecy, then require a separate `confirm` before executing it. -8. Verify the required keys and secrecy through paginated `list_variables`. +9. Verify the required keys and secrecy through paginated `list_variables`. Never quote or report plaintext values. If a write or import partially fails, stop before deployment and leave the environment intact. -9. Call `trigger_deployment` with its default dry run. If supported, show the +10. Call `trigger_deployment` with its default dry run. If supported, show the branch, explain that branch HEAD rather than local files will deploy, and require a separate `confirm`. -10. Execute with `dry_run: false` and a stable deployment `idempotency_key`. +11. Execute with `dry_run: false` and a stable deployment `idempotency_key`. Reuse that key for retries of the same deployment request, then monitor the new deployment as described below. @@ -323,10 +329,12 @@ failure from empty MCP logs. **User:** "Production is serving the preview branch at `/app`. Point it back to `main` at `/`." -Resolve production, show its current and proposed branch and mount, explain -that the update does not deploy `main`, and require `confirm`. Apply the update, -reconcile the environment, and preview a separate branch-HEAD deployment only -if the user also asked to deploy it. +Resolve production and call `get_app` because the mount would change. Apply the +live mount guidance to the proposed `main` at `/` mapping. Continue to the +before-and-after preview and require `confirm` only when the mapping is valid; +otherwise stop before confirmation and report the required correction. Apply +and reconcile only a valid, confirmed mapping; preview a separate branch-HEAD +deployment only if the user also asked to deploy it. ### Provision, configure, and deploy a branch environment From 7d7b2bbd5d228daca992e674a37f2d12eb05d03f Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Sun, 30 Aug 2026 23:07:07 -0300 Subject: [PATCH 06/10] chore(plugins): restore plugin metadata --- .cursor-plugin/plugin.json | 4 ++-- plugins/webflow-skills/.claude-plugin/plugin.json | 4 ++-- plugins/webflow-skills/.codex-plugin/plugin.json | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 4c4ad3d..4f787e9 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webflow", - "version": "1.0.8", - "description": "Production-ready agent skills for Webflow - CMS management, Cloud app operations, site auditing, Designer tools, Code Components, CLI workflows, and safe publishing", + "version": "1.0.7", + "description": "Production-ready agent skills for Webflow - CMS management, site auditing, Designer tools, Code Components, CLI workflows, and safe publishing", "author": { "name": "Webflow", "email": "developers@webflow.com", diff --git a/plugins/webflow-skills/.claude-plugin/plugin.json b/plugins/webflow-skills/.claude-plugin/plugin.json index 54327cb..0f6e08b 100644 --- a/plugins/webflow-skills/.claude-plugin/plugin.json +++ b/plugins/webflow-skills/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "webflow-skills", - "description": "Production-ready skills for managing Webflow CMS content, operating Webflow Cloud apps, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes", - "version": "1.0.8", + "description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes", + "version": "1.0.7", "skills": "./skills/" } diff --git a/plugins/webflow-skills/.codex-plugin/plugin.json b/plugins/webflow-skills/.codex-plugin/plugin.json index 74a2bb2..a003428 100644 --- a/plugins/webflow-skills/.codex-plugin/plugin.json +++ b/plugins/webflow-skills/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webflow-skills", - "version": "1.0.8", - "description": "Production-ready skills for managing Webflow CMS content, operating Webflow Cloud apps, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes.", + "version": "1.0.7", + "description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes.", "author": { "name": "Webflow", "email": "developers@webflow.com", @@ -39,8 +39,8 @@ "mcpServers": "./.mcp.json", "interface": { "displayName": "Webflow Skills", - "shortDescription": "Manage CMS, Cloud apps, Designer, Code Components, and CLI workflows", - "longDescription": "Use Webflow Skills in Codex to manage CMS content, inspect and operate Webflow Cloud apps, audit site health, optimize assets, check links, apply FlowKit naming, manage custom code, build and inspect Designer pages and components, create and deploy Code Components, run Webflow CLI workflows, and prepare safe publishing workflows with Webflow MCP.", + "shortDescription": "Manage CMS, Designer, Code Components, and CLI workflows", + "longDescription": "Use Webflow Skills in Codex to manage CMS content, audit site health, optimize assets, check links, apply FlowKit naming, manage custom code, build and inspect Designer pages and components, create and deploy Code Components, run Webflow CLI workflows, and prepare safe publishing workflows with Webflow MCP.", "developerName": "Webflow", "category": "Productivity", "capabilities": ["Interactive", "Read", "Write"], @@ -54,8 +54,7 @@ "Inspect the current Designer page structure", "Build this Figma design in Webflow", "Create a new Webflow Code Component", - "Deploy a Webflow Cloud app", - "Inspect the latest deployment for my Webflow Cloud app" + "Deploy a Webflow Cloud app" ], "brandColor": "#146EF5", "composerIcon": "./assets/logo.svg", From e1097e3718cb5f6d50fcadb34927c984b4f19e5b Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Mon, 31 Aug 2026 00:51:36 -0300 Subject: [PATCH 07/10] feat(skills): support GitHub-source Cloud app workflows --- .../webflow-skills/skills/cloud-apps/SKILL.md | 95 +++++++++++++------ 1 file changed, 67 insertions(+), 28 deletions(-) diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index cf8bdfb..119c264 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -1,18 +1,18 @@ --- name: webflow-mcp:cloud-apps -description: Monitor, troubleshoot, and manage environments for existing Webflow Cloud apps through Webflow MCP. Use when identifying apps or environments, checking domains or deployed versions, diagnosing failures, verifying environment-variable keys, correcting branch or mount mappings, provisioning branch environments, or previewing a retry, rollback, or GitHub branch deployment. Do not use for design/CSS variables, creating Cloud apps, deploying local source, or passing environment-variable values through MCP. +description: 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. --- # Webflow Cloud Apps -Use `data_apps_tool` to answer operational questions and manage environments for -existing Webflow Cloud apps. Start from the user's outcome, gather only the -evidence needed, and distinguish observations from conclusions. +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 creating an app, -building or deploying local source, or creating or updating environment -variables. Client-side build output is not sent to Webflow and cannot be -recovered through MCP. +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 @@ -24,12 +24,12 @@ recovered through MCP. 3. Include the required `context` parameter in every tool call. Write 15-25 words in third-person perspective. 4. Route by the capability the task requires: - - Use `data_apps_tool` to inspect existing apps, environments, domains, - deployment records, available server-side logs, and variable metadata; to - create, update, or delete environments; and to enqueue deployments. + - 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 app creation, local builds and deployments, or - creating and updating environment-variable values. + - Use `webflow-cli:cloud` for CLI/local-source apps, local builds and + deployments, or creating and updating environment-variable values. 5. 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. @@ -48,22 +48,53 @@ list_environments(app_id) -> env_id list_deployments(app_id, env_id) -> deployment_id ``` -Use an identifier supplied by the user only after verifying it through the -corresponding get or list action. Use exact filters when available. If a list -action returns `nextCursor`, pass it back as `cursor` until `nextCursor` is null -whenever absence or completeness matters. - -If multiple resources match, present distinguishing metadata and require the -user to select one before any mutation. Auto-select only when one resource is -unambiguous. +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 + +1. Establish the app name, canonical GitHub repository URL, branch, optional + description, and whether it is standalone or attached to an existing site. +2. For a site-attached app, resolve the site ID. Omit `site_id` for standalone. +3. 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. +4. 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. +5. Call `create_app` with its default dry run. Show the repository, branch, + attachment, site when applicable, mount, and initial-deployment attempt. +6. 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. +7. 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. +8. 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. +9. 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? -1. Use `list_apps` to find the app and `get_app` for its metadata. -2. Use `list_environments` to report the branch, mount, deploy URL, and latest - deployment status exposed by the live response. +1. Use `list_apps` to find the app and `get_app` for its metadata, including + `sourceUrl` and `siteAttached`. +2. 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. 3. Use `get_app_domains` when the user asks where the app is reachable. 4. Explain that custom-domain results exclude the default `*.webflow.io` hostname. Domains for an app attached to a regular Webflow site may belong @@ -233,9 +264,17 @@ These operations are supported but are not the skill's primary workflow. For `update_app`: 1. Fetch the current app with `get_app`. -2. Show the exact name or description change and require `confirm`. -3. Call `update_app`, then verify with `get_app`. -4. Pass `description: null` to clear a description. Do not use an empty string. +2. For a name or description change, prepare and show the exact change. Pass + `description: null` to clear a description. +3. 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`. +4. Require `confirm`, call `update_app` once, and verify with `get_app`. An + unreadable response requires reconciliation before retrying. +5. A source update does not change an environment branch or deploy code. Treat + those as separate confirmed mutations. +6. 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`: @@ -360,7 +399,7 @@ value outside chat. - 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 app creation, local builds and deployments, and variable values. +- 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`. From 48953ddbf9ac864b26e4875a536f2ee2af8b0b69 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Mon, 31 Aug 2026 00:53:42 -0300 Subject: [PATCH 08/10] fix(skills): harden Cloud mutation and deployment workflows --- .../webflow-skills/skills/cloud-apps/SKILL.md | 190 ++++++++++-------- 1 file changed, 108 insertions(+), 82 deletions(-) diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index 119c264..29d2913 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -144,101 +144,125 @@ filter, pagination, cursor, and action-batching mechanics. #### Is required configuration present? -1. Resolve the environment and call `list_variables`. -2. Report keys and metadata only. Secret entries have `isSecret: true` and no +1. 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. +2. 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. +3. 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. +4. 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. +5. Report keys and metadata only. Secret entries have `isSecret: true` and no value; a missing secret value is expected. -3. If a key is absent, exhaust pagination before concluding it is missing. -4. If the value must be created or changed, stop the MCP workflow and route to - `webflow-cli:cloud` without requesting the value in chat. +6. 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. +7. 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? -1. Resolve the exact environment and report its current branch, mount, deploy - URL, and latest deployment status. +1. Resolve the exact environment and report its current branch, mount, + `publicUrl`, and latest deployment status. Report a null `publicUrl` without + constructing an address. 2. Compare the current branch and mount with the user's intended mapping. If the request is only diagnostic, stop after reporting the mismatch. -3. If the correction changes the mount, call `get_app` and apply the live mount - guidance before previewing the mutation. Stop before confirmation when the - proposed mount is invalid. +3. 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`. 4. 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. 5. Require `confirm`, call `update_environment` once, and report the returned - environment and `mountRefreshStatus`. -6. If the response is unreadable or the outcome is uncertain, reconcile with - `list_environments`, filtering by the expected new branch when available and - keeping the selected filters unchanged while paging, before considering a - retry. + environment, `publicUrl`, and `mountRefreshStatus`. +6. 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. 7. A failed or unknown mount refresh does not mean the environment update was - rolled back. Report routing as uncertain and do not retry the update solely - because the refresh failed. + rolled back. Report routing as uncertain and do not retry solely because the + refresh failed. 8. 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 -1. Resolve the existing app, call `get_app`, and apply the live mount guidance - before previewing the mutation. Stop before confirmation when the proposed - mount is invalid. +1. Resolve the existing app, call `get_app`, and validate the proposed mount + with `siteAttached` before previewing the mutation. 2. Page through `list_environments` to check whether the requested branch or mount is already in use. 3. Show the proposed branch and mount. Explain that `create_environment` is immediate, has no dry run, and creates a mapping without deploying code. 4. Generate one stable `idempotency_key`, require `confirm`, and call - `create_environment`. Reuse that key for retries of the same creation. -5. Report the returned environment and `mountRefreshStatus`. A failed refresh - means creation succeeded but routing may be incomplete; do not retry the - creation. If the environment is null or the outcome is otherwise uncertain, - reconcile through a complete `list_environments` search before retrying. -6. Determine whether configuration is required before deployment. Use only - user-identified keys, a protected local file, or keys inspected from a - user-selected reference environment. Never copy values returned by MCP. -7. If values are required, switch to the installed Webflow CLI and inspect - `webflow apps env-vars --help`. Pass the resolved app and environment IDs - explicitly. Use `set` with stdin or a hidden prompt, or `import` with a - protected `.env` file. A secret import marks every key in that file secret, - so use separate inputs when secrecy is mixed. -8. Run the CLI operation with `--dry-run` first. Show only target IDs, keys, and - intended secrecy, then require a separate `confirm` before executing it. -9. Verify the required keys and secrecy through paginated `list_variables`. - Never quote or report plaintext values. If a write or import partially - fails, stop before deployment and leave the environment intact. -10. Call `trigger_deployment` with its default dry run. If supported, show the - branch, explain that branch HEAD rather than local files will deploy, and - require a separate `confirm`. -11. Execute with `dry_run: false` and a stable deployment `idempotency_key`. - Reuse that key for retries of the same deployment request, then monitor the - new deployment as described below. + `create_environment`. Reuse that key only for exact retries. +5. 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. +6. A failed refresh means creation succeeded but routing may be incomplete. Do + not retry creation or delete the environment automatically. +7. 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: - -1. Resolve the environment and call `trigger_deployment` with its default dry - run. -2. If preview rejects the target as unsupported, make no mutation and route the - user to a fresh CLI deployment. -3. If preview succeeds, show the returned branch and explain that execution - deploys its latest commit, not local files. -4. Require the user to type `confirm`. -5. Generate one stable `idempotency_key`, execute with `dry_run: false`, and - reuse that key for every retry. -6. The action returns no deployment ID. Poll `list_deployments`, identify the - new record, and use `get_deployment` until it leaves an active state or the - bounded monitoring period ends. - -For a retry or rollback: - -1. Select the exact prior deployment and call `redeploy` with its default dry - run. -2. If preview rejects the target as unsupported, make no mutation and route the - user to a fresh CLI deployment. -3. If preview succeeds, show the returned commit hash and message. Explain that - this creates a fresh build at that commit. -4. Require `confirm`, execute with `dry_run: false` and a stable - `idempotency_key`, then poll as described above. +For a new deployment from the connected branch or a prior exact commit: + +1. Resolve the environment. For a retry or rollback, also resolve the exact + prior deployment. +2. 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. +3. 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`. +4. For `redeploy`, explain that the older commit runs with the environment's + current configuration, so compatibility is not guaranteed. +5. Show the returned branch or commit and explain that execution creates a new + GitHub build, not a deployment of local files. +6. 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. +7. 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. +8. 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. +9. 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. +10. 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 @@ -254,8 +278,9 @@ For a retry or rollback: - Require an itemized preview and the exact word `confirm` before every mutation. - Reconcile an uncertain mutation through observable state before retrying it. -- Never delete a newly created environment automatically when configuration or - deployment fails. Report the partial state and wait for an explicit request. +- 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 @@ -282,8 +307,8 @@ For `delete_variable`: 2. If `exists` is false, report that nothing was deleted and stop. 3. If `exists` is true, show the app, environment, and key; warn that deletion is permanent and require `confirm`. -4. Call once with `dry_run: false`. Treat `deleted: true` as success even if the - backend message is absent. +4. 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`: @@ -295,6 +320,8 @@ For `delete_environment`: 3. Call once with `dry_run: false`. Treat `deleted: true` as success. 4. A failed or null `mountRefreshStatus` means deletion succeeded but routing cleanup is failed or uncertain. Report it and never retry the delete. +5. 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`: @@ -303,8 +330,8 @@ For `delete_app`: while `hard_delete` permanently deletes the app and all its environments and cannot be undone. 3. Require `confirm`, then call once with `dry_run: false`. -4. Treat `deleted: true` as success even when the resource cannot be fetched - afterward. +4. 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 @@ -318,11 +345,10 @@ For `delete_app`: considering a retry. - Duplicate environment branch or mount: report the conflicting environment; do not silently update or delete it. -- Partial CLI variable import: report the failed keys without values and stop - before deployment. Do not roll back successful keys or delete the environment. -- Rejected cursor: restart that listing without the cursor and page again. -- `GITHUB_APP_NOT_INSTALLED`: provide the returned `installUrl`, require the - user to reconnect GitHub, and retry only after reconnection. +- 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. @@ -404,5 +430,5 @@ value outside chat. - 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. -- Never deploy a newly created environment until required configuration has - been verified or the user has established that none is needed. +- Keep repository, environment, configuration, and deployment changes separate. +- Preserve partial resources unless the user explicitly requests deletion. From 076ab2c650f852fcfe13ae3664c5dd06fae0d32b Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Mon, 31 Aug 2026 00:54:06 -0300 Subject: [PATCH 09/10] refactor(skills): remove duplicated Cloud workflow guidance --- .../webflow-skills/skills/cloud-apps/SKILL.md | 86 +++++-------------- 1 file changed, 23 insertions(+), 63 deletions(-) diff --git a/plugins/webflow-skills/skills/cloud-apps/SKILL.md b/plugins/webflow-skills/skills/cloud-apps/SKILL.md index 29d2913..f01554e 100644 --- a/plugins/webflow-skills/skills/cloud-apps/SKILL.md +++ b/plugins/webflow-skills/skills/cloud-apps/SKILL.md @@ -18,7 +18,8 @@ MCP. ### 1. Establish scope -1. Call `webflow_guide_tool` before any other Webflow MCP tool. +1. Call `webflow_guide_tool` before any other Webflow MCP tool. The live guide + and action schemas are authoritative for current arguments and responses. 2. Use Webflow MCP tools for Webflow operations except the explicit CLI handoff for environment-variable values. Never call Webflow APIs directly. 3. Include the required `context` parameter in every tool call. Write 15-25 @@ -34,9 +35,8 @@ 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, use the installed Webflow CLI's `apps env-vars` help and -require a hidden prompt, stdin, or protected file. Never pass a secret as a -positional argument. +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 @@ -270,10 +270,6 @@ For a new deployment from the connected branch or a prior exact commit: 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. -- Never conclude that a paginated resource is absent after one page. -- Never translate an empty list into a tool failure. -- The live action schema is authoritative for arguments and response fields. - Never fabricate IDs, fields, statuses, branches, commits, or live 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. @@ -335,14 +331,6 @@ For `delete_app`: ### 6. Handle errors and report -- `401` or `403`: report the authentication or permission problem; do not - retry. -- `404`: verify the complete app -> environment -> deployment chain; do not - silently switch targets. -- `429`: honor the backoff signal before a bounded retry. -- `5xx` on a read: retry a bounded number of times. -- `5xx` on a mutation: treat the outcome as uncertain and reconcile it before - considering a retry. - 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 @@ -352,73 +340,45 @@ For `delete_app`: - An unsupported deployment preview is a capability boundary, not a reason to bypass MCP with a direct API call. -Final reports must state the selected app and environment, evidence inspected, -observed status, inferred cause when supported, confidence or limitations, any -remediation performed, and the next required user action only when blocked. +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 -### Diagnose a failed deployment - -**User:** "Why did the latest production deployment fail?" - -1. Resolve the app and production environment. -2. Fetch the latest deployment and inspect its status and timeline. -3. If `logsAvailable` is true, retrieve narrowly filtered build/deploy logs. -4. Redact sensitive content and report the failed phase, evidence, likely root - cause, and limitations. -5. If the logs are empty, report that no matching server-side logs are - retrievable; do not call that evidence of success. - -### Diagnose a known CLI build failure +### Create a site-attached GitHub app -**User:** "I deployed with the CLI and the build failed. What went wrong?" +**User:** "Create `search-app` from `https://github.com/acme/search` on the +`main` branch and attach it to my marketing site at `/search`." -Explain that the client-side build output is not sent to Webflow. Inspect the -deployment record and any available server-side deployment evidence, then use -the originating CLI output for the local build failure. Do not infer the local -failure from empty MCP logs. +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. -### Retry a failed deployment +### Diagnose a failed deployment -**User:** "Retry the failed production deployment." +**User:** "Why did the latest production deployment fail?" -1. Resolve the exact failed deployment. -2. Preview `redeploy` with its default dry run. -3. If supported, show the exact commit and require `confirm` before executing. -4. If unsupported, make no mutation and route to a fresh CLI deployment. -5. After execution, poll and report the new deployment's status. +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 `/`." -Resolve production and call `get_app` because the mount would change. Apply the -live mount guidance to the proposed `main` at `/` mapping. Continue to the -before-and-after preview and require `confirm` only when the mapping is valid; -otherwise stop before confirmation and report the required correction. Apply -and reconcile only a valid, confirmed mapping; preview a separate branch-HEAD -deployment only if the user also asked to deploy it. +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`." -Check for branch and mount conflicts, confirm and create the environment, then -use the CLI to dry-run and import the protected file without displaying values. -Confirm the import separately, verify its keys through MCP, and only then -preview and confirm the branch-HEAD deployment. Stop before deployment if any -required variable fails and leave the environment in place. - -### Check or set configuration - -**User:** "Is `DATABASE_URL` configured in production?" - -List variable metadata and report whether the key exists without exposing a -value. If the user then asks to set it, route to `webflow-cli:cloud` and keep the -value outside chat. +Use the new-environment workflow, then apply its mandatory configuration gate +before routing to deployment. Preserve the environment if a later step fails. ## Guidelines From a9e688f8f880496cef546d2e3509285e93e70eb1 Mon Sep 17 00:00:00 2001 From: Nicolas Berrios Verboven Date: Mon, 31 Aug 2026 01:11:16 -0300 Subject: [PATCH 10/10] docs(readme): update Cloud apps skill description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6a2c89..5eeeb2c 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ All skills ship from the single `webflow-skills` plugin. | webflow-mcp:flowkit-naming | Apply Webflow's official FlowKit CSS naming conventions | | webflow-mcp:designer-tools | Build and manage page structure, elements, components, and styles in Webflow Designer | | webflow-mcp:figma-to-webflow | Build pages, sections, components, or full sites from Figma designs using Figma MCP and Webflow MCP | -| webflow-mcp:cloud-apps | Monitor and troubleshoot existing Webflow Cloud apps, deployments, configuration, domains, and runtime behavior | +| webflow-mcp:cloud-apps | Create and operate GitHub-source Webflow Cloud apps, including environments, deployments, configuration checks, domains, and diagnostics | ### Webflow CLI Skills