# Install Webstudio Native CMP with the Webstudio MCP > Instructions for AI agents (Claude Code, Codex, Cursor and others) that are connected to a Webstudio project through the Webstudio MCP or CLI. Follow them to add Webstudio Native CMP, a free cookie, script and embed consent manager built from native Webstudio instances, to the user's project. - Engine version: 1.2.1 - Install bundle (JSON, served as .txt): https://nativecmp.com/install/steps.txt - Installer script: https://nativecmp.com/install/install.js - Human documentation: https://nativecmp.com/docs · Config generator: https://nativecmp.com/generator · Service examples: https://nativecmp.com/examples ## Rules - Work in the directory that is linked to the user's Webstudio project (`npx webstudio@latest link` with a share link that has build permissions). - Download the bundle and script as raw files, for example with `curl -fsSL`. The bundle is JSON and the script is an ES module; both are served with `.txt` and `.js` extensions so they aren't blocked by bot protection. Do not summarize or retype them: the JSX, tokens and engine code must be passed unchanged. - Existing design tokens, CSS variables and Custom Code of the project are kept. Never remove code the user already has. - Do not publish, and do not change pages other than the ones the user agreed to. Summarize what you changed at the end. - Consent texts and service lists are the user's responsibility. Do not claim the result makes a site legally compliant. ## 1. Ask the user first 1. Which page gets the Consent Manager (default: Home) and whether it should be added to every page (default: yes). 2. Which services the site uses. Recommend building the configuration in the generator (https://nativecmp.com/generator): its **Updating an existing installation** section contains `consentServices` and `consentTranslations` JSON that you can save to files. Without it, the installer adds an English, German, Spanish and Arabic starter configuration that only contains the consent manager itself. 3. Where the **Privacy settings** link should go (usually the footer). You need the instance id of that parent. ## 2. Option A: run the installer (recommended if you can run shell commands) ```sh curl -fsSL https://nativecmp.com/install/install.js -o native-cmp-install.mjs # save as .mjs: it is an ES module node native-cmp-install.mjs --page / --attach all ``` Options: | Option | Default | Meaning | | --- | --- | --- | | `--page ` | `/` | Page that receives the Consent Manager before it becomes a shared Slot. | | `--attach all\|none\|/a,/b` | `all` | Pages that get the shared Slot as well. | | `--services ` | starter config | JSON array for the `consentServices` variable (from the generator). | | `--translations ` | starter config | JSON array for the `consentTranslations` variable (from the generator). | | `--privacy-link-parent ` | none | Adds a Privacy settings button inside this instance. | | `--custom-code install\|skip` | `install` | Adds the engine to Project Settings → Custom Code, or updates an older engine in place. | | `--force` | off | Add a Consent Manager even if the page already has one. Without it, a second run only updates the engine, tokens and CSS variables. | | `--bundle ` | `https://nativecmp.com/install/steps.txt` | Use another bundle. | Requires Node.js 18 or newer. The script only runs `npx webstudio@latest ` commands (the same tools as in option B). Tell the user before running it, and show them its output. ## 3. Option B: the same steps as MCP tool calls Load `https://nativecmp.com/install/steps.txt` as `bundle`. Keep the ids you receive from each call. 1. **Page**: `list-pages` → the target page's `rootInstanceId` (the Body). `list-instances` with its `pagePath`: if an instance labelled `Consent Manager` exists, stop and update its variables instead (see Updating). 2. **Breakpoint**: `list-breakpoints` → the id of the breakpoint with `maxWidth: 479` (no `minWidth`, no `condition`). If there is none: `create-breakpoint` with `bundle.mobileBreakpoint`. 3. **CSS variables**: `list-css-variables`, then `define-css-variable` with `{"vars": {…}}` containing only the entries of `bundle.cssVariables` that don't exist yet. 4. **Design tokens**: `list-design-tokens` (page with `cursor`), then `create-design-token` with `{"tokens": […]}` for every entry of `bundle.tokens` whose `name` doesn't exist yet. Replace each `"breakpoint": "$mobileBreakpointId"` with the id from step 2. Declarations without `breakpoint` belong to the base breakpoint. 5. **Custom Code**: `get-project-settings` → `meta.code`. If it contains `data-cmp-engine=`, replace its `` and `` blocks with the ones from `bundle.customCode` (this keeps the user's `window.cmpConfig`). Otherwise put `bundle.customCode` at the very top, before any analytics or tag manager code. Save with `update-project-settings` `{"meta": {"code": "…"}}`. 6. **Consent Manager root**: `insert-fragment` with `{"parentInstanceId": , "conflictResolution": "ours", "fragment": bundle.consentManager.skeleton}` → `rootInstanceIds[0]` is the root. 7. **Variables**: `create-variable` twice with `scopeInstanceId` = root: `consentServices` and `consentTranslations`, each `{"type": "json", "value": …}` from the generator or `bundle.consentManager.variables`. 8. **Collections**, strictly in the order of `bundle.consentManager.collections`: 1. below `Service Registry`: data `consentServices` 2. below `Languages`: data `consentTranslations`, then rename the item parameter to `language` 3. below `Purposes`: data `language?.purposes` 4. below `Services`: data `collectionItem?.services` For each entry: `list-instances` on the page and find the instance whose `label` equals `parentLabel` below the root. Call `insert-collection` with `{"parentInstanceId": , "insertIndex": insertIndex, "conflictResolution": "ours", "data": {"type": "expression", "value": data}, "itemFragment": itemFragment}`. If `renameItemParameterTo` is set, rename the new item parameter before the next collection: `apply-patch` with `{"baseVersion": , "transactions": [{"id": "rename-item", "payload": [{"namespace": "dataSources", "patches": [{"op": "replace", "path": [, "name"], "value": renameItemParameterTo}]}]}]}`. Nested item fragments reference that name. 9. **Check**: `verify-bindings` must report 0 findings. 10. **Shared Slot**: `extract-slot` with `{"instanceSelector": [, ], "label": "Consent Manager"}`, then `attach-slot` with `{"sourceSlotId": , "parentInstanceId": , "label": "Consent Manager"}` for every other HTML page the user wants. 11. **Privacy settings link**: `insert-fragment` with `bundle.privacySettingsLink` into the parent the user chose, `conflictResolution: "ours"`. ## 4. Block services, embeds and videos The consent manager only controls code that is marked for it: - **Head scripts** (analytics, pixels) go into Custom Code below the engine as blocked scripts: `type="text/plain"`, `data-cmp-service=""`, and `data-src="…"` instead of `src`. Copy exact snippets from the generator or https://nativecmp.com/examples. - **Embeds** (Google Maps, Calendly, forms): wrap them in a Consent Gate. The generator copies ready-made gates as Webstudio clipboard data for the user to paste; as an agent, rebuild the structure with `insert-fragment`: a wrapper with `data-cmp-gate=""` containing a notice (`data-cmp-gate-notice`, buttons with `data-cmp-action="accept-once"` and `accept-always`) and the content (`data-cmp-gate-content`) with an HTML Embed whose iframe or script uses `data-src` and `data-cmp-service`. - **YouTube and Vimeo**: keep Webstudio's native components inside a gate with `data-cmp-gate-mode="interaction"`, and turn off their preview, autoplay and preconnect settings so nothing loads before consent. Details: https://nativecmp.com/docs#native-video - Every service name used in markup must exist in `consentServices` and have a title and description in each `consentTranslations` entry. Attribute reference: https://nativecmp.com/docs#attributes ## Updating - **Engine**: run the installer again (`node native-cmp-install.mjs --page `). On a page that already has the Consent Manager it only updates the engine in Custom Code and adds missing tokens and CSS variables. Without shell access, repeat steps 2 to 5. - **Services and texts**: `list-variables`, then `update-variable` on `consentServices` and `consentTranslations` of the Consent Manager root. - **Contextual consent only** (no notice on page load, consent is asked by gates): set `noNotice: true` in `window.cmpConfig` in Custom Code. ## Troubleshooting - `Unknown dependency "language"` or empty modal rows: the item parameter of the Languages collection was not renamed before the nested collections were inserted. Delete the Consent Manager root and repeat steps 6 to 8. - Unstyled notice: the design tokens were not created (step 4) or were created without the mobile breakpoint id. - Nothing is blocked: the engine is missing from Custom Code, or a script still uses `src` instead of `data-src`. - The notice never appears: check `noNotice` and `mustConsent` in `window.cmpConfig`, and whether the page contains the Consent Manager Slot.