Can an AI agent use Cloudinary?
As of 6 Oct 2026, an AI agent gets into Cloudinary on its own and does 100% of the core work.
- Find: Some docs for agents: llms.txt and an MCP server.
- Access: Sign-up in a browser.
- Use: 100% of the work.
- Pay: Payment not reached.
- Leave: Nothing to cancel: Can't delete its account.
To reach L5 · Autonomous: pay without a person.
What the levels meanDriven 6 Oct 20261 drive so farRules of 15 Oct 2026Claim this page
Written and checked by our agents from this drive's record. How we write.
Who gets in
- Agents on a serverGet in on their own.
- Signed agentsThe site opens.
- Agents in a person's browserNot measured yet.
Sign-up page checked 12 Oct 2026. Signed agents: the ones Cloudflare verifies. Where agents come from
What an agent can do in Cloudinary.
On its own
- Get a free, working account instantly with one API call, no form to fill in
- Upload photos and videos, including by pasting a web link
- Resize, crop, and apply effects or text overlays to images
6 more
- Automatically pick the best image format and quality for each viewer
- Serve images and video through a fast content delivery network
- Stream video that adjusts quality to the viewer's connection
- Make a short AI highlight clip from a longer video
- Organize, tag, label, and search through stored files
- Clean up everything it created when finished
What it can't, and why
- Log into the website dashboardSetting a password there requires passing a visual robot check
- Upgrade to a paid planPayment is only a credit-card form inside that same locked dashboard
- Delete the account itselfThe company says only its support team can do that
1 more
- Use advanced AI add-ons like text reading or face searchThose need a paid subscription the free account doesn't have
Can an AI agent sign up for Cloudinary on its own?
Yes, over the API, without a browser. Claimable cloud: unauthenticated POST https://api.cloudinary.com/v1_1/provisioning/clouds returned a working cloud, key/secret and claim_url (auth.md 'anonymous' pattern)
Does Cloudinary have an MCP server, and can an agent connect to it?
Yes. Cloudinary has an official MCP server.
A new agent can get in on its own: in the drive of 6 Oct 2026, our agent signed up, verified and got its key without a person. Through the MCP server, 13 of our agent's 15 attempts worked.
What the drive found
API–OpenAPIMCP · officialCLISDKllms.txtWebhooks–SandboxHow does an AI agent get a Cloudinary API key?
In the drive of 6 Oct 2026, our agent got its Cloudinary API key over the API, without a browser or a person. api_key/api_secret/CLOUDINARY_URL in the provisioning response; same value works as cloudinary-url header on the MCP servers
Can an AI agent delete its Cloudinary account?
Not on its own: blocked. All assets and account config (presets, transformations, mappings, streaming profile, metadata field, trigger, folders) deleted headless via the API. The account itself was not deleted: docs state 'You can't delete an account yourself, this requires a support request', and no support request was filed in this drive. An unclaimed cloud would self-delete after 24h, but this cloud was claimed, so the claimed login remains active and no rejected-access evidence exists.
Not tested in this drive: paying. Every checkpoint, in detail
For the team behind Cloudinary.
Where agents stop in Cloudinary today, and the fixes that get them further, highest impact first.
The fixes, highest impact first
- Let agents delete accounts via the API
- Set the Console password inside the claim flowStep-by-step guide
- Support MCP (the 28 Jul 2026 spec) server/discover
3 more fixes
- Fix the provisioning response docs
- Offer CIMD and drop PKCE plain Step-by-step guide
- Publish OpenAPI for Upload and Admin APIs Step-by-step guide
- Claim it free and reply next to the result.
- A Drive, $49: your private report, with where agents stop, the evidence and the fixes that move your level.
- Fixed something? Order a Drive ($49) any time, or the Monthly drive ($29/month).
Details
Your API, MCP server or CLI is the product? An Audit ($299) also checks every documented route, MCP tool and CLI command against your docs. Compare plans.
Already claimed it? Open it in your dashboard.
Rather not be driven? Block AgentDrivesAgent in robots.txt or write to us. We stop driving it ourselves; this page stays, with its date.
Embed the badge on your site
Behind the level.
The part scores and the measures behind them.
Part scores and the measures · paid plans
Part scores
Agent-ready setup
- llms.txt: found
- OpenAPI: not found
- MCP server: found
- CLI: found
Not measured in this drive: Holds up, Docs match (part of an Audit).
Security: reported privately to the owner
The measures
- Work done100
- Reliability100
- Crash test–
Needs a paid plan
Not counted in the level. Our drive used free plan (claimable cloud, then claimed).
| Capability | Plan |
|---|---|
| Auto-tag with AI add-ons | add-on subscription |
| OCR | add-on subscription |
| AI Vision | paid feature |
| People search | paid feature |
| Multiple product environments via API | Enterprise |
For agents and builders.
The drive as data, every checkpoint and all 52 attempts.
How an agent connects · 5 tips
/api/tools/cloudinary.json/tools/cloudinary.mdMCP get_tool {"slug":"cloudinary"}
- Start with POST /v1_1/provisioning/clouds (or npx @cloudinary/cloud) and give the user the claim_url early: unclaimed clouds are deleted after 24 h
- Use the MCP servers with header cloudinary-url: cloudinary://key:secret@cloud; initialize with 2025-11-25
- Put the asset's real version in delivery URLs; folder names like 'ad_test' can be parsed as transformations otherwise
- Search lags uploads by about a minute; dynamic folders mean 'folder:' does not match public_id paths
- Delivery is IP-locked until the claim: declare the viewer's IP
Every checkpoint, in detail · 9 checkpoints
- DocsHeadlessllms.txt (root and /documentation), /auth.md, markdown docs via Accept: text/markdown and .md URLs
- Sign upHeadlessClaimable cloud: unauthenticated POST https://api.cloudinary.com/v1_1/provisioning/clouds returned a working cloud, key/secret and claim_url (auth.md 'anonymous' pattern)
- VerifyIn a browserOptional claim: claim page + confirmation mail + 'Verify & activate' in the browser; no bot check on these pages
- KeyHeadlessapi_key/api_secret/CLOUDINARY_URL in the provisioning response; same value works as cloudinary-url header on the MCP servers
- First callHeadlessGET /usage 200 (plan Free, 25 credits)
- First actionHeadlessMCP upload-asset created an image, confirmed through Admin API
- PayNot reachedNo 402/x402/MPP/UCP, not in x402 Bazaar or mpp.dev; docs: upgrade via Console > Billing > Plans by credit card, no billing API. Console login for the claimed cloud needs a password set behind a reCAPTCHA v2 checkbox, so checkout was not reached.
- CancelNot neededNothing to cancel: our agent used the free plan.
- DeleteBlockedAll assets and account config (presets, transformations, mappings, streaming profile, metadata field, trigger, folders) deleted headless via the API. The account itself was not deleted: docs state 'You can't delete an account yourself, this requires a support request', and no support request was filed in this drive. An unclaimed cloud would self-delete after 24h, but this cloud was claimed, so the claimed login remains active and no rejected-access evidence exists.
The attempt log · 52 attempts
| Capability | Route | Result | Evidence |
|---|---|---|---|
| robots.txt / aipref: Read robots.txt for Content-Usage / Content-signal | api | done ✓ | 200 text/plain; no Content-Usage or Content-signal lines; User-agent * disallows /blog/tag/*, /documentation/sdks/* etc. |
| llms.txt: Fetch llms.txt | api | done ✓ | https://cloudinary.com/llms.txt 200 text/plain, H1 '# Cloudinary', describes itself as 'the media layer for AI agents'; also /documentation/llms.txt and per-product llms-image-and-video-apis.txt |
| well-known cards: ai-catalog.json, agent-card.json, agent.json, mcp/server-card.json, ucp, oauth-* on cloudinary.com | api | failed ✓ | All 403 application/xml S3 AccessDenied (no card). <mcp>/server-card 404 JSON 'Unknown endpoint'. |
| markdown docs: Accept: text/markdown on docs page and .md URL | api | done ✓ | documentation/cloudinary_llm_mcp with Accept: text/markdown -> 200 content-type text/markdown, no Vary: Accept header; .md URL -> 200 text/markdown |
| MCP version: POST server/discover (2026-07-28) to 4 remote MCP servers | mcp | partial ✓ | All 401 before protocol handling; asset-management: WWW-Authenticate Bearer resource_metadata=.../.well-known/oauth-protected-resource; body 'Provide either OAuth Bearer token or API key headers.'; retry with creds pending |
| auth.md: GET /auth.md | api | done ✓ | 200 text/plain auth.md: Path 1 OAuth via MCP (DCR), Path 2 'claimable cloud' POST https://api.cloudinary.com/v1_1/provisioning/clouds unauthenticated, claim within 24h; ID-JAG not supported |
| pay probes: x402./mpp./agents. subdomains, /.well-known/ucp, unauth API | api | done ✓ | x402/mpp/agents.cloudinary.com 404 image/gif; /.well-known/ucp 403 S3; api.cloudinary.com/v1_1/demo/resources/image 401 JSON {'error':{'message':'Invalid credentials'}} (no 402) |
| MCP version (with creds): server/discover 2026-07-28 with cloudinary-url header, then initialize | mcp | done ✓ | server/discover -> HTTP 400 JSON-RPC -32000 'Unsupported protocol version: 2026-07-28 (supported versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07)' (not -32022). initialize offering 2026-07-28 -> protocolVersion 2025-11-25, serverInfo CloudinaryAssetMgmt 0.11.2, SSE reply, no Mcp-Session-Id. tools/list: asset-management 30, environment-config 24, structured-metadata 11 tools |
| docs: Find API docs, llms.txt, auth.md | api | done ✓ | llms.txt, /documentation/llms.txt, auth.md, docs pages served as markdown |
| signup: Provision a claimable cloud without an account | api | done ✓ | POST https://api.cloudinary.com/v1_1/provisioning/clouds {delivery_ips:['requester_ip'],email:an inbox@...} -> 200, cloud_name [redacted], api_key/secret, claim_url, expires_at 2026-10-07T00:36:29Z, delivery_ips ['167.235.152.186'] |
| credentials: Get API credentials | api | done ✓ | api_key + api_secret + CLOUDINARY_URL returned in the provisioning response; same value accepted by MCP servers via cloudinary-url header |
| The first call: GET usage with the new credentials | api | done ✓ | GET /v1_1/[redacted]/usage -> 200 plan Free, credits limit 25; X-FeatureRateLimit-Limit 500 / Remaining 499 |
| View usage and credit consumption reports: Read current usage/credits | api | done ✓ | GET admin /usage 200: plan Free, credits {usage 0, limit 25}, storage/bandwidth/transformations, media_limits |
| The first action: Upload an asset via MCP upload-asset | mcp | done ✓ | upload-asset -> public_id ad_test/sample_remote 864x576 jpg 109669 bytes; read back via Admin API GET resources/image/upload/ad_test/sample_remote |
| Upload an image or video: Upload local JPEG and MP4 via Upload API | api | done ✓ | POST image/upload face.jpg -> etag e8282247... == local md5, 582249 bytes; POST video/upload dog.mp4 9094354 bytes 13.4s; Admin GET resources returns same bytes/format |
| Upload an image or video: Upload remote URL via MCP upload-asset | mcp | done ✓ | MCP upload-asset (asset-management, cloudinary-url header) -> ad_test/sample_remote; Admin API GET confirms 109669 bytes jpg |
| Fetch a remote file by URL into Cloudinary: Upload with file=<remote URL> | mcp | done ✓ | upload-asset file=https://res.cloudinary.com/demo/image/upload/sample.jpg -> stored, original_filename 'sample', GET resource 864x576 109669 bytes |
| Resize and crop an image/video via URL transformation: Crop face.jpg to 300x200 via c_fill URL | api | done ✓ | GET res.cloudinary.com/[redacted]/image/upload/c_fill,h_200,w_300/v1791247043/ad_test/face.jpg -> 200 image/jpeg, JPEG SOF dims 300x200; c_thumb,h_200,w_200,g_face -> 200x200 |
| Apply AI-based smart/face-aware cropping: Compare g_auto vs g_center 300x300 crop | api | done ✓ | g_auto md5 1e43a71b67 (10403 B) vs g_center md5 84cde706a1 (10271 B): different framing; g_face thumb 200x200 returned |
| Apply visual effects, filters, and overlays: e_cartoonify and a text overlay | api | done ✓ | e_cartoonify -> 200, md5 differs from original; l_text:Arial_60:AgentDrives,co_white,g_south -> 200 image with 'AgentDrives' text visible at bottom (ev_overlay_text.jpg, viewed) |
| Auto-optimize format and quality: f_auto,q_auto with different Accept headers | api | done ✓ | Accept avif/webp -> image/webp 32168 B; Accept image/jpeg -> image/jpeg 50154 B; original 582249 B; Vary: Accept,User-Agent,Save-Data |
| Deliver assets through a CDN: Check CDN headers on delivery URL | api | done ✓ | res.cloudinary.com delivery: cache-control public, immutable, max-age=2592000; server-timing cld-fastly ... desc=miss / cld-cloudflare desc=hit; server Cloudinary |
| Organize assets into folders: Create folder and move an asset into it | mcp | done ✓ | MCP create-folder agentdrives/photos -> success; asset-rename to agentdrives/photos/sample_remote; Admin GET /folders/agentdrives lists 'photos'; rename response public_id agentdrives/photos/sample_remote |
| Tag assets: Add tag and list by tag | mcp | done ✓ | First call with 'tag' (singular) -> clear error 'Missing required parameter. Either tag or tags are required'; with tags:[drive_tag_1] -> ok; Admin GET resources/image/tags/drive_tag_1 returns ad_test/face |
| Attach structured/contextual metadata fields to assets: Create a structured metadata field, set it, add context | mcp | done ✓ | structured-metadata MCP create-metadata-field drive_note -> created; manage-asset-metadata sets drive_note; Admin GET resource shows metadata {'drive_note':'set by AgentDrives'} and context custom alt/caption |
| Moderate uploaded content: Upload with moderation=manual, approve, list approved | api | done ✓ | upload modtest/m1 moderation [{'kind':'manual','status':'pending'}]; POST resources/image/upload/modtest/m1 moderation_status=approved -> approved; GET resources/image/moderations/manual/approved lists modtest/m1 |
| Relate assets to each other: Relate face image to dog video | mcp | done ✓ | MCP create-asset-relations -> success_ids; Admin GET resource ?related=true shows related_assets [ad_test/dog] |
| Define reusable upload presets: Create preset that tags, upload with it | mcp | done ✓ | environment-config MCP create-upload-preset ad_preset (tags from_preset) -> created; Upload API with upload_preset=ad_preset -> resource tags ['from_preset'] |
| Save and reuse named transformations: Create t_ad_thumb and use it in a URL | mcp | done ✓ | MCP create-transformation ad_thumb = c_fill,h_100,w_100 -> created; Admin GET /transformations/t_ad_thumb info [{height:100,width:100,crop:fill}]; GET .../t_ad_thumb/.../face.jpg -> 200 JPEG 100x100 |
| Transcode and adaptively stream video (HLS/MPEG-DASH): HLS via sp_auto on uploaded MP4; custom streaming profile | api | done ✓ | GET https://res.cloudinary.com/[redacted]/video/upload/sp_auto/v1791247045/ad_test/dog.m3u8 -> master playlist with 3 variants (640x358, 480x268, 320x178); ffprobe reads all three programs with video+audio. environment-config MCP create-streaming-profile ad_profile; Admin GET /streaming_profiles/ad_profile returns it |
| Generate AI video summary/highlight clip: e_preview:duration_5 on the 13.4s dog.mp4 | api | done ✓ | First request -> 423 x-cld-error 'Video summarization is processing in the background' (clear); ~2 min later -> 200 video/mp4 379307 bytes, ffprobe duration 5.04s (source 13.41s) |
| Receive webhook/event notifications on triggers: Create an upload trigger to a URL on our domain | mcp | partial | environment-config MCP create-trigger event_type upload uri https://agentdrives.com/hooks/cloudinary-an inbox -> created id af9f25fa...; list-triggers returns it |
| Search and filter assets: Search by tag expression via MCP and REST | mcp | done ✓ | MCP search-assets expression 'tags=drive_tag_1' -> total_count 1 [ad_test/face] (empty right after tagging: index lag ~1-2 min); REST POST /resources/search 'resource_type:video' -> 5 incl. ad_test/dog and 4 preloaded samples |
| Dynamically map upload sources: Map folder 'demomap' to res.cloudinary.com/demo and 'wiki' to Wikimedia Commons, request unknown ids | mcp | done ✓ | environment-config MCP create-upload-mapping demomap -> created; GET res.../image/upload/demomap/woman.jpg -> 200 1000x688; Admin GET resources/image/upload/demomap/woman -> bytes 582249 created 2026-10-06T00:41:22Z; wiki/3/3f/JPEG_example_flower.jpg -> 200 500x477 |
| Restore deleted/backed-up asset versions: Upload with backup=true, delete, restore | api | done ✓ | DELETE resources/image/upload?public_ids[]=restore_me -> deleted; POST resources/image/upload/restore -> restore_me version 1791247296, 864x576, 109669 bytes; GET resource shows bytes 109669, backup true |
| Restrict asset access with token/cookie-based authentication: Upload type=authenticated, compare unsigned vs signed delivery | api | done ✓ | Unsigned .../image/authenticated/v1791247305/secret1.jpg -> 401 x-cld-error 'Unauthenticated access'; signed secure_url (s--koS_QAw1--) -> 200 109669 B; self-signed w_200 URL -> 200, unsigned w_200 -> 401 |
| Auto-tag and categorize content with AI: Upload with categorization=google_tagging / aws_rek_tagging | api | plan_gated | HTTP 420 'Enhance Your Calm' {'error':{'message':"You don't have an active subscription for Google Auto Tagging"}} (same for Rekognition) |
| Extract text from images via OCR: Upload with ocr=adv_ocr | api | plan_gated | HTTP 420 {'error':{'message':"You don't have an active subscription for OCR Text Detection and Extraction"}} |
| Answer questions about image content with generative AI (AI Vision): POST v2/analysis/{cloud}/analyze/ai_vision_general | api | plan_gated | 403 {'error':{'category':'auth_error','code':'MA_00007','message':'account does not have an active subscription for feature','details':{'feature_name':'ai_vision'}}} |
| verify: Claim the cloud: claim page + confirmation email | browser | done ✓ | Claim page (console.cloudinary.com/users/agent_email_confirmation) pre-filled the agent's inbox -> 'Send confirmation link' -> mail 'Confirm your email to claim your Cloudinary cloud' arrived 00:43:12 -> link -> 'Verify & activate' -> "You're all set! Your email has been verified" |
| console login: Set a console password after the claim | browser | blocked | 'Set up password & log in' led to /users/login; /users/recover_password shows a reCAPTCHA v2 checkbox ('Verification required.' after submit). |
| Search and filter assets: Search by tag via official CLI | cli | done ✓ | cloudinary-cli 1.46.3 in a venv: 'cld admin ping' -> status ok; 'cld search tags=drive_tag_1' returns ad_test/face |
| OAuth DCR: POST /register on asset-management MCP AS | mcp | done ✓ | DCR 200: client_id mcp_client_..., token_endpoint_auth_method none; AS metadata has no client_id_metadata_document_supported (no CIMD); no device_authorization_endpoint |
| pay: Probe agent payment rails and billing route | api | done ✓ | No 402 anywhere (API unauth -> 401 JSON); x402./mpp./agents. subdomains 404; /.well-known/ucp 403; no /openapi.json; x402 Bazaar has only bazaar icons hosted on res.cloudinary.com (other merchants), mpp.dev/api/services has no cloudinary entry; billing docs: free plan no card, upgrade via Console Settings > Billing > Plans, payment by credit card; no billing API |
| delete: Delete our data and the account | api | partial ✓ | API: DELETE resources/{image,video}/{upload,authenticated}?all=true -> deleted (our uploads + preloaded samples); presets, named transformation, upload mappings, streaming profile, metadata field, trigger, folders deleted (each 'deleted'/'ok'); MCP delete-asset -> ok, GET -> 404. Account: docs (ts_how_can_i_cancel_or_delete_my_cloudinary_account) say 'You can't delete an account yourself, this requires a support request'; cancel is Console-only |
| Detect and search for people/faces across assets: GET admin /people | api | plan_gated | 403 {'error':{'message':'People Search is not enabled for this customer'}} |
| Manage multiple product environments per account: Create/read a second product environment | api | plan_gated | GET /config returns only this cloud ([redacted]); provisioning_api.md: 'Provisioning API access is available upon request for accounts on an Enterprise plan'; Console (where free accounts add environments) unreachable: password setup behind reCAPTCHA |
| View last-access reports for assets: GET resources/last_access_reports | api | failed | 400 {'error':{'message':'Illegal id'}}, endpoint path guessed from the map, not checked against docs; not pursued (paid in map) |
| Build no-code media workflows (MediaFlows): MediaFlows is a Console/UI product | none | blocked | No API in the map; Console login blocked |
| Browse and search assets from VS Code extension: VS Code extension | none | skipped | No VS Code in the drive sandbox |
| Back up assets to a customer-owned S3 bucket: Console setting | none | skipped | Map: paid, no API; not attempted |
| Configure custom domain (CNAME): Console/support setting | none | skipped | Map: paid, no API; needs a domain we control; not attempted |
Also in File storage.
Backblaze B2L1Gets in on its ownCloudinary vs Backblaze B2
BoxL1Can't sign up on its ownCloudinary vs Box
DropboxL1Can't sign up on its ownCloudinary vs Dropbox
PinataL1Can't sign up on its ownCloudinary vs Pinata