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.
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-codeWhat 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-codenpx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a claude-code2Manually: put the files in place
~/.claude/skills/webflow-compress-cms-image/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/webflow-compress-cms-image/
1Skills CLI (Vercel)
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a codex2Manually: put the files in place
.agents/skills/webflow-compress-cms-image/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a cursor2Manually: put the files in place
.cursor/skills/webflow-compress-cms-image/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install webflow/webflow-skills webflow-compress-cms-image2Manually: put the files in place
.github/skills/webflow-compress-cms-image/SKILL.md1Skills CLI (Vercel)
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a gemini-cli2Platform CLI
gemini skills install https://github.com/webflow/webflow-skills --path plugins/webflow-skills/skills/webflow-compress-cms-imageManually: put the files in place
.devin/skills/webflow-compress-cms-image/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add webflow/webflow-skills --skill webflow-compress-cms-image -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
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