Skip to main content
skill CX Codex

webflow-mcp:compress-cms-image — Claude Code skill: how to install

Converts and compresses Webflow CMS item images to WebP or AVIF formats. It updates asset references and republishes the collection item through Webflow MCP.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add webflow/webflow-skills --skill webflow-mcp:compress-cms-image -a claude-code
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a claude-code
Open on GitHub

What webflow-mcp:compress-cms-image does

The skill asks for collection and item identifiers, target field slugs, desired format, and compression quality (recommending 85 for WebP or 75 for AVIF). It inspects the collection schema using Webflow MCP's data_cms_tool to locate fields typed as Image or MultiImage. Assets are downloaded to /tmp/ and converted locally via Python's Pillow library.

After calculating the MD5 hash of each processed image, the skill requests presigned S3 upload credentials via data_assets_tool. It streams the converted file to S3, replaces the asset references on the target CMS item, and triggers publication. Every mutation pauses for approval until you type confirm.

Images nested inside Rich Text fields are strictly omitted from processing. An active Webflow MCP configuration and a working Python 3 setup are mandatory prerequisites.

What it helps with

  • convert Webflow CMS images to WebP or AVIF
  • reduce file sizes across Image and MultiImage schema fields
  • upload compressed assets directly to Webflow storage via presigned S3 URLs
  • update collection item fields and republish changes

Example prompts for the agent

  • Compress all images for item item_123 in collection col_456 to webp
  • Optimize the main-image field in my Webflow blog collection with avif quality 75
  • Convert MultiImage gallery fields to webp with quality 85 and republish

How to install webflow-mcp:compress-cms-image

1Skills CLI (Vercel)

npx skills add webflow/webflow-skills --skill webflow-mcp:compress-cms-image -a claude-code
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a claude-code

2Manually: put the files in place

~/.claude/skills/webflow-compress-cms-image/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/webflow-compress-cms-image/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about webflow-mcp:compress-cms-image

How do I install webflow-mcp:compress-cms-image in Claude Code?

Run npx skills add webflow/webflow-skills --skill webflow-mcp:compress-cms-image -a claude-code in your terminal.

What does webflow-mcp:compress-cms-image do?

It fetches images from a Webflow CMS item, converts them locally to WebP or AVIF with Pillow, uploads them back to Webflow Assets, and republishes the item.

Does this skill support images inside Rich Text fields?

No, it explicitly skips Rich Text HTML markup. Only dedicated Image and MultiImage schema fields are supported.

Source text

SKILL.md · MIT
---
name: webflow-mcp:compress-cms-image
description: Compress and convert CMS item image fields to webp or avif in a Webflow collection. Prompts for collection ID, item ID, image fields, quality, and target format, then downloads, converts, re-uploads via presigned S3, and publishes the updated item.
---

# Webflow CMS Image Compression

Compress and reformat image fields on a Webflow CMS item to `.webp` or `.avif`.

This skill does not support images embedded inside Rich Text fields at this time. Tell the user that limitation before starting and only process CMS fields whose schema type is `Image` or `MultiImage`.

## Important Note

**ALWAYS use Webflow MCP tools for Webflow operations:**
- Use Webflow MCP's `data_sites_tool` with action `list_sites` to discover the site ID when needed
- Use Webflow MCP's `data_cms_tool` with action `get_collection_details` to fetch collection schemas
- Use Webflow MCP's `data_cms_tool` with action `list_collection_items` to fetch the target CMS item
- Use Webflow MCP's `data_assets_tool` with action `create_asset` to create presigned asset uploads
- Use Webflow MCP's `data_cms_tool` with action `update_collection_items` to update CMS image fields
- Use Webflow MCP's `data_cms_tool` with action `publish_collection_items` to publish the updated item
- All Webflow MCP calls must include the required `context` parameter (15-25 words, third-person perspective)
- Mutating operations require explicit user confirmation. Ask the user to type `confirm` before uploading assets, updating CMS fields, or publishing.
- Rich Text embedded images are not supported. Do not parse or rewrite Rich Text HTML for image compression.

## Instructions

### Phase 1: Gather Parameters

Collect all required inputs in one shot when possible:

1. **Collection ID**: Ask "What is the Collection ID?"
2. **Item ID**: Ask "What is the Item ID?"
3. **Image fields**: Ask "Which image fields should be compressed?"
   - "All image fields" - compress every Image or MultiImage field found on the item
   - "Specify field names" - user will name specific field slugs
