Update to Arcads
Snapshot Oct 26, 2026 · 12:07 UTC · version 1.0.10
Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.
Instructions updated for media-router
Full description — Now says:
Observed in instructions or declared skills. Runtime behavior has not been tested.
Up to 10 plugins free · no card required.
All fields and original values.
Full description
Sep 30, 2026 · 22:49 UTC
proactively
Oct 26, 2026 · 12:07 UTC
Skill instructions
Sep 30, 2026 · 22:49 UTC
proactively when the user asks to "generate an Before routing, check whether one of these matches better and hand off instead. **All three sibling skills below are `disable-model-invocation: true`** — they will not auto-activate on user ...
Oct 26, 2026 · 12:07 UTC
when the user asks to "generate an Before routing, check whether one of these matches better and hand off instead. Invoke the sibling skill explicitly with the Skill tool (e.g. `Skill("arcads:clone-hook")`). The hand-off carries the requ...
Compare saved observations
Download comparison JSONSKILL.md text changes
− removed · + added
--- before +++ after @@ -4,7 +4,7 @@ Smart router for any "generate" or "edit/modify/repurpose" request on an image or video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool list, picks the best-matching tool for the user's intent, and runs it end-to-end - (upload, call, poll, deliver). Use proactively when the user asks to "generate an + (upload, call, poll, deliver). Use when the user asks to "generate an image", "make a picture of…", "generate a video", "create a video of…", "edit this image", "remove the background", "extend this video", "add captions", "add a voice-over", "translate this ad", "upscale this", "change the background", "repurpose @@ -34,7 +34,7 @@ ## When to defer to a specialized skill -Before routing, check whether one of these matches better and hand off instead. **All three sibling skills below are `disable-model-invocation: true`** — they will not auto-activate on user phrases, so you (the router) are the one route that brings them in. Invoke them explicitly with the Skill tool (e.g. `mcp_Skill("arcads:clone-hook")`); this works even when model-invocation is disabled. +Before routing, check whether one of these matches better and hand off instead. Invoke the sibling skill explicitly with the Skill tool (e.g. `Skill("arcads:clone-hook")`). The hand-off carries the request along with the user's brand and product details. | User intent | Defer to | |---|---| @@ -120,6 +120,12 @@ --- +## Run folder + +Create one folder per run with `mkdir -p ~/Downloads/arcads/media-router-$(date +%Y%m%d-%H%M)` and reuse that exact path, written `<run>` below, for the whole run, follow-ups included. Every file the run produces goes into it, and the link handed over points into this folder. + +--- + ## Step 5 — Collect required inputs and upload assets For the chosen tool, read its required parameters and check what the user has actually provided: @@ -129,11 +135,15 @@ 1. Get the file onto disk (search `~/Downloads`, `~/Desktop`, `~/Pictures` if the user pasted a chat thumbnail rather than a path: `find ~/Downloads ~/Desktop -maxdepth 1 -type f \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.webp" -o -iname "*.mp4" -o -iname "*.mov" \) -mmin -15`). Confirm by reading. 2. Call `arcads_get_upload_url` with the file's `mimeType`. 3. `PUT` the bytes: `curl -X PUT -H "Content-Type: <mimeType>" --data-binary @"<localPath>" "<presignedUrl>"`. Expect HTTP 200. - 4. Pass the returned `filePath` as the parameter value. -- **Upload paths expire (~10 min).** If a call fails with `REFERENCE_FILE_NOT_FOUND`, re-upload and retry with the fresh path. -- **Reasonable defaults for unset optional params:** `aspectRatio` `"9:16"` for social video / `"1:1"` for static, `resolution` `"1080p"`, `audioEnabled` `true` for video. Override anything the user specified. + 4. Pass the returned `filePath` as the parameter value. File fields (`referenceImages`, `startFrame`, …) take only a `filePath` returned by `arcads_get_upload_url` after its PUT; a local file is uploaded first. +- **Each upload serves one generation call.** A generation copies its `external-api-temp-uploads/*` references and deletes them, so upload a fresh copy of each input for every call, including calls you run in parallel. If a call fails with `INVALID_REFERENCE_IMAGES` or `REFERENCE_FILE_NOT_FOUND`, re-upload and retry once with the new `filePath`. +- **Reasonable defaults for unset optional params:** `aspectRatio` `"9:16"` for social video / `"1:1"` for static, `audioEnabled` `true` for video. Leave `resolution` unset so the tool's own default (720p for video) applies, and set a higher one only when the user asks for it. Override anything the user specified. - **`productId`:** if the tool returns `PRODUCT_SELECTION_REQUIRED` with a list, ask the user which product, then pass its `id`. +### Defaults + +One output per call, the tool's own resolution, one clip. Raise any of them when the user asks. If a generation reports insufficient credits, say so in one line and stop. + --- ## Step 6 — Run, poll, deliver @@ -142,11 +152,12 @@ - Tell the user something short and human, e.g. "Generating your image…" or "Editing your video…". Don't narrate which tool or how. - Poll with `arcads_get_asset` until `status === "generated"` (or `"failed"`). Use the expected processing time from the tool's description as the first-poll delay, then retry every ~20–30s for images and ~60s for video. -- On success, call `arcads_watch_asset` (or read the asset's `data.url` for non-media outputs like text analysis) to get the signed URL. -- Download and open locally: - - **Image** → `curl -sL "<url>" -o ~/Downloads/arcads-output.png && open ~/Downloads/arcads-output.png` - - **Video** → `curl -sL "<url>" -o ~/Downloads/arcads-output.mp4 && open ~/Downloads/arcads-output.mp4` - - **Audio** → `curl -sL "<url>" -o ~/Downloads/arcads-output.mp3 && open ~/Downloads/arcads-output.mp3` +- On success, the `arcads_get_asset` result carries the `downloadUrl` of a media file (for text outputs like an analysis, read `data.generatedText` instead). +- Save locally (media file only — never execute or `open` it from the shell) and give the user a clickable file link: + - **Image** → `curl -sL "<url>" -o <run>/output-1.png`, then link to that file + - **Video** → `curl -sL "<url>" -o <run>/output-1.mp4`, then link to that file + - **Audio** → `curl -sL "<url>" -o <run>/output-1.mp3`, then link to that file + - Number each further output of the run (`output-2.png`, …). The question that asks about a result, in `AskUserQuestion` or in plain text, carries its link and a short description (`[output-1.png](<run>/output-1.png): product centered on cream`): the user sees only the chat and question text, and an image you open with Read stays invisible to them. - On failure, read the error message, fix the obvious issue (re-upload expired refs, drop an invalid parameter, ask the user for a missing input), and retry **once**. If it fails again, surface a short explanation and stop. Then summarize in one line — what was produced, not which tool you used: @@ -198,6 +209,6 @@ | MCP introspection (`list_tools` / namespaced tool enumeration) | Step 1 + 2 — locate Arcads and read the live catalog | | `arcads_get_upload_url` + `curl -X PUT` | Step 5 — upload any file inputs | | The chosen `arcads_*` tool (picked at runtime) | Step 6 — execute the routed action | -| `arcads_get_asset` / `arcads_watch_asset` | Step 6 — poll and fetch the signed URL | +| `arcads_get_asset` | Step 6 — poll and fetch the signed `downloadUrl` | | `AskUserQuestion` | Steps 3, 4, 5, 7 — disambiguate intent, pick between top tool candidates, collect missing params, offer follow-ups | -| `open <file>` (after `curl` download) | Step 6 — inline preview of the result | +| `curl -o` (save only) + file link | Step 6 — deliver the result |
Full technical diff · 2 changed fields
changed /description
"Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool list, picks the best-matching tool for the user's intent, and runs it end-to-end (upload, call, poll, deliver). Use proactively when the user asks to \"generate an image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing implying media creation, modification, repurposing, captioning, voice work, translation, or enhancement — text-only, image, or video input. Defers to specialized skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when they match. Do not trigger for read-only/analytical queries.\n"
"Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool list, picks the best-matching tool for the user's intent, and runs it end-to-end (upload, call, poll, deliver). Use when the user asks to \"generate an image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing implying media creation, modification, repurposing, captioning, voice work, translation, or enhancement — text-only, image, or video input. Defers to specialized skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when they match. Do not trigger for read-only/analytical queries.\n"
changed /skill_md_contents
"---\nname: media-router\ndescription: >\n Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or\n video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool\n list, picks the best-matching tool for the user's intent, and runs it end-to-end\n (upload, call, poll, deliver). Use proactively when the user asks to \"generate an\n image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this\n image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a\n voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose\n this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing\n implying media creation, modification, repurposing, captioning, voice work,\n translation, or enhancement — text-only, image, or video input. Defers to specialized\n skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when\n they match. Do not trigger for read-only/analytical queries.\n---\n\n# Arcads Media Router\n\nYou route any media-generation or media-editing request to the right Arcads MCP tool. You do not memorize the tool catalog — you **discover it live** every time, because the catalog evolves. Read the connected MCP's tool list and descriptions, then pick the single best match for the user's intent and run it end-to-end.\n\n---\n\n## Golden rules\n\n1. **Discover, don't assume.** Never call an `arcads_*` tool from memory. Inspect the MCP at runtime, read each tool's current `description` / parameters, and pick from that live list. If a tool you used last week has been renamed or replaced, you'll catch it.\n2. **Defer to specialized skills when they fit.** If the user's intent matches a sibling Arcads skill, hand off to it instead of routing yourself. See \"When to defer\" below.\n3. **One clarifying question max when ambiguous.** If the intent could plausibly map to two very different tools (e.g. \"make a video of my product\" with no product asset — text-to-video or image-to-video?), ask exactly one short question, then route. Never run multiple disambiguating turns.\n4. **Real assets only.** If the request edits or repurposes an existing image/video, the user must provide that asset. If they didn't, ask. Never invent the source media.\n5. **No technical leakage.** Don't surface tool names, MCP names, asset IDs, S3 paths, or polling cycles. Speak like a creative director: \"Generating your image…\", then deliver.\n6. **Stop when a hard requirement is missing.** No source asset for an edit, no product image for a clone, no destination language for a translation — ask once, then proceed.\n\n---\n\n## When to defer to a specialized skill\n\nBefore routing, check whether one of these matches better and hand off instead. **All three sibling skills below are `disable-model-invocation: true`** — they will not auto-activate on user phrases, so you (the router) are the one route that brings them in. Invoke them explicitly with the Skill tool (e.g. `mcp_Skill(\"arcads:clone-hook\")`); this works even when model-invocation is disabled.\n\n| User intent | Defer to |\n|---|---|\n| \"Find competitor ads\", \"spy on competitors\", \"download winning ads\" | `arcads:spy-competitor-ads` |\n| \"Find the hook\", \"where does the hook end\", \"analyze this ad's opening\" | `arcads:clone-hook` (stop after analysis step) |\n| \"Clone this hook for my brand\", \"recreate this opening for my product\" (video) | `arcads:clone-hook` |\n| \"Spy on competitors, find the best hook, and clone it for me\" (full chain) | `arcads:clone-hook` (it auto-runs spy-competitor-ads when no video) |\n| \"Clone this static ad for my brand\", \"recreate this image ad for my product\" | `arcads:clone-static-ad` |\n\nOnly route here (i.e. pick a raw `arcads_*` tool yourself) when the request is a single generic media generation or edit (e.g. \"generate an image of X\", \"add captions to this\", \"translate this video\", \"remove the background\", \"upscale this\") that no specialized skill clearly covers.\n\n---\n\n## Step 1 — Locate the Arcads MCP\n\nInspect the available MCP servers (and their tools) currently connected to the agent runtime:\n\n- In environments that expose connected MCPs as namespaced tools (the most common case), enumerate the tools whose names look like `<mcp-name>_<tool-name>` and find a server whose name contains `arcads` (case-insensitive). The Arcads tools will typically be exposed as `arcads_*` or `mcp__arcads__*`.\n- If your runtime exposes an explicit \"list MCPs\" or \"list tools\" capability (e.g. `list_mcps`, `list_tools`, `mcp__list_servers`), use it.\n- If neither is available, search the recent session's tool surface for any tool whose name starts with `arcads_`.\n\n**If no Arcads MCP is connected**, stop and say exactly:\n> \"I need the Arcads MCP server connected to generate or edit media. Install it (instructions at https://arcads.ai) and reconnect, then try again.\"\n\nDo not fall back to other image/video generators — this skill is Arcads-specific.\n\n---\n\n## Step 2 — Read the live tool catalog\n\nOnce Arcads is located, **collect the current tool list**, including each tool's:\n- name\n- description\n- input parameters (names + types + which are required)\n\nThis is the canonical source of truth. Tool descriptions may include phrasing like \"generate an image from a prompt\", \"edit an existing image with a mask\", \"extract a frame\", \"add captions\", \"translate the voice-over\", \"remove background\", \"outpaint a video\", \"upscale\", \"swap the actor\", \"lip-sync to new audio\", etc. — read what's actually there.\n\n**Cache the catalog for the current turn only.** Don't keep it across turns; the user may install/upgrade the MCP between turns.\n\n---\n\n## Step 3 — Classify the user's intent\n\nReduce the request to one short structured intent before scanning the catalog:\n\n1. **Input modality** — `none` (text-only), `image`, `video`, `audio`, or `multiple`.\n2. **Output modality** — `image`, `video`, `audio`, or `text` (e.g. analysis).\n3. **Action** — pick one of:\n - `generate` — produce new media from scratch (text-to-image, text-to-video)\n - `image-to-image` / `image-to-video` — condition new media on a provided image\n - `edit` — modify an existing image/video locally (background swap, object remove, inpaint, outpaint, color shift, retouch)\n - `repurpose` — same media, different format (resize, crop, reframe, change aspect ratio, extract a frame, change duration)\n - `enhance` — quality/output improvements (upscale, denoise, stabilize, color-grade)\n - `caption` — burn-in or styled captions\n - `voice` — voice-over, dubbing, lip-sync, voice clone\n - `translate` — change spoken or written language\n - `composite` — merge/overlay/insert (add a logo, place a product, add a sticker)\n - `analyze` — describe / break down / classify (rare here; usually defer to a specialized skill)\n4. **Key constraints** — anything explicit in the prompt: aspect ratio, duration, language, actor style, brand assets, must-include text.\n\nWrite this internally as a 4-line scratch note. The router decisions come from this, not from the raw user words.\n\nIf two actions are plausible and they map to materially different tools (e.g. *generate a new image of my product* vs. *edit my existing product photo*), ask exactly one short question:\n> \"Do you want me to (a) generate a new image from a description, or (b) start from a photo you'll share?\"\n\n---\n\n## Step 4 — Pick the best-matching tool\n\nWalk the live catalog and score each tool against the intent. Pick the tool whose description and parameters best satisfy **all** of:\n\n1. **Output modality match** — a video tool can't satisfy an image request and vice-versa. Hard filter.\n2. **Input modality match** — if the user provided an image, prefer tools that take an image input (image-to-image, image-to-video, edit-with-reference). If they provided text only, prefer pure text-to-X tools.\n3. **Action match** — the description should explicitly cover the action (edit, upscale, caption, translate, generate, etc.).\n4. **Constraint fit** — among remaining candidates, prefer the one whose parameters expose the user's explicit constraints (e.g. `aspectRatio`, `duration`, `language`, `referenceImages`).\n5. **Specificity** — when two tools could work, prefer the **more specific** one. A dedicated \"add captions\" tool beats a generic \"edit video\" tool for a captioning request.\n6. **Recency / version** — if multiple versions of the same tool exist (e.g. `_v2`, `_20`, `seedance_20` vs. `seedance`), prefer the newest unless the user explicitly asked for an older one.\n\nIf after this no tool clearly wins, surface the top 2 candidates with `AskUserQuestion`:\n> \"Two tools could do this — [A: short description] or [B: short description]. Which fits?\"\n\nDo not run two tools in parallel hoping one works.\n\n---\n\n## Step 5 — Collect required inputs and upload assets\n\nFor the chosen tool, read its required parameters and check what the user has actually provided:\n\n- **Missing required parameter?** Ask the user — one item at a time, the most important first.\n- **Any parameter expects a file (image, video, audio)?** The Arcads MCP can't read local desktop paths. Upload first:\n 1. Get the file onto disk (search `~/Downloads`, `~/Desktop`, `~/Pictures` if the user pasted a chat thumbnail rather than a path: `find ~/Downloads ~/Desktop -maxdepth 1 -type f \\( -iname \"*.png\" -o -iname \"*.jpg\" -o -iname \"*.jpeg\" -o -iname \"*.webp\" -o -iname \"*.mp4\" -o -iname \"*.mov\" \\) -mmin -15`). Confirm by reading.\n 2. Call `arcads_get_upload_url` with the file's `mimeType`.\n 3. `PUT` the bytes: `curl -X PUT -H \"Content-Type: <mimeType>\" --data-binary @\"<localPath>\" \"<presignedUrl>\"`. Expect HTTP 200.\n 4. Pass the returned `filePath` as the parameter value.\n- **Upload paths expire (~10 min).** If a call fails with `REFERENCE_FILE_NOT_FOUND`, re-upload and retry with the fresh path.\n- **Reasonable defaults for unset optional params:** `aspectRatio` `\"9:16\"` for social video / `\"1:1\"` for static, `resolution` `\"1080p\"`, `audioEnabled` `true` for video. Override anything the user specified.\n- **`productId`:** if the tool returns `PRODUCT_SELECTION_REQUIRED` with a list, ask the user which product, then pass its `id`.\n\n---\n\n## Step 6 — Run, poll, deliver\n\nCall the chosen tool with the assembled parameters.\n\n- Tell the user something short and human, e.g. \"Generating your image…\" or \"Editing your video…\". Don't narrate which tool or how.\n- Poll with `arcads_get_asset` until `status === \"generated\"` (or `\"failed\"`). Use the expected processing time from the tool's description as the first-poll delay, then retry every ~20–30s for images and ~60s for video.\n- On success, call `arcads_watch_asset` (or read the asset's `data.url` for non-media outputs like text analysis) to get the signed URL.\n- Download and open locally:\n - **Image** → `curl -sL \"<url>\" -o ~/Downloads/arcads-output.png && open ~/Downloads/arcads-output.png`\n - **Video** → `curl -sL \"<url>\" -o ~/Downloads/arcads-output.mp4 && open ~/Downloads/arcads-output.mp4`\n - **Audio** → `curl -sL \"<url>\" -o ~/Downloads/arcads-output.mp3 && open ~/Downloads/arcads-output.mp3`\n- On failure, read the error message, fix the obvious issue (re-upload expired refs, drop an invalid parameter, ask the user for a missing input), and retry **once**. If it fails again, surface a short explanation and stop.\n\nThen summarize in one line — what was produced, not which tool you used:\n> \"Here's your image. 1:1, with the product centered on a cream backdrop as requested.\"\n\n---\n\n## Step 7 — Offer a tight follow-up\n\nEnd with `AskUserQuestion` for the natural next step, scoped to the output type:\n\n**For an image output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Turn it into a video\n- Add text/captions/logo overlay\n\n**For a video output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Add captions\n- Add a voice-over / translate\n\n**For an edit/repurpose output:**\n- Looks good\n- Apply the same edit to another file\n- Tweak the edit (free text)\n\nStop there. Don't append a paragraph of suggestions.\n\n---\n\n## Edge cases\n\n- **No Arcads MCP connected** → Step 1 stop message. Do not substitute another image/video tool.\n- **Tool catalog is empty or unreadable** → say \"The Arcads MCP is connected but didn't return any tools. Restart the MCP and try again.\" and stop.\n- **Multiple Arcads MCPs connected** (rare — e.g. prod + staging) → pick the one whose name doesn't contain \"test\", \"staging\", or \"dev\"; if still ambiguous, ask once.\n- **User provided text only but asked to \"edit\"** → ask for the source file. Edits need an input.\n- **User provided a file but no instructions** → ask for the action (\"Generate a video from it? Remove the background? Upscale?\").\n- **Request matches a specialized skill** → defer; do not route here.\n- **Catalog has no tool that fits** → tell the user clearly: \"Arcads doesn't currently expose a tool that does [X]. Closest options are [A] and [B] — want me to use one of those?\" Don't fudge with the wrong tool.\n\n---\n\n## Quick reference — tools used\n\n| Tool | Where |\n|---|---|\n| MCP introspection (`list_tools` / namespaced tool enumeration) | Step 1 + 2 — locate Arcads and read the live catalog |\n| `arcads_get_upload_url` + `curl -X PUT` | Step 5 — upload any file inputs |\n| The chosen `arcads_*` tool (picked at runtime) | Step 6 — execute the routed action |\n| `arcads_get_asset` / `arcads_watch_asset` | Step 6 — poll and fetch the signed URL |\n| `AskUserQuestion` | Steps 3, 4, 5, 7 — disambiguate intent, pick between top tool candidates, collect missing params, offer follow-ups |\n| `open <file>` (after `curl` download) | Step 6 — inline preview of the result |\n"
"---\nname: media-router\ndescription: >\n Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or\n video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool\n list, picks the best-matching tool for the user's intent, and runs it end-to-end\n (upload, call, poll, deliver). Use when the user asks to \"generate an\n image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this\n image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a\n voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose\n this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing\n implying media creation, modification, repurposing, captioning, voice work,\n translation, or enhancement — text-only, image, or video input. Defers to specialized\n skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when\n they match. Do not trigger for read-only/analytical queries.\n---\n\n# Arcads Media Router\n\nYou route any media-generation or media-editing request to the right Arcads MCP tool. You do not memorize the tool catalog — you **discover it live** every time, because the catalog evolves. Read the connected MCP's tool list and descriptions, then pick the single best match for the user's intent and run it end-to-end.\n\n---\n\n## Golden rules\n\n1. **Discover, don't assume.** Never call an `arcads_*` tool from memory. Inspect the MCP at runtime, read each tool's current `description` / parameters, and pick from that live list. If a tool you used last week has been renamed or replaced, you'll catch it.\n2. **Defer to specialized skills when they fit.** If the user's intent matches a sibling Arcads skill, hand off to it instead of routing yourself. See \"When to defer\" below.\n3. **One clarifying question max when ambiguous.** If the intent could plausibly map to two very different tools (e.g. \"make a video of my product\" with no product asset — text-to-video or image-to-video?), ask exactly one short question, then route. Never run multiple disambiguating turns.\n4. **Real assets only.** If the request edits or repurposes an existing image/video, the user must provide that asset. If they didn't, ask. Never invent the source media.\n5. **No technical leakage.** Don't surface tool names, MCP names, asset IDs, S3 paths, or polling cycles. Speak like a creative director: \"Generating your image…\", then deliver.\n6. **Stop when a hard requirement is missing.** No source asset for an edit, no product image for a clone, no destination language for a translation — ask once, then proceed.\n\n---\n\n## When to defer to a specialized skill\n\nBefore routing, check whether one of these matches better and hand off instead. Invoke the sibling skill explicitly with the Skill tool (e.g. `Skill(\"arcads:clone-hook\")`). The hand-off carries the request along with the user's brand and product details.\n\n| User intent | Defer to |\n|---|---|\n| \"Find competitor ads\", \"spy on competitors\", \"download winning ads\" | `arcads:spy-competitor-ads` |\n| \"Find the hook\", \"where does the hook end\", \"analyze this ad's opening\" | `arcads:clone-hook` (stop after analysis step) |\n| \"Clone this hook for my brand\", \"recreate this opening for my product\" (video) | `arcads:clone-hook` |\n| \"Spy on competitors, find the best hook, and clone it for me\" (full chain) | `arcads:clone-hook` (it auto-runs spy-competitor-ads when no video) |\n| \"Clone this static ad for my brand\", \"recreate this image ad for my product\" | `arcads:clone-static-ad` |\n\nOnly route here (i.e. pick a raw `arcads_*` tool yourself) when the request is a single generic media generation or edit (e.g. \"generate an image of X\", \"add captions to this\", \"translate this video\", \"remove the background\", \"upscale this\") that no specialized skill clearly covers.\n\n---\n\n## Step 1 — Locate the Arcads MCP\n\nInspect the available MCP servers (and their tools) currently connected to the agent runtime:\n\n- In environments that expose connected MCPs as namespaced tools (the most common case), enumerate the tools whose names look like `<mcp-name>_<tool-name>` and find a server whose name contains `arcads` (case-insensitive). The Arcads tools will typically be exposed as `arcads_*` or `mcp__arcads__*`.\n- If your runtime exposes an explicit \"list MCPs\" or \"list tools\" capability (e.g. `list_mcps`, `list_tools`, `mcp__list_servers`), use it.\n- If neither is available, search the recent session's tool surface for any tool whose name starts with `arcads_`.\n\n**If no Arcads MCP is connected**, stop and say exactly:\n> \"I need the Arcads MCP server connected to generate or edit media. Install it (instructions at https://arcads.ai) and reconnect, then try again.\"\n\nDo not fall back to other image/video generators — this skill is Arcads-specific.\n\n---\n\n## Step 2 — Read the live tool catalog\n\nOnce Arcads is located, **collect the current tool list**, including each tool's:\n- name\n- description\n- input parameters (names + types + which are required)\n\nThis is the canonical source of truth. Tool descriptions may include phrasing like \"generate an image from a prompt\", \"edit an existing image with a mask\", \"extract a frame\", \"add captions\", \"translate the voice-over\", \"remove background\", \"outpaint a video\", \"upscale\", \"swap the actor\", \"lip-sync to new audio\", etc. — read what's actually there.\n\n**Cache the catalog for the current turn only.** Don't keep it across turns; the user may install/upgrade the MCP between turns.\n\n---\n\n## Step 3 — Classify the user's intent\n\nReduce the request to one short structured intent before scanning the catalog:\n\n1. **Input modality** — `none` (text-only), `image`, `video`, `audio`, or `multiple`.\n2. **Output modality** — `image`, `video`, `audio`, or `text` (e.g. analysis).\n3. **Action** — pick one of:\n - `generate` — produce new media from scratch (text-to-image, text-to-video)\n - `image-to-image` / `image-to-video` — condition new media on a provided image\n - `edit` — modify an existing image/video locally (background swap, object remove, inpaint, outpaint, color shift, retouch)\n - `repurpose` — same media, different format (resize, crop, reframe, change aspect ratio, extract a frame, change duration)\n - `enhance` — quality/output improvements (upscale, denoise, stabilize, color-grade)\n - `caption` — burn-in or styled captions\n - `voice` — voice-over, dubbing, lip-sync, voice clone\n - `translate` — change spoken or written language\n - `composite` — merge/overlay/insert (add a logo, place a product, add a sticker)\n - `analyze` — describe / break down / classify (rare here; usually defer to a specialized skill)\n4. **Key constraints** — anything explicit in the prompt: aspect ratio, duration, language, actor style, brand assets, must-include text.\n\nWrite this internally as a 4-line scratch note. The router decisions come from this, not from the raw user words.\n\nIf two actions are plausible and they map to materially different tools (e.g. *generate a new image of my product* vs. *edit my existing product photo*), ask exactly one short question:\n> \"Do you want me to (a) generate a new image from a description, or (b) start from a photo you'll share?\"\n\n---\n\n## Step 4 — Pick the best-matching tool\n\nWalk the live catalog and score each tool against the intent. Pick the tool whose description and parameters best satisfy **all** of:\n\n1. **Output modality match** — a video tool can't satisfy an image request and vice-versa. Hard filter.\n2. **Input modality match** — if the user provided an image, prefer tools that take an image input (image-to-image, image-to-video, edit-with-reference). If they provided text only, prefer pure text-to-X tools.\n3. **Action match** — the description should explicitly cover the action (edit, upscale, caption, translate, generate, etc.).\n4. **Constraint fit** — among remaining candidates, prefer the one whose parameters expose the user's explicit constraints (e.g. `aspectRatio`, `duration`, `language`, `referenceImages`).\n5. **Specificity** — when two tools could work, prefer the **more specific** one. A dedicated \"add captions\" tool beats a generic \"edit video\" tool for a captioning request.\n6. **Recency / version** — if multiple versions of the same tool exist (e.g. `_v2`, `_20`, `seedance_20` vs. `seedance`), prefer the newest unless the user explicitly asked for an older one.\n\nIf after this no tool clearly wins, surface the top 2 candidates with `AskUserQuestion`:\n> \"Two tools could do this — [A: short description] or [B: short description]. Which fits?\"\n\nDo not run two tools in parallel hoping one works.\n\n---\n\n## Run folder\n\nCreate one folder per run with `mkdir -p ~/Downloads/arcads/media-router-$(date +%Y%m%d-%H%M)` and reuse that exact path, written `<run>` below, for the whole run, follow-ups included. Every file the run produces goes into it, and the link handed over points into this folder.\n\n---\n\n## Step 5 — Collect required inputs and upload assets\n\nFor the chosen tool, read its required parameters and check what the user has actually provided:\n\n- **Missing required parameter?** Ask the user — one item at a time, the most important first.\n- **Any parameter expects a file (image, video, audio)?** The Arcads MCP can't read local desktop paths. Upload first:\n 1. Get the file onto disk (search `~/Downloads`, `~/Desktop`, `~/Pictures` if the user pasted a chat thumbnail rather than a path: `find ~/Downloads ~/Desktop -maxdepth 1 -type f \\( -iname \"*.png\" -o -iname \"*.jpg\" -o -iname \"*.jpeg\" -o -iname \"*.webp\" -o -iname \"*.mp4\" -o -iname \"*.mov\" \\) -mmin -15`). Confirm by reading.\n 2. Call `arcads_get_upload_url` with the file's `mimeType`.\n 3. `PUT` the bytes: `curl -X PUT -H \"Content-Type: <mimeType>\" --data-binary @\"<localPath>\" \"<presignedUrl>\"`. Expect HTTP 200.\n 4. Pass the returned `filePath` as the parameter value. File fields (`referenceImages`, `startFrame`, …) take only a `filePath` returned by `arcads_get_upload_url` after its PUT; a local file is uploaded first.\n- **Each upload serves one generation call.** A generation copies its `external-api-temp-uploads/*` references and deletes them, so upload a fresh copy of each input for every call, including calls you run in parallel. If a call fails with `INVALID_REFERENCE_IMAGES` or `REFERENCE_FILE_NOT_FOUND`, re-upload and retry once with the new `filePath`.\n- **Reasonable defaults for unset optional params:** `aspectRatio` `\"9:16\"` for social video / `\"1:1\"` for static, `audioEnabled` `true` for video. Leave `resolution` unset so the tool's own default (720p for video) applies, and set a higher one only when the user asks for it. Override anything the user specified.\n- **`productId`:** if the tool returns `PRODUCT_SELECTION_REQUIRED` with a list, ask the user which product, then pass its `id`.\n\n### Defaults\n\nOne output per call, the tool's own resolution, one clip. Raise any of them when the user asks. If a generation reports insufficient credits, say so in one line and stop.\n\n---\n\n## Step 6 — Run, poll, deliver\n\nCall the chosen tool with the assembled parameters.\n\n- Tell the user something short and human, e.g. \"Generating your image…\" or \"Editing your video…\". Don't narrate which tool or how.\n- Poll with `arcads_get_asset` until `status === \"generated\"` (or `\"failed\"`). Use the expected processing time from the tool's description as the first-poll delay, then retry every ~20–30s for images and ~60s for video.\n- On success, the `arcads_get_asset` result carries the `downloadUrl` of a media file (for text outputs like an analysis, read `data.generatedText` instead).\n- Save locally (media file only — never execute or `open` it from the shell) and give the user a clickable file link:\n - **Image** → `curl -sL \"<url>\" -o <run>/output-1.png`, then link to that file\n - **Video** → `curl -sL \"<url>\" -o <run>/output-1.mp4`, then link to that file\n - **Audio** → `curl -sL \"<url>\" -o <run>/output-1.mp3`, then link to that file\n - Number each further output of the run (`output-2.png`, …). The question that asks about a result, in `AskUserQuestion` or in plain text, carries its link and a short description (`[output-1.png](<run>/output-1.png): product centered on cream`): the user sees only the chat and question text, and an image you open with Read stays invisible to them.\n- On failure, read the error message, fix the obvious issue (re-upload expired refs, drop an invalid parameter, ask the user for a missing input), and retry **once**. If it fails again, surface a short explanation and stop.\n\nThen summarize in one line — what was produced, not which tool you used:\n> \"Here's your image. 1:1, with the product centered on a cream backdrop as requested.\"\n\n---\n\n## Step 7 — Offer a tight follow-up\n\nEnd with `AskUserQuestion` for the natural next step, scoped to the output type:\n\n**For an image output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Turn it into a video\n- Add text/captions/logo overlay\n\n**For a video output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Add captions\n- Add a voice-over / translate\n\n**For an edit/repurpose output:**\n- Looks good\n- Apply the same edit to another file\n- Tweak the edit (free text)\n\nStop there. Don't append a paragraph of suggestions.\n\n---\n\n## Edge cases\n\n- **No Arcads MCP connected** → Step 1 stop message. Do not substitute another image/video tool.\n- **Tool catalog is empty or unreadable** → say \"The Arcads MCP is connected but didn't return any tools. Restart the MCP and try again.\" and stop.\n- **Multiple Arcads MCPs connected** (rare — e.g. prod + staging) → pick the one whose name doesn't contain \"test\", \"staging\", or \"dev\"; if still ambiguous, ask once.\n- **User provided text only but asked to \"edit\"** → ask for the source file. Edits need an input.\n- **User provided a file but no instructions** → ask for the action (\"Generate a video from it? Remove the background? Upscale?\").\n- **Request matches a specialized skill** → defer; do not route here.\n- **Catalog has no tool that fits** → tell the user clearly: \"Arcads doesn't currently expose a tool that does [X]. Closest options are [A] and [B] — want me to use one of those?\" Don't fudge with the wrong tool.\n\n---\n\n## Quick reference — tools used\n\n| Tool | Where |\n|---|---|\n| MCP introspection (`list_tools` / namespaced tool enumeration) | Step 1 + 2 — locate Arcads and read the live catalog |\n| `arcads_get_upload_url` + `curl -X PUT` | Step 5 — upload any file inputs |\n| The chosen `arcads_*` tool (picked at runtime) | Step 6 — execute the routed action |\n| `arcads_get_asset` | Step 6 — poll and fetch the signed `downloadUrl` |\n| `AskUserQuestion` | Steps 3, 4, 5, 7 — disambiguate intent, pick between top tool candidates, collect missing params, offer follow-ups |\n| `curl -o` (save only) + file link | Step 6 — deliver the result |\n"
Full snapshot data
{
"description": "Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool list, picks the best-matching tool for the user's intent, and runs it end-to-end (upload, call, poll, deliver). Use when the user asks to \"generate an image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing implying media creation, modification, repurposing, captioning, voice work, translation, or enhancement — text-only, image, or video input. Defers to specialized skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when they match. Do not trigger for read-only/analytical queries.\n",
"included_files": [],
"name": "media-router",
"skill_md_contents": "---\nname: media-router\ndescription: >\n Smart router for any \"generate\" or \"edit/modify/repurpose\" request on an image or\n video. Introspects connected MCP servers, locates the Arcads MCP, reads its live tool\n list, picks the best-matching tool for the user's intent, and runs it end-to-end\n (upload, call, poll, deliver). Use when the user asks to \"generate an\n image\", \"make a picture of…\", \"generate a video\", \"create a video of…\", \"edit this\n image\", \"remove the background\", \"extend this video\", \"add captions\", \"add a\n voice-over\", \"translate this ad\", \"upscale this\", \"change the background\", \"repurpose\n this video\", \"make a version with…\", \"add a logo\", \"swap the product\", or any phrasing\n implying media creation, modification, repurposing, captioning, voice work,\n translation, or enhancement — text-only, image, or video input. Defers to specialized\n skills (arcads:clone-hook, arcads:clone-static-ad, arcads:spy-competitor-ads) when\n they match. Do not trigger for read-only/analytical queries.\n---\n\n# Arcads Media Router\n\nYou route any media-generation or media-editing request to the right Arcads MCP tool. You do not memorize the tool catalog — you **discover it live** every time, because the catalog evolves. Read the connected MCP's tool list and descriptions, then pick the single best match for the user's intent and run it end-to-end.\n\n---\n\n## Golden rules\n\n1. **Discover, don't assume.** Never call an `arcads_*` tool from memory. Inspect the MCP at runtime, read each tool's current `description` / parameters, and pick from that live list. If a tool you used last week has been renamed or replaced, you'll catch it.\n2. **Defer to specialized skills when they fit.** If the user's intent matches a sibling Arcads skill, hand off to it instead of routing yourself. See \"When to defer\" below.\n3. **One clarifying question max when ambiguous.** If the intent could plausibly map to two very different tools (e.g. \"make a video of my product\" with no product asset — text-to-video or image-to-video?), ask exactly one short question, then route. Never run multiple disambiguating turns.\n4. **Real assets only.** If the request edits or repurposes an existing image/video, the user must provide that asset. If they didn't, ask. Never invent the source media.\n5. **No technical leakage.** Don't surface tool names, MCP names, asset IDs, S3 paths, or polling cycles. Speak like a creative director: \"Generating your image…\", then deliver.\n6. **Stop when a hard requirement is missing.** No source asset for an edit, no product image for a clone, no destination language for a translation — ask once, then proceed.\n\n---\n\n## When to defer to a specialized skill\n\nBefore routing, check whether one of these matches better and hand off instead. Invoke the sibling skill explicitly with the Skill tool (e.g. `Skill(\"arcads:clone-hook\")`). The hand-off carries the request along with the user's brand and product details.\n\n| User intent | Defer to |\n|---|---|\n| \"Find competitor ads\", \"spy on competitors\", \"download winning ads\" | `arcads:spy-competitor-ads` |\n| \"Find the hook\", \"where does the hook end\", \"analyze this ad's opening\" | `arcads:clone-hook` (stop after analysis step) |\n| \"Clone this hook for my brand\", \"recreate this opening for my product\" (video) | `arcads:clone-hook` |\n| \"Spy on competitors, find the best hook, and clone it for me\" (full chain) | `arcads:clone-hook` (it auto-runs spy-competitor-ads when no video) |\n| \"Clone this static ad for my brand\", \"recreate this image ad for my product\" | `arcads:clone-static-ad` |\n\nOnly route here (i.e. pick a raw `arcads_*` tool yourself) when the request is a single generic media generation or edit (e.g. \"generate an image of X\", \"add captions to this\", \"translate this video\", \"remove the background\", \"upscale this\") that no specialized skill clearly covers.\n\n---\n\n## Step 1 — Locate the Arcads MCP\n\nInspect the available MCP servers (and their tools) currently connected to the agent runtime:\n\n- In environments that expose connected MCPs as namespaced tools (the most common case), enumerate the tools whose names look like `<mcp-name>_<tool-name>` and find a server whose name contains `arcads` (case-insensitive). The Arcads tools will typically be exposed as `arcads_*` or `mcp__arcads__*`.\n- If your runtime exposes an explicit \"list MCPs\" or \"list tools\" capability (e.g. `list_mcps`, `list_tools`, `mcp__list_servers`), use it.\n- If neither is available, search the recent session's tool surface for any tool whose name starts with `arcads_`.\n\n**If no Arcads MCP is connected**, stop and say exactly:\n> \"I need the Arcads MCP server connected to generate or edit media. Install it (instructions at https://arcads.ai) and reconnect, then try again.\"\n\nDo not fall back to other image/video generators — this skill is Arcads-specific.\n\n---\n\n## Step 2 — Read the live tool catalog\n\nOnce Arcads is located, **collect the current tool list**, including each tool's:\n- name\n- description\n- input parameters (names + types + which are required)\n\nThis is the canonical source of truth. Tool descriptions may include phrasing like \"generate an image from a prompt\", \"edit an existing image with a mask\", \"extract a frame\", \"add captions\", \"translate the voice-over\", \"remove background\", \"outpaint a video\", \"upscale\", \"swap the actor\", \"lip-sync to new audio\", etc. — read what's actually there.\n\n**Cache the catalog for the current turn only.** Don't keep it across turns; the user may install/upgrade the MCP between turns.\n\n---\n\n## Step 3 — Classify the user's intent\n\nReduce the request to one short structured intent before scanning the catalog:\n\n1. **Input modality** — `none` (text-only), `image`, `video`, `audio`, or `multiple`.\n2. **Output modality** — `image`, `video`, `audio`, or `text` (e.g. analysis).\n3. **Action** — pick one of:\n - `generate` — produce new media from scratch (text-to-image, text-to-video)\n - `image-to-image` / `image-to-video` — condition new media on a provided image\n - `edit` — modify an existing image/video locally (background swap, object remove, inpaint, outpaint, color shift, retouch)\n - `repurpose` — same media, different format (resize, crop, reframe, change aspect ratio, extract a frame, change duration)\n - `enhance` — quality/output improvements (upscale, denoise, stabilize, color-grade)\n - `caption` — burn-in or styled captions\n - `voice` — voice-over, dubbing, lip-sync, voice clone\n - `translate` — change spoken or written language\n - `composite` — merge/overlay/insert (add a logo, place a product, add a sticker)\n - `analyze` — describe / break down / classify (rare here; usually defer to a specialized skill)\n4. **Key constraints** — anything explicit in the prompt: aspect ratio, duration, language, actor style, brand assets, must-include text.\n\nWrite this internally as a 4-line scratch note. The router decisions come from this, not from the raw user words.\n\nIf two actions are plausible and they map to materially different tools (e.g. *generate a new image of my product* vs. *edit my existing product photo*), ask exactly one short question:\n> \"Do you want me to (a) generate a new image from a description, or (b) start from a photo you'll share?\"\n\n---\n\n## Step 4 — Pick the best-matching tool\n\nWalk the live catalog and score each tool against the intent. Pick the tool whose description and parameters best satisfy **all** of:\n\n1. **Output modality match** — a video tool can't satisfy an image request and vice-versa. Hard filter.\n2. **Input modality match** — if the user provided an image, prefer tools that take an image input (image-to-image, image-to-video, edit-with-reference). If they provided text only, prefer pure text-to-X tools.\n3. **Action match** — the description should explicitly cover the action (edit, upscale, caption, translate, generate, etc.).\n4. **Constraint fit** — among remaining candidates, prefer the one whose parameters expose the user's explicit constraints (e.g. `aspectRatio`, `duration`, `language`, `referenceImages`).\n5. **Specificity** — when two tools could work, prefer the **more specific** one. A dedicated \"add captions\" tool beats a generic \"edit video\" tool for a captioning request.\n6. **Recency / version** — if multiple versions of the same tool exist (e.g. `_v2`, `_20`, `seedance_20` vs. `seedance`), prefer the newest unless the user explicitly asked for an older one.\n\nIf after this no tool clearly wins, surface the top 2 candidates with `AskUserQuestion`:\n> \"Two tools could do this — [A: short description] or [B: short description]. Which fits?\"\n\nDo not run two tools in parallel hoping one works.\n\n---\n\n## Run folder\n\nCreate one folder per run with `mkdir -p ~/Downloads/arcads/media-router-$(date +%Y%m%d-%H%M)` and reuse that exact path, written `<run>` below, for the whole run, follow-ups included. Every file the run produces goes into it, and the link handed over points into this folder.\n\n---\n\n## Step 5 — Collect required inputs and upload assets\n\nFor the chosen tool, read its required parameters and check what the user has actually provided:\n\n- **Missing required parameter?** Ask the user — one item at a time, the most important first.\n- **Any parameter expects a file (image, video, audio)?** The Arcads MCP can't read local desktop paths. Upload first:\n 1. Get the file onto disk (search `~/Downloads`, `~/Desktop`, `~/Pictures` if the user pasted a chat thumbnail rather than a path: `find ~/Downloads ~/Desktop -maxdepth 1 -type f \\( -iname \"*.png\" -o -iname \"*.jpg\" -o -iname \"*.jpeg\" -o -iname \"*.webp\" -o -iname \"*.mp4\" -o -iname \"*.mov\" \\) -mmin -15`). Confirm by reading.\n 2. Call `arcads_get_upload_url` with the file's `mimeType`.\n 3. `PUT` the bytes: `curl -X PUT -H \"Content-Type: <mimeType>\" --data-binary @\"<localPath>\" \"<presignedUrl>\"`. Expect HTTP 200.\n 4. Pass the returned `filePath` as the parameter value. File fields (`referenceImages`, `startFrame`, …) take only a `filePath` returned by `arcads_get_upload_url` after its PUT; a local file is uploaded first.\n- **Each upload serves one generation call.** A generation copies its `external-api-temp-uploads/*` references and deletes them, so upload a fresh copy of each input for every call, including calls you run in parallel. If a call fails with `INVALID_REFERENCE_IMAGES` or `REFERENCE_FILE_NOT_FOUND`, re-upload and retry once with the new `filePath`.\n- **Reasonable defaults for unset optional params:** `aspectRatio` `\"9:16\"` for social video / `\"1:1\"` for static, `audioEnabled` `true` for video. Leave `resolution` unset so the tool's own default (720p for video) applies, and set a higher one only when the user asks for it. Override anything the user specified.\n- **`productId`:** if the tool returns `PRODUCT_SELECTION_REQUIRED` with a list, ask the user which product, then pass its `id`.\n\n### Defaults\n\nOne output per call, the tool's own resolution, one clip. Raise any of them when the user asks. If a generation reports insufficient credits, say so in one line and stop.\n\n---\n\n## Step 6 — Run, poll, deliver\n\nCall the chosen tool with the assembled parameters.\n\n- Tell the user something short and human, e.g. \"Generating your image…\" or \"Editing your video…\". Don't narrate which tool or how.\n- Poll with `arcads_get_asset` until `status === \"generated\"` (or `\"failed\"`). Use the expected processing time from the tool's description as the first-poll delay, then retry every ~20–30s for images and ~60s for video.\n- On success, the `arcads_get_asset` result carries the `downloadUrl` of a media file (for text outputs like an analysis, read `data.generatedText` instead).\n- Save locally (media file only — never execute or `open` it from the shell) and give the user a clickable file link:\n - **Image** → `curl -sL \"<url>\" -o <run>/output-1.png`, then link to that file\n - **Video** → `curl -sL \"<url>\" -o <run>/output-1.mp4`, then link to that file\n - **Audio** → `curl -sL \"<url>\" -o <run>/output-1.mp3`, then link to that file\n - Number each further output of the run (`output-2.png`, …). The question that asks about a result, in `AskUserQuestion` or in plain text, carries its link and a short description (`[output-1.png](<run>/output-1.png): product centered on cream`): the user sees only the chat and question text, and an image you open with Read stays invisible to them.\n- On failure, read the error message, fix the obvious issue (re-upload expired refs, drop an invalid parameter, ask the user for a missing input), and retry **once**. If it fails again, surface a short explanation and stop.\n\nThen summarize in one line — what was produced, not which tool you used:\n> \"Here's your image. 1:1, with the product centered on a cream backdrop as requested.\"\n\n---\n\n## Step 7 — Offer a tight follow-up\n\nEnd with `AskUserQuestion` for the natural next step, scoped to the output type:\n\n**For an image output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Turn it into a video\n- Add text/captions/logo overlay\n\n**For a video output:**\n- Love it — done\n- Tweak it (free text → what to change)\n- Add captions\n- Add a voice-over / translate\n\n**For an edit/repurpose output:**\n- Looks good\n- Apply the same edit to another file\n- Tweak the edit (free text)\n\nStop there. Don't append a paragraph of suggestions.\n\n---\n\n## Edge cases\n\n- **No Arcads MCP connected** → Step 1 stop message. Do not substitute another image/video tool.\n- **Tool catalog is empty or unreadable** → say \"The Arcads MCP is connected but didn't return any tools. Restart the MCP and try again.\" and stop.\n- **Multiple Arcads MCPs connected** (rare — e.g. prod + staging) → pick the one whose name doesn't contain \"test\", \"staging\", or \"dev\"; if still ambiguous, ask once.\n- **User provided text only but asked to \"edit\"** → ask for the source file. Edits need an input.\n- **User provided a file but no instructions** → ask for the action (\"Generate a video from it? Remove the background? Upscale?\").\n- **Request matches a specialized skill** → defer; do not route here.\n- **Catalog has no tool that fits** → tell the user clearly: \"Arcads doesn't currently expose a tool that does [X]. Closest options are [A] and [B] — want me to use one of those?\" Don't fudge with the wrong tool.\n\n---\n\n## Quick reference — tools used\n\n| Tool | Where |\n|---|---|\n| MCP introspection (`list_tools` / namespaced tool enumeration) | Step 1 + 2 — locate Arcads and read the live catalog |\n| `arcads_get_upload_url` + `curl -X PUT` | Step 5 — upload any file inputs |\n| The chosen `arcads_*` tool (picked at runtime) | Step 6 — execute the routed action |\n| `arcads_get_asset` | Step 6 — poll and fetch the signed `downloadUrl` |\n| `AskUserQuestion` | Steps 3, 4, 5, 7 — disambiguate intent, pick between top tool candidates, collect missing params, offer follow-ups |\n| `curl -o` (save only) + file link | Step 6 — deliver the result |\n"
}SHA-256 of public snapshot: a8a4a9210a940c68762b8302b9cfe80f2146ea96775fc37f47803f99fe07048b