First-party app
Cloudinary Cloudinary

Cloudinary

Manage a Cloudinary media library — upload from a URL, search and tag assets, organise folders, apply named transformations, and build delivery URLs.

stable StorageDocuments & FilesDeveloper Tools

About

Cloudinary ships in the w6w first-party pack. It declares 21 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.

App id
io.w6w.cloudinary
Version
0.1.2
Author
w6w
Licence
MIT
Categories
Storage · Documents & Files · Developer Tools

Overview

Cloudinary puts a media library into a workflow — upload an asset from a remote URL or data URI, search and tag it, organise folders, define reusable named transformations, and build the delivery URLs that are the point of all of it. Assets can be read back with their derived renditions and EXIF data, updated with tags, context and structured metadata, renamed (which moves them between folders), deleted by id or prefix, and restored where backups are enabled.

Named transformations turn a size or crop setting into something a workflow references by name rather than a string baked into every URL — edit the definition once and every derived asset built from it regenerates on the next request. Delivery URLs are assembled locally from the cloud name, transformation and public id rather than fetched from an endpoint, and can include a version segment to make a URL immutable against a later overwrite.

The app tracks a few real gotchas: overwriting or deleting an asset does not flush the CDN edge cache unless explicitly invalidated, an upload without an explicit public id creates a fresh copy on every run rather than replacing the last one, and tag operations vary widely in scope — from touching one asset’s tags to clearing every tag across the entire account. It does not perform signed uploads or signed delivery URLs for private assets, since those require signing a request body rather than a plain HTTP call.

Build with Cloudinary

Three routes to the same 21 actions. The Workflow tab is generated from Cloudinary's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.

Delete assets

asset-delete

Delete by public id (up to 100), by prefix, or everything of a type. The last two need an explicit confirmation — neither can say in advance how much it removes.

Apply transformations or analysis to an existing asset

asset-explicit

Re-run the upload pipeline over an asset already in the library — pre-generate transformations, or run auto-tagging, moderation and OCR after the fact.

Get asset

asset-get

One asset in full — including its derived renditions and extracted metadata, and unlike search, immediately after upload.

List assets

asset-list

Assets by public-id prefix, newest first. Filtering by anything richer — tags, size, dates — is Search's job.

Rename or move asset

asset-rename

Change an asset's public id — which, in a fixed-folder account, is also how it moves folders. Every delivery URL using the old id breaks.

Restore deleted assets

asset-restore

Bring back deleted (or overwritten) assets — only if the account had backups enabled BEFORE the delete. Without them the response is empty rather than an error.

Search assets

asset-search

Cloudinary's search expression language over every indexed field — tags, folder, format, dimensions, dates, context and structured metadata. The index is eventually consistent.

Manage tags

asset-tag

Add or remove one tag across many assets without touching their other tags. `replace` and `remove_all` are destructive and need confirming.

Update asset

asset-update

Change an asset's tags, context, structured metadata or moderation status. Tags REPLACE the whole set — Manage Tags is the additive version.

Upload asset

asset-upload

Upload from a remote URL or a data URI. Without a public id Cloudinary invents one, so repeated runs create duplicates rather than replacing.

Build a delivery URL

asset-url

Assemble a transformation URL from a public id — locally, with no API call. Refuses private and authenticated assets, which need a signature this app cannot produce.

Create folder

folder-create

Create a folder and any missing parents. Dynamic-folder accounts only — in a fixed-folder account, folders come from the assets' public ids.

Delete folder

folder-delete

Delete an empty folder. Cloudinary refuses while it still holds assets, which is why this needs no confirmation — emptying it is a separate, gated step.

List folders

folder-list

The folders directly under a path — one level per call, since Cloudinary returns no tree.

List structured metadata fields

metadata-field-list

The account's structured metadata schema — the external ids and allowed enum values that writing metadata has to match.

List tags

tag-list

Every tag in use for a resource type. Tags are per resource type, so the same word on an image and a video is two entries.

Create named transformation

transformation-create