4. **Target format**: Ask "Target format?"
   - "webp (Recommended)" - best browser support, good compression
   - "avif" - better compression, slightly less support
5. **Quality (1-100)**: Ask "Quality (1-100)?"
   - "85 - Recommended (webp)" - visually lossless for most photos
   - "75 - Recommended (avif)" - avif is efficient at lower quality
   - "Custom" - user types their own value

If the user chose "Specify field names", follow up for comma-separated field slugs. If the user chose "Custom" quality, follow up for the numeric value. Validate custom quality is an integer from 1 to 100.

### Phase 2: Discover Image Fields

1. Call `data_cms_tool` with action `get_collection_details` and the collection ID.
2. Filter fields where `type === "Image"` or `type === "MultiImage"`.
3. Select target fields:
   - If the user chose "All image fields", use every Image and MultiImage field found.
   - If the user named specific fields, validate each slug exists and is an Image or MultiImage field.
   - Warn and skip requested fields that do not exist or are not image fields.
4. Stop and report if no valid image fields remain.

### Phase 3: Fetch the CMS Item

Call `data_cms_tool` with action `list_collection_items` to fetch the target item. Use the item ID to identify the item directly when the tool supports it; otherwise filter or search the returned items.

Extract current `fieldData` for each target field:
- For Image fields, capture `url` and `fileId`.
- For MultiImage fields, capture each array entry's `url` and `fileId`.
- Skip null, empty, or malformed image values.
- Skip images already in the target format unless the user explicitly asks to recompress them.

### Phase 4: Preview and Confirm

Before downloading or uploading anything, show a preview:

```markdown
Compression Preview

Collection: [collection ID]
Item: [item ID]
Target format: webp
Quality: 85

Fields to process:
- main-image: hero.jpg -> hero.webp
- gallery: 3 images -> webp

Skipped:
- thumbnail: already webp

Type `confirm` to download, convert, upload, update the CMS item, and publish.
```

Proceed only after the user types `confirm`.

### Phase 5: Convert Each Image

For each image:

1. Download to `/tmp/`:

```bash
curl -sL "{url}" -o "/tmp/cms_img_{fieldSlug}_{index}.orig"
```

2. Ensure Pillow is available:

```bash
python3 -c "from PIL import Image" 2>/dev/null || pip3 install Pillow -q
```

For avif, also try:

```bash
pip3 install pillow-avif-plugin -q
```

3. Convert with the user's quality setting:

```bash
python3 - <<'EOF'
from PIL import Image
import os

try:
    import pillow_avif
except ImportError:
    pass

source = "/tmp/cms_img_{fieldSlug}_{index}.orig"
target = "/tmp/cms_img_{fieldSlug}_{index}.{ext}"
img = Image.open(source)
img.save(target, "{FORMAT}", quality={quality})
orig = os.path.getsize(source)
new = os.path.getsize(target)
print(f"Original: {orig:,} bytes -> {FORMAT}: {new:,} bytes ({(1 - new / orig) * 100:.1f}% smaller)")
EOF
```

If avif conversion fails, report the error and ask whether to fall back to webp or abort.

4. Compute the MD5 hash of the converted file:

```bash
md5 -q "/tmp/cms_img_{fieldSlug}_{index}.{ext}"
```

On Linux:

```bash
md5sum "/tmp/cms_img_{fieldSlug}_{index}.{ext}" | cut -d' ' -f1
```

### Phase 6: Upload to Webflow Assets

For each converted file:

1. Determine `site_id`. If it is not known from the collection or prior context, call `data_sites_tool` with action `list_sites`. If multiple sites are available, ask the user which one owns the collection.
2. Call `data_assets_tool` with action `create_asset`:
   - `site_id`: the target site ID
   - `file_name`: original base name plus the new extension, such as `hero.webp`
   - `file_hash`: the MD5 hex string
3. Capture the response values:
   - `uploadUrl`: S3 endpoint
   - `uploadDetails`: form fields
   - `id`: new asset ID
   - `hostedUrl`: CDN URL to use as the CMS source reference
4. POST to S3 as multipart/form-data. Map `uploadDetails` keys to curl fields:
   - `xAmzAlgorithm` -> `X-Amz-Algorithm`
   - `xAmzCredential` -> `X-Amz-Credential`
   - `xAmzDate` -> `X-Amz-Date`
   - `xAmzSignature` -> `X-Amz-Signature`
   - `successActionStatus` -> `success_action_status`
   - `contentType` -> `Content-Type`
   - `cacheControl` -> `Cache-Control`
   - Pass `acl`, `bucket`, `key`, and `policy` as-is
   - Append the file last: `-F "file=@/tmp/cms_img_{fieldSlug}_{index}.{ext};type=image/{ext}"`
