experience-content-media-stock-image-search
Searches for and downloads ethically-licensed stock images via the media-management MCP server. Use this skill whenever a user wants an image, photo, or picture — for BOTH requests to find existing imagery ("find a stock image", "search for a photo of X", "get a royalty-free image", "find an ethical
By forcedotcom · 1,678 installs
npx skills add forcedotcom/sf-skills --skill experience-content-media-stock-image-search
Source repository · Upstream listing
Stock Image Search
When to Trigger This Skill
Trigger immediately — without asking the user to choose a search method — whenever the user wants an image, photo, or picture. This covers both :
Finding existing imagery: "find a stock image", "search for a photo of X", "get a royalty free image", "find an ethical image", editorial or news photography
Requests phrased ambiguously as creating or generating: "create an image of a sunset", "generate a picture of a team meeting", "make me a mountain image" — treat these as stock search requests; this skill searches a stock photo library, it does not generate images.
In all of these cases, search the stock library — this is the tool for obtaining an image. Do NOT offer alternative search methods (hybrid search, user provided URL/path, etc.) and do NOT ask the user to pick one.
Does not apply to:
Searching internal CMS / Data Cloud media (use experience search coordinate )
Requests that explicitly ask for AI generated, synthetic, or computer generated imagery — this skill only searches licensed stock photography and has no image generation capability
Step 1 — Search
MCP tool: search stock images (server: media management )
Timeout: 30 seconds
Parameter Required Default Notes
query ✅ Yes — Natural language search phrase (e.g. "sunset over ocean", "business meeting"), max 500 chars
searchType No Creative Creative (royalty free stock), Editorial (rights managed news/event imagery)
orientation No (none) Horizontal , Vertical , Square , PanoramicHorizontal , PanoramicVertical
sortOrder No BestMatch BestMatch , MostPopular , Newest
pageSize No 5 1–100
page No 1 1 indexed, must be = 1
Smart keyword extraction: If the query is longer than 20 words or returns no results, the tool automatically extracts short keyword phrases via LLM and retries. The effectiveQuery field in the response shows what was actually sent to the search service ( null if the original query was used unchanged).
Response fields:
Field Notes
images[] List of results (see item fields below)
totalCount Total matches across all pages
page Current page (1 indexed)
pageSize Results per page
searchRequestId Internal correlation ID. Server managed; not passed back through the MCP download tool. Safe to surface in debug output if useful.
effectiveQuery Keywords actually sent to the search service. Null if the original query was used unchanged.
errorMessage Non null if the search failed
Each images[] item:
Field Notes
assetId Stock asset ID — required for download. Safe to display alongside the result if useful.
title Image title
caption Image description
thumbnailUrl Small preview URL — use for grid display
previewUrl Larger comp/preview URL — use for tile display
width Max width in pixels
height Max height in pixels
licenseModel e.g. royaltyfree , rightsmanaged
artist Contributor/artist name
collection Collection name
Step 2 — Present Results, then STOP
Render a numbered list with an inline thumbnail for each result, using thumbnailUrl for the image and previewUrl as the click through link (clicking the thumbnail opens the full preview in the browser):
This is standard markdown image in link syntax ( [](previewUrl) ) — it renders an actual thumbnail, not just a text link, and clicking it navigates to previewUrl . If a client doesn't render markdown images, this degrades gracefully to a linked title.
Prefix the list with Searched for: <effectiveQuery only if effectiveQuery is non null and differs from the user's original query.
End the turn here. Do not auto download, do not write files, do not ask a follow up question. Agentforce injects its own selection UI — a question or auto select causes a duplicate "double ask". Do not pick a result on behalf of the user.
Non interactive mode (scheduled/headless, no user present): pick images[0] from the results and note the auto selection in the report. Then proceed directly to Step 3.
Step 3 — Download (billed)
⚠️ Each call licenses the image and spends a stock image download credit. Only invoke after the user explicitly selects an image (or in non interactive mode, as noted above).
Before calling download stock image , verify:
[ ] User has explicitly named or numbered the image they want (or non interactive mode is confirmed)
[ ] This is not an automatic retry of a previous download
MCP tool: download stock image (server: media management )
Timeout: 60 seconds
Parameter Required Default Notes
assetId ✅ Yes — Stock asset ID from the prior search stock images result, max 50 chars
size No comp comp (web quality composite, default), medium jpg , largest (full res, can exceed 100 MB), max 50 chars
Use largest only when the user explicitly asks for full/original resolution.
Response fields:
Field Notes
assetId Stock asset ID that was downloaded
managedContentBodyId Salesforce record ID where image bytes are stored
parentContentGenAiOutputId Record tracking the download request
childContentGenAiOutputId Record linking the request to the persisted body
byteCount Size of the persisted image in bytes
format Resolved image format (e.g. jpg , png , eps , tiff , svg )
url URL to the persisted image — use this to download or preview it
Step 4 — Download to Client and Preview
After a successful download stock image call, download the image locally and open it in VS Code.
You MUST use download stock image.py for this. Do not use curl , wget , or any other tool.
The script retrieves org credentials via the sf CLI ( sf config get target org and sf org auth show access token ), downloads the image with Authorization: Bearer <accessToken to stockimages/<assetId .<format , and opens it in VS Code if preview is passed.
Pass output dir <path to override the default stockimages/ directory.
Never resize or post process the image. Use CSS ( width , height , object fit ) to control display dimensions.
Vector/binary formats ( eps , tiff ): always pass the exact format returned by the download response — never substitute a format like jpg to work around a validation error; the file bytes won't match the extension and the file will appear corrupted. VS Code cannot render eps / tiff previews, so the script skips preview for those formats automatically and still reports the saved path.
Step 5 — Report Back
After a successful download, tell the user:
Image title and artist
Local path to the saved image (printed by the script)
managedContentBodyId
Attribution: {artist} · {collection} (use the attribution string returned by the download response when present)
Fallbacks & Errors
Situation Action
errorMessage non null in search Show it; suggest a simpler query or different searchType / orientation
images empty Suggest broader keywords; try switching Editorial vs Creative
effectiveQuery differs Inform user what the search service actually received
MCP tools unavailable Use the placeholder URL below — do not download or save
Download fails Show error; do NOT retry automatically — confirm with user first (each retry is billed)
Placeholder
If search stock images and download stock image are both unavailable, use this URL directly as src or CSS url() :
Placeholder policy: There is only one placeholder URL. Do not download it, modify it, or generate alternative placeholders using Python, ImageMagick, or any other tool. If the user asks for a placeholder of a specific size or format, tell them only this URL is available and direct them to use CSS to scale it at the point of use.