Define `t_name` once and reference it from every URL — so changing the size of a thumbnail is a setting rather than a redeploy.

Delete named transformation

transformation-delete

Remove a named transformation and every rendition generated from it. Originals are never touched; URLs using `t_name` break.

List transformations

transformation-list

Named transformations and the unnamed ones Cloudinary has generated from delivery URLs — the latter being a record of storage spent, not a design.

List upload presets

upload-preset-list

Stored upload settings by name, for Upload Asset's preset field. The `unsigned` flag marks presets anyone with the cloud name can use.

Get account usage

usage-get

Plan usage — credits or transformations, storage and bandwidth — plus the hourly API request allowance from the rate-limit headers.

A workflow step names the app and the action, and the editor fills in the connection when you pick one. This is the Step shape from the workflow spec, carrying Cloudinary's real ids.

{
  "manifestVersion": "2",
  "name": "cloudinary-example",
  "steps": [
    {
      "id": "asset-explicit",
      "uses": {
        "app": "io.w6w.cloudinary",
        "action": "asset-explicit",
        "connection": "conn_YOUR_CONNECTION_ID"
      },
      "with": {
        "publicId": "<publicId>"
      }
    }
  ]
}

Here are some of the things you can do

  • Apply transformations or analysis to an existing asset

    perform
    asset-explicit
  • Get asset

    read
    asset-get
  • List assets

    read
    asset-list
  • Rename or move asset

    perform
    asset-rename
  • Restore deleted assets

    perform
    asset-restore

+16 more actions available

Every app-specific value here is a blank you have to fill in. An app action is reached through the connection that authenticates it, so the address is a connection id, not the app id — and connections belong to your account, so a public page cannot know yours. Create one for Cloudinary, then fill in the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the parameters that action declares. The call itself is real — the shape is transcribed from the studio's own snippet builder, which prints the same kind of blanks — but nothing in it is specific to Cloudinary. The Workflow tab is where this app's real ids are.

Install
npm install @w6w/sdk
yarn add @w6w/sdk
pnpm add @w6w/sdk
deno add npm:@w6w/sdk
Code
import { W6wClient, isActionRun } from "@w6w/sdk";

// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();

const envelope = await client.run({
  urn: "conn_YOUR_CONNECTION_ID",
  action: "asset-explicit",
  payload: {
    publicId: "<value>",
    // resourceType: "<value>",
    // type: "<value>",
    // eager: "<value>",
    // eagerAsync: "<value>",
    // categorization: "<value>",
    // autoTagging: "<value>",
    // ocr: "<value>",
    // tags: "<value>",
    // context: "<value>",
  },
});

if (isActionRun(envelope)) console.log(envelope.value);
Install the CLI
npm install -g @w6w/cli
CLI
w6w run conn_YOUR_CONNECTION_ID --action asset-explicit --payload '{"publicId":"<value>"}'

Give an AI agent Cloudinary — without giving it Cloudinary's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.

One tool call
{
  "name": "w6w_invoke",
  "arguments": {
    "ref": "app:io.w6w.cloudinary#asset-explicit",
    "input": {
      "publicId": "<publicId>"
    }
  }
}

Every tool names its target with a single ref. The app: form above doesn't name a connection at all — the host resolves which of the caller's Cloudinary connections to sign with, and refuses rather than guesses when the answer is ambiguous.

What the agent gets

Credentials it can't read

The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.

A tool surface scoped to the caller

Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.

A durable workflow in one call

Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.

Health-aware discovery

Cloudinary's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.

The MCP surface is part of the hosted platform. Cloudinary itself is MIT, and the runtime that executes it is source-available (FSL).

Request MCP access

Health checks

Cloudinary declares its own checks, so its health is a property of the app rather than something the host guesses at.

service

Cloudinary datacenter status

The Admin, Upload and Media Transformation components for THIS connection's datacenter — an outage in another region is not this connection's problem.

quota

API and plan headroom

Cloudinary's hourly API request allowance, read from the rate-limit headers, and the plan's credit budget from GET /usage. Being throttled and being over budget are different problems.