This connects Claude to Cloudinary's media management API so you can upload, transform, and manipulate images and videos without leaving your workflow. The skill covers both unsigned uploads (simpler, great for prototyping) and signed uploads (more secure), plus on-the-fly URL transformations for resizing, cropping, and format optimization. It even handles video concatenation through URL parameters, though you'll hit practical limits around 10 clips due to URL length constraints. The free tier gives you 25 credits monthly, which translates to roughly 25,000 transformations or 25GB of storage and bandwidth. Solid for personal projects or testing before you need to scale up.
npx -y skills add vm0-ai/vm0-skills --skill cloudinary --agent claude-codeInstalls into .claude/skills of the current project.
If requests fail, run zero doctor check-connector --env-name CLOUDINARY_TOKEN or zero doctor check-connector --url https://api.cloudinary.com/v1_1/your-cloud-name/image/upload --method POST
First, create an unsigned upload preset in Cloudinary Console: Settings > Upload > Upload presets > Add upload preset > Signing Mode: Unsigned
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/image/upload" -F "file=@/path/to/image.png" -F "upload_preset=your_preset_name"
Generate signature and upload:
# Generate timestamp
TIMESTAMP=$(date +%s)
# Generate signature (alphabetical order of params)
SIGNATURE=$(echo -n "timestamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
# Upload
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/image/upload" -F "file=@/path/to/image.png" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
TIMESTAMP=$(date +%s)
SIGNATURE=$(echo -n "timestamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/image/upload" -F "file=https://example.com/image.png" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
TIMESTAMP=$(date +%s)
SIGNATURE=$(echo -n "timestamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/video/upload" -F "file=@/path/to/video.mp4" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
TIMESTAMP=$(date +%s)
PUBLIC_ID="my-videos/clip1"
SIGNATURE=$(echo -n "public_id=$PUBLIC_ID×tamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/video/upload" -F "file=@/path/to/video.mp4" -F "public_id=$PUBLIC_ID" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
TIMESTAMP=$(date +%s)
PUBLIC_ID="my-videos/clip1"
SIGNATURE=$(echo -n "public_id=$PUBLIC_ID×tamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/video/upload" -F "file=https://example.com/video.mp4" -F "public_id=$PUBLIC_ID" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
TIMESTAMP=$(date +%s)
PUBLIC_ID="my-folder/my-image"
SIGNATURE=$(echo -n "public_id=$PUBLIC_ID×tamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/image/upload" -F "file=@/path/to/image.png" -F "public_id=$PUBLIC_ID" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
{
"public_id": "sample",
"secure_url": "https://res.cloudinary.com/demo/image/upload/v1234567890/sample.png",
"url": "http://res.cloudinary.com/demo/image/upload/v1234567890/sample.png",
"format": "png",
"width": 800,
"height": 600
}
Key field: secure_url - Use this in Markdown: 
Cloudinary URLs support on-the-fly transformations:
https://res.cloudinary.com/{cloud_name}/image/upload/{transformations}/{public_id}.{format}
Examples:
# Resize to 300x200
.../image/upload/w_300,h_200/sample.png
# Auto format and quality
.../image/upload/f_auto,q_auto/sample.png
# Crop to square
.../image/upload/w_200,h_200,c_fill/sample.png
# Combine transformations
.../image/upload/w_400,h_300,c_fill,f_auto,q_auto/sample.png
Concatenate videos using URL transformations with l_video: (overlay) and fl_splice flag.
Append clip2 to the end of clip1:
https://res.cloudinary.com/{cloud_name}/video/upload/l_video:clip2,fl_splice/fl_layer_apply/clip1.mp4
Append clip2 and clip3 to clip1:
https://res.cloudinary.com/{cloud_name}/video/upload/l_video:clip2,fl_splice/fl_layer_apply/l_video:clip3,fl_splice/fl_layer_apply/clip1.mp4
Resize all videos to same dimensions:
https://res.cloudinary.com/{cloud_name}/video/upload/w_640,h_360,c_fill/l_video:clip2,fl_splice,w_640,h_360,c_fill/fl_layer_apply/clip1.mp4
Add fade out (-1000ms) on first video and fade in (1000ms) on second:
https://res.cloudinary.com/{cloud_name}/video/upload/w_640,h_360,c_fill,e_fade:-1000/l_video:clip2,fl_splice,e_fade:1000,w_640,h_360,c_fill/fl_layer_apply/clip1.mp4
Prepend an image as intro:
https://res.cloudinary.com/{cloud_name}/video/upload/l_intro_image,fl_splice,du_3/so_0,fl_layer_apply/clip1.mp4
TIMESTAMP=$(date +%s)
PUBLIC_ID="<your-public-id>"
SIGNATURE=$(echo -n "public_id=$PUBLIC_ID×tamp=$TIMESTAMP$CLOUDINARY_API_SECRET" | sha1sum | cut -d" " -f1)
# Delete image
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/image/destroy" -F "public_id=$PUBLIC_ID" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
# Delete video
curl -X POST "https://api.cloudinary.com/v1_1/<your-cloud-name>/video/destroy" -F "public_id=$PUBLIC_ID" -F "api_key=$CLOUDINARY_TOKEN" -F "timestamp=$TIMESTAMP" -F "signature=$SIGNATURE"
f_auto,q_auto to URLs for automatic format/qualitypublic_id="folder/subfolder/name" to organize mediajuliusbrussee/caveman
mattpocock/skills
shadcn/improve
obra/superpowers
forrestchang/andrej-karpathy-skills
vercel-labs/skills