5. Expect HTTP 201. If the response is not 201, log the response body and report the upload error. Presigned URLs have a one-hour TTL; restart from asset creation if the URL expires.

### Phase 7: Update and Publish

Call `data_cms_tool` with action `update_collection_items` using only fields that were successfully converted and uploaded.

For Image fields, set:

```json
{
  "fieldSlug": {
    "fileId": "{newAssetId}",
    "url": "{hostedUrl}"
  }
}
```

For MultiImage fields, reconstruct the full image array and replace only successfully processed entries with the new `{ "fileId", "url" }` values. Preserve skipped entries exactly as they were.

After a successful update, call `data_cms_tool` with action `publish_collection_items` for the item ID. The CMS may re-process the image and generate its own CDN URL; the `hostedUrl` from the asset upload is the source reference.

### Phase 8: Report Results

Print a concise summary table:

| Field | Original | Converted | Savings |
|-------|----------|-----------|---------|
| main-image | 118,044 B (JPEG) | 113,260 B (webp) | 4.1% |

Also report:
- Fields skipped because they were null, empty, malformed, already in the target format, or not image fields
- Conversion failures and whether the user chose fallback or abort
- Upload failures, including response bodies when available
- New asset IDs for uploads that succeeded when a later CMS update or publish failed

## Examples

**User prompt:**

```text
Compress the main image on this CMS item to webp.
```

**Response flow:**

```markdown
I need the collection ID, item ID, image fields, target format, and quality before compressing the CMS image.

Compression Preview

Collection: 65f...
Item: 66a...
Target format: webp
Quality: 85

Fields to process:
- main-image: blog-hero.jpg -> blog-hero.webp

Type `confirm` to download, convert, upload, update the CMS item, and publish.
```

**Final report:**

```markdown
CMS Image Compression Complete

| Field | Original | Converted | Savings |
|-------|----------|-----------|---------|
| main-image | 842,911 B (JPEG) | 214,330 B (webp) | 74.6% |

Updated and published item 66a...
```

## Guidelines

- Handle one CMS item at a time. For bulk operations across many items, rerun the skill for each item or extend the workflow with an explicit loop.
- Do not delete the original JPEG or PNG from Webflow's asset store; only update the CMS field reference.
- Preserve filenames by stripping the original extension and appending the target extension. Avoid double extensions such as `hero.jpg.webp`.
- Continue processing other selected fields after a single image conversion or upload failure unless the failed field is the only target.
- Never update or publish the CMS item if no image was successfully converted and uploaded.
- Keep a local in-memory rollback note with the original image field values and include it in the final report when an update succeeds.

© webflow · MIT · webflow/webflow-skills

Similar skills

All skills for Automation and no-code: n8n, Zapier, Make →

From the same set27

webflow-mcp:cms-collection-setup Creates CMS collections in Webflow with fields, relationships, and plan limit checks. Runs through seven phases: site selection, requirements, schema validation, approval, collection creation, field setup, and final report. CX Codex +1 841installs webflow-mcp:bulk-cms-update This skill creates and updates many Webflow CMS items at once, validating each one against the collection schema and showing a diff before writing. CX Codex +1 839installs webflow-mcp:safe-publish Shows what changed on a Webflow site since the last publish, runs pre-publish checks, and waits until you type "publish". CX Codex +1 826installs webflow-mcp:flowkit-naming Brings CSS class names in Webflow in line with the Flowkit system: audits what exists, generates new names, applies them through MCP tools. CX Codex +1 824installs webflow-mcp:site-activity Inspects Webflow Enterprise activity logs to identify who made changes across pages, styles, and CMS before you publish. CX Codex +1 757installs webflow-mcp:review-comments Walks the open comment threads on a Webflow site and sorts each one into noise, stale or open. Optionally posts a bot reply. CX Codex +1 684installs webflow-university:mcp-getting-started Walks you through a first real Webflow MCP workflow: checks the connection, helps pick a task and write the prompt. CX Codex +1 432installs webflow-mcp:figma-to-webflow Translates Figma layouts into native Webflow elements and styles using Figma MCP and Webflow MCP. Ideal for assembling pages directly in Webflow without copy-pasting raw markup. CX Codex +1 373installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor