Update to Enkio
Snapshot Oct 26, 2026 · 06:08 UTC · version 1.0.1
Collection source: downloaded plugin package.
Instructions updated for generate-mv
Skill instructions — Now says: Choose model, confirm parameters and credits | 1 | `mv_get_options` returns `confirmation_gate: "plan_and_credit"` | every generation parameter (model,...
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.
Skill instructions
Oct 24, 2026 · 13:32 UTC
Confirm parameters and credits | 1 | `mv_get_options` returns `confirmation_gate: "plan_and_credit"` | every generation parameter (audio, images, prompt, aspect ratio, quality, mode) + story-creation credit cost | confirm these parameter...
Oct 26, 2026 · 06:08 UTC
Choose model, confirm parameters and credits | 1 | `mv_get_options` returns `confirmation_gate: "plan_and_credit"` | every generation parameter (model, audio, images, prompt, aspect ratio, quality) + story-creation credit cost | confirm ...
Supporting files
Oct 24, 2026 · 13:32 UTC
[{"relative_path":"references/auth.md","size_in_bytes":4896},{"relative_path":"references/credits.md","size_in_bytes":3037},{"relative_path":"references/errors.md","size_in_bytes":4802},{"relative_path":"references/workflow.md","size_in_...
Oct 26, 2026 · 06:08 UTC
[{"relative_path":"references/auth.md","size_in_bytes":4896},{"relative_path":"references/credits.md","size_in_bytes":3605},{"relative_path":"references/errors.md","size_in_bytes":5460},{"relative_path":"references/workflow.md","size_in_...
Compare saved observations
Download comparison JSONSKILL.md text changes
− removed · + added
--- before +++ after @@ -30,7 +30,7 @@ The workflow has two stages and is **entirely asynchronous**: submission tools return immediately, so you must poll query tools yourself. ``` -0 Log in / check balance → 1 Upload materials → [GATE 1] 2 Confirm parameters and credits +0 Log in / check balance → 1 Upload materials → [GATE 1] 2 Choose model, confirm parameters and credits → 3 Story creation (charged) → [GATE 2] cover + outline + lyrics + storyline → 4 Edit storyline/lyrics (free), regenerate cover/role (charged) → 5 Shot production (charged) + show shots → [GATE 3] segment images @@ -49,7 +49,7 @@ | Gate | Fires when | You must show | You must ask | Forbidden until the user answers | | --- | --- | --- | --- | --- | -| 1 | `mv_get_options` returns `confirmation_gate: "plan_and_credit"` | every generation parameter (audio, images, prompt, aspect ratio, quality, mode) + story-creation credit cost | confirm these parameters, or change them? | `mv_create_story` | +| 1 | `mv_get_options` returns `confirmation_gate: "plan_and_credit"` | every generation parameter (model, audio, images, prompt, aspect ratio, quality) + story-creation credit cost | confirm these parameters, or change them? | `mv_create_story` | | 2 | `mv_get_story` returns `confirmation_gate: "story_assets"` | cover image + story outline + lyrics + storyline shots, and the shot-production credit cost | edit anything, or start the charged shot production? | `mv_submit_production` | | 3 | `mv_get_production` returns `confirmation_gate: "segments"` | every shot image + the credit cost of this step | regenerate any shot, or accept them? | delivering `result_url` | @@ -157,6 +157,13 @@ The returned `credit` is the current credit balance. `is_member` / `member_level_name` / `expire_time` are membership status. Remember the balance and compare it with the estimated cost when quoting in step 2. +**Membership check (required).** Creating tasks with `mv_create_story` requires an active membership. If +`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url` +and give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare +account used to authorize this MCP, to purchase a membership. Do not continue with model selection, +uploads, quoting, or task creation; after the user says the purchase is complete, call +`get_user_profile()` again and continue only when `is_member` is `true`. + ## Step 1: Upload materials 1. Call `create_upload_url()` to obtain `upload_url` and `headers`. @@ -170,15 +177,20 @@ 3. The `d` in the response is the file URL. `c != 200` means failure; relay `m` to the user. 4. Uploaded files are **temporary storage and will be cleaned up periodically**. After obtaining the URL, submit the task as soon as possible. -## Step 2: Confirm parameters and credits (GATE 1) +## Step 2: Choose model, confirm parameters and credits (GATE 1) + +Call `mv_list_models()` to list the available MV models (`models[].model`, `model_name`, qualities, aspect ratios, +and per-stage credits). If there is more than one, briefly list them for the user and let them choose; otherwise +use the only one. `default_model` is used whenever `model` is omitted. The model is fixed once the task is +created, so it cannot be switched for regeneration or shot production later. -`mv_get_options(audio_duration_sec=<audio seconds>)` returns available qualities, aspect ratios, duration range, prompt length limit, +`mv_get_options(model=<chosen model>, audio_duration_sec=<audio seconds>)` returns available qualities, aspect ratios, duration range, prompt length limit, and credits for each stage (shot production is estimated by duration). It always comes back with `confirmation_gate: "plan_and_credit"`, so **this is GATE 1**. List for the user, item by item: -1. Every parameter you intend to pass to `mv_create_story`: audio file, image files, `prompt`, `ratio`, `quality`, `mode` +1. Every parameter you intend to pass to `mv_create_story`: `model`, audio file, image files, `prompt`, `ratio`, `quality` 2. `step_credit.credit` — the story-creation cost of this step — plus the estimated shot-production cost (`qualities[].estimated_production_credit`) 3. The `credit` balance from step 0; if the balance is insufficient, prompt recharge first (see references/credits.md for the recharge link and steps) and do not force-submit @@ -191,10 +203,11 @@ ## Step 3: Story creation (stage one, charged) ``` -mv_create_story(audio_urls=[...], image_urls=[...], prompt?, ratio?, quality?, mode?) -→ { task_id, task_status, quality, credit_cost } +mv_create_story(audio_urls=[...], image_urls=[...], prompt?, ratio?, quality?, model?) +→ { task_id, task_status, model, model_name, quality, credit_cost } ``` +- `model` must be the same `models[].model` you passed to `mv_get_options`; `ratio` and `quality` must come from that model's options. - `ratio` must be one of the available values from `mv_get_options` (such as `16:9` / `9:16` / `1:1`). - `prompt` uses the user's natural-language description of style and narrative, and may be left empty. @@ -241,7 +254,7 @@ ## Step 5: Shot production (stage two, charged by duration) ``` -mv_submit_production(task_id, mode?) # First call, charges credits +mv_submit_production(task_id) # First call, charges credits mv_get_production(task_id) # Poll ``` @@ -269,7 +282,7 @@ ## Step 6: Single-shot refinement (optional, charged) ``` -mv_regenerate_segment(task_id, segment_index, image_prompt?, video_prompt?, mode?) # Charged +mv_regenerate_segment(task_id, segment_index, image_prompt?, video_prompt?) # Charged mv_get_production(task_id) # Poll this shot mv_submit_production(task_id, compose_only=true) # Free, refresh final MV ```
Full technical diff · 2 changed fields
changed /included_files
[
{
"relative_path": "references/auth.md",
"size_in_bytes": 4896
},
{
"relative_path": "references/credits.md",
"size_in_bytes": 3037
},
{
"relative_path": "references/errors.md",
"size_in_bytes": 4802
},
{
"relative_path": "references/workflow.md",
"size_in_bytes": 8505
}
][
{
"relative_path": "references/auth.md",
"size_in_bytes": 4896
},
{
"relative_path": "references/credits.md",
"size_in_bytes": 3605
},
{
"relative_path": "references/errors.md",
"size_in_bytes": 5460
},
{
"relative_path": "references/workflow.md",
"size_in_bytes": 9004
}
]changed /skill_md_contents
"---\nname: generate-mv\ndescription: Generate a music MV from audio and images (Enkio / enkiomv.ai). Use when the user wants to make an MV, music video, add visuals to a song, turn photos into a beat-synced video, or modify the storyline, lyrics, role image, cover image, or an individual shot of an already generated MV. The entire workflow is completed through the enkio MCP service.\n---\n\n# Generate MV\n\nUse the `enkio` MCP service to call enkiomv.ai's MV Agent and turn one audio track plus several images into an MV.\n\n## Service binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**. Codex normalizes `-` in server names to `_`,\n and tool names do not carry a prefix. Every tool name below (such as `get_user_profile`) refers to the tool of the same name in the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n authorization URL it prints, and give the user only that link to click -- do not lead with the\n `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are two services,\n two accounts, and two credit pools; cross-use will charge real credits to the wrong account). Also do not mix in\n a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, rely on the `brand` / `brand_website`\n returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`.\n Do not answer from memory or guesswork; if `brand` is not Enkio, stop immediately and report an error.\n\nThe workflow has two stages and is **entirely asynchronous**: submission tools return immediately, so you must poll query tools yourself.\n\n```\n0 Log in / check balance → 1 Upload materials → [GATE 1] 2 Confirm parameters and credits\n→ 3 Story creation (charged) → [GATE 2] cover + outline + lyrics + storyline\n→ 4 Edit storyline/lyrics (free), regenerate cover/role (charged)\n→ 5 Shot production (charged) + show shots → [GATE 3] segment images\n→ 6 Regenerate a single shot (optional, charged)\n→ 7 Retrieve final video (free) → Deliver\n```\n\n**Step 5 only shows shot images and does not deliver the final video**; retrieve the final video uniformly in step 7 with `mv_get_production`, which does not charge any credits.\n\n## Mandatory confirmation gates (read this before anything else)\n\nMV generation has **three mandatory user confirmation gates**. They are not suggestions and they\ncannot be merged, skipped, or pre-approved. **Clearing one gate never authorizes the next one.**\n**Every gate must be presented together with the credit cost of that step** (`step_credit` in the\ntool response).\n\n| Gate | Fires when | You must show | You must ask | Forbidden until the user answers |\n| --- | --- | --- | --- | --- |\n| 1 | `mv_get_options` returns `confirmation_gate: \"plan_and_credit\"` | every generation parameter (audio, images, prompt, aspect ratio, quality, mode) + story-creation credit cost | confirm these parameters, or change them? | `mv_create_story` |\n| 2 | `mv_get_story` returns `confirmation_gate: \"story_assets\"` | cover image + story outline + lyrics + storyline shots, and the shot-production credit cost | edit anything, or start the charged shot production? | `mv_submit_production` |\n| 3 | `mv_get_production` returns `confirmation_gate: \"segments\"` | every shot image + the credit cost of this step | regenerate any shot, or accept them? | delivering `result_url` |\n\nThe MCP service reports each gate in its response:\n\n```\nrequires_user_confirmation: true\nconfirmation_gate: \"plan_and_credit\" | \"story_assets\" | \"segments\"\nblocked_until_user_confirms: [\"mv_submit_production\"]\nuser_confirmation_prompt: \"GATE 2 of 3 - STOP AND ASK THE USER. ...\"\nstep_credit: { step: \"storyboard_production\", credit: 150, charged_by: \"audio duration\", ... }\n```\n\n**Whenever `requires_user_confirmation` is `true`: present the artifacts, state the `step_credit`\namount, ask the question, and END YOUR TURN.** Do not call another tool in the same turn, do not\nkeep polling, and do not assume \"the user already said make an MV\" counts as an answer. Only a new\nuser message in this conversation clears a gate.\n\nIf you ever find yourself about to call `mv_create_story` or `mv_submit_production`, or to hand\nover `result_url`, without a user message in between, you have violated this section - stop and ask\ninstead.\n\n## Hard constraints\n\n- **The three confirmation gates above are absolute.** Never chain parameter confirmation → story creation → shot production → final video in one unattended run.\n- **Every gate must state the credit cost of that step** (`step_credit` from the tool response), not just the artifacts.\n- **Operations that charge credits must first explain the cost to the user and obtain confirmation**: story creation, role/cover regeneration, shot production, and single-shot regeneration.\n Free operations: editing the storyline, editing lyrics, compose-only (`compose_only=true`), and query tools (including retrieving the final video in step 7).\n- **After every display of a cover, role, or shot image, proactively tell the user they can spend credits to regenerate it**; see \"Regeneration prompt\".\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already handles them, and they do not exist in tool inputs.\n- Remember the `task_id` after every submission; every later call must include it.\n- Polling cadence: stage one once every 10 seconds, with an upper limit of about 5 minutes; stage two once every 20 seconds, with an upper limit of about 20 minutes.\n During polling, give the user brief progress updates; do not wait silently for a long time.\n- When any status is `fail`, do not blindly retry the whole order. First tell the user which\n item failed and the error message, then ask whether to regenerate that item or abandon it.\n Regenerating re-bills that step at the normal price--failed credits are refunded\n automatically, and this billing rule was already disclosed when quoting each step's cost, so\n no new price confirmation is needed here.\n- **Before showing images/videos, you must download them locally first**. Directly pasting a remote URL cannot be embedded for preview; see the next section.\n\n## Showing artifacts (important)\n\nThe cover image, role image, shot images, and final MV returned by MV Agent are all Enkio **temporary remote URLs**.\nCodex **cannot embed previews for images on these domains**; directly pasting a URL will only display a gray placeholder box.\n\nTherefore: **For every image or video that should be shown to the user, first download it locally with `curl`, then show it using the local path.**\n\nUse a task-isolated working directory by convention (to avoid polluting the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/<task_id>\"\nmkdir -p \"$WORKDIR\"\n\n# Use a meaningful <name>: cover / role / seg-00 / mv\n# Infer the extension from the URL path; if unavailable, use .png (use .mp4 for video)\ncurl -sS -L -o \"$WORKDIR/<name>.<ext>\" \"<remote URL>\"\n```\n\nAfter downloading:\n\n- Show images using the local absolute path so the user can see them directly in the conversation\n- Also include the original remote URL so the user can save it themselves\n- If download fails (non-200 / empty file), clearly state \"preview download failed\" and provide the remote URL so the user can open it themselves;\n do not falsely claim that the image has been shown\n- The working directory is under the system temporary directory; you do not need to clean it up proactively, and do not write it into the user's repository\n\nWhenever later steps mention \"show\", follow this section.\n\n## Regeneration prompt\n\n**Every time you finish showing a cover image, role image, or shot image, proactively tell the user, \"If you are not satisfied, you can spend credits to regenerate it.\"** Do not wait for the user to ask.\n\nThe prompt must include:\n\n1. What can be regenerated (cover / role / a shot with a specified index)\n2. How many credits each regeneration costs (from `mv_get_options`; see `references/credits.md`)\n3. The current credit balance (`credit` from `get_user_profile()`)\n4. That regeneration supports natural-language descriptions of the desired changes\n\nFor example:\n\n> The cover and role images are shown above. If you are not satisfied, you can regenerate them: cover 10 credits/image, role 10 credits/image.\n> Your current balance is 460 credits. If you want changes, say directly what to change, for example, \"Change the cover to a night scene with a cooler color tone.\"\n\nThen **wait for the user to state their choice explicitly before acting**. Do not initiate any charged regeneration on your own.\n\n## Step 0: Confirm service binding, login, and credit balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**. If not, it means the wrong service is connected; stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. `is_member` / `member_level_name` / `expire_time` are membership status.\nRemember the balance and compare it with the estimated cost when quoting in step 2.\n\n## Step 1: Upload materials\n\n1. Call `create_upload_url()` to obtain `upload_url` and `headers`.\n2. Upload directly with shell (the form field name is fixed as `file`), once per file:\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@/path/to/song.mp3\" -H \"X-Client-Sn: <value from headers>\"\n# → {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../song.mp3\"}\n```\n\n3. The `d` in the response is the file URL. `c != 200` means failure; relay `m` to the user.\n4. Uploaded files are **temporary storage and will be cleaned up periodically**. After obtaining the URL, submit the task as soon as possible.\n\n## Step 2: Confirm parameters and credits (GATE 1)\n\n`mv_get_options(audio_duration_sec=<audio seconds>)` returns available qualities, aspect ratios, duration range, prompt length limit,\nand credits for each stage (shot production is estimated by duration). It always comes back with\n`confirmation_gate: \"plan_and_credit\"`, so **this is GATE 1**.\n\nList for the user, item by item:\n\n1. Every parameter you intend to pass to `mv_create_story`: audio file, image files, `prompt`, `ratio`, `quality`, `mode`\n2. `step_credit.credit` — the story-creation cost of this step — plus the estimated shot-production cost (`qualities[].estimated_production_credit`)\n3. The `credit` balance from step 0; if the balance is insufficient, prompt recharge first (see\n references/credits.md for the recharge link and steps) and do not force-submit\n\nThen **end your turn** and wait for the user to confirm or change the parameters. **Do not call\n`mv_create_story` in the same turn.**\n\nAudio duration can be inferred from a local file (for example with `ffprobe`); if it cannot be obtained, omit this parameter for now and show only the unit-price rules.\n\n## Step 3: Story creation (stage one, charged)\n\n```\nmv_create_story(audio_urls=[...], image_urls=[...], prompt?, ratio?, quality?, mode?)\n→ { task_id, task_status, quality, credit_cost }\n```\n\n- `ratio` must be one of the available values from `mv_get_options` (such as `16:9` / `9:16` / `1:1`).\n- `prompt` uses the user's natural-language description of style and narrative, and may be left empty.\n\nThen poll `mv_get_story(task_id)` until the outline, cover, role, storyline, and lyrics statuses are all `success`.\nOutputs: story outline, cover image, role image, storyline shots (index/start-end time/description), and timestamped lyrics.\n\nShow them to the user (**first download `cover_url` and `role_url` according to \"Showing artifacts\", then paste the local paths**):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/$TASK_ID\"; mkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/cover.png\" \"<cover_url>\"\ncurl -sS -L -o \"$WORKDIR/role.png\" \"<role_url>\"\n```\n\nThen provide, in order: cover image, role image, story outline, storyline shots, and lyrics summary.\n\nOnce the cover, outline, lyrics, and storyline are all `success`, `mv_get_story` returns\n`confirmation_gate: \"story_assets\"` — this is **GATE 2**:\n\n1. Show the cover image, the story outline, the timestamped lyrics, and the storyline shots\n2. State `step_credit.credit`, the credit cost of the shot production you are about to start\n3. Follow \"Regeneration prompt\" (cover/role regeneration is charged; storyline/lyrics edits are free)\n4. Ask whether to edit anything or to start the charged shot production, then **end your turn**\n\n**Do not call `mv_submit_production` in the same turn in which the gate fired.** Wait for the user's\nexplicit go-ahead.\n\n## Step 4: Edits and regeneration (optional)\n\n| Request | Tool | Billing |\n| --- | --- | --- |\n| Change shot descriptions or timeline | `mv_update_storyline(task_id, storyline)` | Free |\n| Change lyrics or timestamps | `mv_update_lyrics(task_id, lyrics)` | Free |\n| Role image is unsatisfactory | `mv_regenerate_asset(task_id, \"role\", prompt?)` | Charged |\n| Cover image is unsatisfactory | `mv_regenerate_asset(task_id, \"cover\", prompt?)` | Charged |\n\n- Both update tools require a **complete list** (not a delta). Modify the full result from `mv_get_story` and write it back.\n- Edits can only be made after stage one completes and before submitting shot production.\n- Regeneration is asynchronous; after submitting it, return to polling the corresponding status with `mv_get_story`.\n- After regeneration completes, **download and show the new image again** (the URL changes). Do not fool the user with the old local file.\n\nField structures are in `references/workflow.md`.\n\n## Step 5: Shot production (stage two, charged by duration)\n\n```\nmv_submit_production(task_id, mode?) # First call, charges credits\nmv_get_production(task_id) # Poll\n```\n\nAfter polling until all `segments[].image_status == 2`, **this step only shows shot images; do not rush to provide the final video**.\n\nDownload and show shot images according to \"Showing artifacts\":\n\n```bash\ncurl -sS -L -o \"$WORKDIR/seg-00.png\" \"<segments[0].image_url>\" # Name by index and download one by one\n```\n\nWhen there are many shots, show the first few plus any the user names; do not pull all of them at once.\n\nThis is **GATE 3**. After showing the shots, state `step_credit` (accepting the shots and\nretrieving the final video is free) and follow \"Regeneration prompt\" to tell the user which shots\ncan be regenerated and how many credits each costs, then **end your turn** and wait for their\nchoice:\n\n- If the user wants regeneration → go to step 6\n- If the user is satisfied → go to step 7 to retrieve the final video\n\n**Even if `result_url` is already present in the response, do not deliver it before the user\naccepts the shots.**\n\n## Step 6: Single-shot refinement (optional, charged)\n\n```\nmv_regenerate_segment(task_id, segment_index, image_prompt?, video_prompt?, mode?) # Charged\nmv_get_production(task_id) # Poll this shot\nmv_submit_production(task_id, compose_only=true) # Free, refresh final MV\n```\n\n- `segment_index` comes from `segments[].index` in `mv_get_production`; do not count it yourself.\n- **After regenerating a shot, you must run composition once with `compose_only=true`**, otherwise step 7 will still return the old final video.\n- After regeneration completes, download and show the new shot image again (the URL changes), then ask the user whether to keep editing.\n- When the user is done editing → go to step 7.\n\n## Step 7: Retrieve final video (no credits charged)\n\n```\nmv_get_production(task_id).result_url\n```\n\nCall `mv_get_production` again and take `result_url`, which is the composed final MV. **This step does not consume any credits**.\n\n**Only reach this step after the user has cleared GATE 3.**\n\n- If `result_url` is empty: composition has not finished; continue polling at the stage-two cadence.\n If step 6 was just performed and it still does not refresh, check whether the `compose_only=true` composition was missed.\n- After obtaining `result_url`, proceed to \"Deliver\".\n\n## Deliver\n\nFirst download the final MV to the local working directory, then deliver it:\n\n```bash\ncurl -sS -L -o \"$WORKDIR/mv.mp4\" \"<result_url>\"\n```\n\nProvide the local file path + original `result_url`, and remind the user: the remote link points to temporary storage and will be cleaned up,\nand the local file is under the system temporary directory and may also be reclaimed by the system. Recommend that the user save it to their own directory as soon as possible.\n\n## Error handling\n\nFor login, connection, and service binding issues, see `references/auth.md` (**when not logged in, the entire MCP namespace will not appear**; do not misjudge it as an uninstalled plugin, and never switch to another brand's MCP).\nFor common upstream error codes and handling, see `references/errors.md`; for credit and billing rule details, see `references/credits.md`;\nfor return field structures of each tool, see `references/workflow.md`.\n""---\nname: generate-mv\ndescription: Generate a music MV from audio and images (Enkio / enkiomv.ai). Use when the user wants to make an MV, music video, add visuals to a song, turn photos into a beat-synced video, or modify the storyline, lyrics, role image, cover image, or an individual shot of an already generated MV. The entire workflow is completed through the enkio MCP service.\n---\n\n# Generate MV\n\nUse the `enkio` MCP service to call enkiomv.ai's MV Agent and turn one audio track plus several images into an MV.\n\n## Service binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**. Codex normalizes `-` in server names to `_`,\n and tool names do not carry a prefix. Every tool name below (such as `get_user_profile`) refers to the tool of the same name in the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n authorization URL it prints, and give the user only that link to click -- do not lead with the\n `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are two services,\n two accounts, and two credit pools; cross-use will charge real credits to the wrong account). Also do not mix in\n a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, rely on the `brand` / `brand_website`\n returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`.\n Do not answer from memory or guesswork; if `brand` is not Enkio, stop immediately and report an error.\n\nThe workflow has two stages and is **entirely asynchronous**: submission tools return immediately, so you must poll query tools yourself.\n\n```\n0 Log in / check balance → 1 Upload materials → [GATE 1] 2 Choose model, confirm parameters and credits\n→ 3 Story creation (charged) → [GATE 2] cover + outline + lyrics + storyline\n→ 4 Edit storyline/lyrics (free), regenerate cover/role (charged)\n→ 5 Shot production (charged) + show shots → [GATE 3] segment images\n→ 6 Regenerate a single shot (optional, charged)\n→ 7 Retrieve final video (free) → Deliver\n```\n\n**Step 5 only shows shot images and does not deliver the final video**; retrieve the final video uniformly in step 7 with `mv_get_production`, which does not charge any credits.\n\n## Mandatory confirmation gates (read this before anything else)\n\nMV generation has **three mandatory user confirmation gates**. They are not suggestions and they\ncannot be merged, skipped, or pre-approved. **Clearing one gate never authorizes the next one.**\n**Every gate must be presented together with the credit cost of that step** (`step_credit` in the\ntool response).\n\n| Gate | Fires when | You must show | You must ask | Forbidden until the user answers |\n| --- | --- | --- | --- | --- |\n| 1 | `mv_get_options` returns `confirmation_gate: \"plan_and_credit\"` | every generation parameter (model, audio, images, prompt, aspect ratio, quality) + story-creation credit cost | confirm these parameters, or change them? | `mv_create_story` |\n| 2 | `mv_get_story` returns `confirmation_gate: \"story_assets\"` | cover image + story outline + lyrics + storyline shots, and the shot-production credit cost | edit anything, or start the charged shot production? | `mv_submit_production` |\n| 3 | `mv_get_production` returns `confirmation_gate: \"segments\"` | every shot image + the credit cost of this step | regenerate any shot, or accept them? | delivering `result_url` |\n\nThe MCP service reports each gate in its response:\n\n```\nrequires_user_confirmation: true\nconfirmation_gate: \"plan_and_credit\" | \"story_assets\" | \"segments\"\nblocked_until_user_confirms: [\"mv_submit_production\"]\nuser_confirmation_prompt: \"GATE 2 of 3 - STOP AND ASK THE USER. ...\"\nstep_credit: { step: \"storyboard_production\", credit: 150, charged_by: \"audio duration\", ... }\n```\n\n**Whenever `requires_user_confirmation` is `true`: present the artifacts, state the `step_credit`\namount, ask the question, and END YOUR TURN.** Do not call another tool in the same turn, do not\nkeep polling, and do not assume \"the user already said make an MV\" counts as an answer. Only a new\nuser message in this conversation clears a gate.\n\nIf you ever find yourself about to call `mv_create_story` or `mv_submit_production`, or to hand\nover `result_url`, without a user message in between, you have violated this section - stop and ask\ninstead.\n\n## Hard constraints\n\n- **The three confirmation gates above are absolute.** Never chain parameter confirmation → story creation → shot production → final video in one unattended run.\n- **Every gate must state the credit cost of that step** (`step_credit` from the tool response), not just the artifacts.\n- **Operations that charge credits must first explain the cost to the user and obtain confirmation**: story creation, role/cover regeneration, shot production, and single-shot regeneration.\n Free operations: editing the storyline, editing lyrics, compose-only (`compose_only=true`), and query tools (including retrieving the final video in step 7).\n- **After every display of a cover, role, or shot image, proactively tell the user they can spend credits to regenerate it**; see \"Regeneration prompt\".\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already handles them, and they do not exist in tool inputs.\n- Remember the `task_id` after every submission; every later call must include it.\n- Polling cadence: stage one once every 10 seconds, with an upper limit of about 5 minutes; stage two once every 20 seconds, with an upper limit of about 20 minutes.\n During polling, give the user brief progress updates; do not wait silently for a long time.\n- When any status is `fail`, do not blindly retry the whole order. First tell the user which\n item failed and the error message, then ask whether to regenerate that item or abandon it.\n Regenerating re-bills that step at the normal price--failed credits are refunded\n automatically, and this billing rule was already disclosed when quoting each step's cost, so\n no new price confirmation is needed here.\n- **Before showing images/videos, you must download them locally first**. Directly pasting a remote URL cannot be embedded for preview; see the next section.\n\n## Showing artifacts (important)\n\nThe cover image, role image, shot images, and final MV returned by MV Agent are all Enkio **temporary remote URLs**.\nCodex **cannot embed previews for images on these domains**; directly pasting a URL will only display a gray placeholder box.\n\nTherefore: **For every image or video that should be shown to the user, first download it locally with `curl`, then show it using the local path.**\n\nUse a task-isolated working directory by convention (to avoid polluting the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/<task_id>\"\nmkdir -p \"$WORKDIR\"\n\n# Use a meaningful <name>: cover / role / seg-00 / mv\n# Infer the extension from the URL path; if unavailable, use .png (use .mp4 for video)\ncurl -sS -L -o \"$WORKDIR/<name>.<ext>\" \"<remote URL>\"\n```\n\nAfter downloading:\n\n- Show images using the local absolute path so the user can see them directly in the conversation\n- Also include the original remote URL so the user can save it themselves\n- If download fails (non-200 / empty file), clearly state \"preview download failed\" and provide the remote URL so the user can open it themselves;\n do not falsely claim that the image has been shown\n- The working directory is under the system temporary directory; you do not need to clean it up proactively, and do not write it into the user's repository\n\nWhenever later steps mention \"show\", follow this section.\n\n## Regeneration prompt\n\n**Every time you finish showing a cover image, role image, or shot image, proactively tell the user, \"If you are not satisfied, you can spend credits to regenerate it.\"** Do not wait for the user to ask.\n\nThe prompt must include:\n\n1. What can be regenerated (cover / role / a shot with a specified index)\n2. How many credits each regeneration costs (from `mv_get_options`; see `references/credits.md`)\n3. The current credit balance (`credit` from `get_user_profile()`)\n4. That regeneration supports natural-language descriptions of the desired changes\n\nFor example:\n\n> The cover and role images are shown above. If you are not satisfied, you can regenerate them: cover 10 credits/image, role 10 credits/image.\n> Your current balance is 460 credits. If you want changes, say directly what to change, for example, \"Change the cover to a night scene with a cooler color tone.\"\n\nThen **wait for the user to state their choice explicitly before acting**. Do not initiate any charged regeneration on your own.\n\n## Step 0: Confirm service binding, login, and credit balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**. If not, it means the wrong service is connected; stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. `is_member` / `member_level_name` / `expire_time` are membership status.\nRemember the balance and compare it with the estimated cost when quoting in step 2.\n\n**Membership check (required).** Creating tasks with `mv_create_story` requires an active membership. If\n`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url`\nand give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare\naccount used to authorize this MCP, to purchase a membership. Do not continue with model selection,\nuploads, quoting, or task creation; after the user says the purchase is complete, call\n`get_user_profile()` again and continue only when `is_member` is `true`.\n\n## Step 1: Upload materials\n\n1. Call `create_upload_url()` to obtain `upload_url` and `headers`.\n2. Upload directly with shell (the form field name is fixed as `file`), once per file:\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@/path/to/song.mp3\" -H \"X-Client-Sn: <value from headers>\"\n# → {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../song.mp3\"}\n```\n\n3. The `d` in the response is the file URL. `c != 200` means failure; relay `m` to the user.\n4. Uploaded files are **temporary storage and will be cleaned up periodically**. After obtaining the URL, submit the task as soon as possible.\n\n## Step 2: Choose model, confirm parameters and credits (GATE 1)\n\nCall `mv_list_models()` to list the available MV models (`models[].model`, `model_name`, qualities, aspect ratios,\nand per-stage credits). If there is more than one, briefly list them for the user and let them choose; otherwise\nuse the only one. `default_model` is used whenever `model` is omitted. The model is fixed once the task is\ncreated, so it cannot be switched for regeneration or shot production later.\n\n`mv_get_options(model=<chosen model>, audio_duration_sec=<audio seconds>)` returns available qualities, aspect ratios, duration range, prompt length limit,\nand credits for each stage (shot production is estimated by duration). It always comes back with\n`confirmation_gate: \"plan_and_credit\"`, so **this is GATE 1**.\n\nList for the user, item by item:\n\n1. Every parameter you intend to pass to `mv_create_story`: `model`, audio file, image files, `prompt`, `ratio`, `quality`\n2. `step_credit.credit` — the story-creation cost of this step — plus the estimated shot-production cost (`qualities[].estimated_production_credit`)\n3. The `credit` balance from step 0; if the balance is insufficient, prompt recharge first (see\n references/credits.md for the recharge link and steps) and do not force-submit\n\nThen **end your turn** and wait for the user to confirm or change the parameters. **Do not call\n`mv_create_story` in the same turn.**\n\nAudio duration can be inferred from a local file (for example with `ffprobe`); if it cannot be obtained, omit this parameter for now and show only the unit-price rules.\n\n## Step 3: Story creation (stage one, charged)\n\n```\nmv_create_story(audio_urls=[...], image_urls=[...], prompt?, ratio?, quality?, model?)\n→ { task_id, task_status, model, model_name, quality, credit_cost }\n```\n\n- `model` must be the same `models[].model` you passed to `mv_get_options`; `ratio` and `quality` must come from that model's options.\n- `ratio` must be one of the available values from `mv_get_options` (such as `16:9` / `9:16` / `1:1`).\n- `prompt` uses the user's natural-language description of style and narrative, and may be left empty.\n\nThen poll `mv_get_story(task_id)` until the outline, cover, role, storyline, and lyrics statuses are all `success`.\nOutputs: story outline, cover image, role image, storyline shots (index/start-end time/description), and timestamped lyrics.\n\nShow them to the user (**first download `cover_url` and `role_url` according to \"Showing artifacts\", then paste the local paths**):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/$TASK_ID\"; mkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/cover.png\" \"<cover_url>\"\ncurl -sS -L -o \"$WORKDIR/role.png\" \"<role_url>\"\n```\n\nThen provide, in order: cover image, role image, story outline, storyline shots, and lyrics summary.\n\nOnce the cover, outline, lyrics, and storyline are all `success`, `mv_get_story` returns\n`confirmation_gate: \"story_assets\"` — this is **GATE 2**:\n\n1. Show the cover image, the story outline, the timestamped lyrics, and the storyline shots\n2. State `step_credit.credit`, the credit cost of the shot production you are about to start\n3. Follow \"Regeneration prompt\" (cover/role regeneration is charged; storyline/lyrics edits are free)\n4. Ask whether to edit anything or to start the charged shot production, then **end your turn**\n\n**Do not call `mv_submit_production` in the same turn in which the gate fired.** Wait for the user's\nexplicit go-ahead.\n\n## Step 4: Edits and regeneration (optional)\n\n| Request | Tool | Billing |\n| --- | --- | --- |\n| Change shot descriptions or timeline | `mv_update_storyline(task_id, storyline)` | Free |\n| Change lyrics or timestamps | `mv_update_lyrics(task_id, lyrics)` | Free |\n| Role image is unsatisfactory | `mv_regenerate_asset(task_id, \"role\", prompt?)` | Charged |\n| Cover image is unsatisfactory | `mv_regenerate_asset(task_id, \"cover\", prompt?)` | Charged |\n\n- Both update tools require a **complete list** (not a delta). Modify the full result from `mv_get_story` and write it back.\n- Edits can only be made after stage one completes and before submitting shot production.\n- Regeneration is asynchronous; after submitting it, return to polling the corresponding status with `mv_get_story`.\n- After regeneration completes, **download and show the new image again** (the URL changes). Do not fool the user with the old local file.\n\nField structures are in `references/workflow.md`.\n\n## Step 5: Shot production (stage two, charged by duration)\n\n```\nmv_submit_production(task_id) # First call, charges credits\nmv_get_production(task_id) # Poll\n```\n\nAfter polling until all `segments[].image_status == 2`, **this step only shows shot images; do not rush to provide the final video**.\n\nDownload and show shot images according to \"Showing artifacts\":\n\n```bash\ncurl -sS -L -o \"$WORKDIR/seg-00.png\" \"<segments[0].image_url>\" # Name by index and download one by one\n```\n\nWhen there are many shots, show the first few plus any the user names; do not pull all of them at once.\n\nThis is **GATE 3**. After showing the shots, state `step_credit` (accepting the shots and\nretrieving the final video is free) and follow \"Regeneration prompt\" to tell the user which shots\ncan be regenerated and how many credits each costs, then **end your turn** and wait for their\nchoice:\n\n- If the user wants regeneration → go to step 6\n- If the user is satisfied → go to step 7 to retrieve the final video\n\n**Even if `result_url` is already present in the response, do not deliver it before the user\naccepts the shots.**\n\n## Step 6: Single-shot refinement (optional, charged)\n\n```\nmv_regenerate_segment(task_id, segment_index, image_prompt?, video_prompt?) # Charged\nmv_get_production(task_id) # Poll this shot\nmv_submit_production(task_id, compose_only=true) # Free, refresh final MV\n```\n\n- `segment_index` comes from `segments[].index` in `mv_get_production`; do not count it yourself.\n- **After regenerating a shot, you must run composition once with `compose_only=true`**, otherwise step 7 will still return the old final video.\n- After regeneration completes, download and show the new shot image again (the URL changes), then ask the user whether to keep editing.\n- When the user is done editing → go to step 7.\n\n## Step 7: Retrieve final video (no credits charged)\n\n```\nmv_get_production(task_id).result_url\n```\n\nCall `mv_get_production` again and take `result_url`, which is the composed final MV. **This step does not consume any credits**.\n\n**Only reach this step after the user has cleared GATE 3.**\n\n- If `result_url` is empty: composition has not finished; continue polling at the stage-two cadence.\n If step 6 was just performed and it still does not refresh, check whether the `compose_only=true` composition was missed.\n- After obtaining `result_url`, proceed to \"Deliver\".\n\n## Deliver\n\nFirst download the final MV to the local working directory, then deliver it:\n\n```bash\ncurl -sS -L -o \"$WORKDIR/mv.mp4\" \"<result_url>\"\n```\n\nProvide the local file path + original `result_url`, and remind the user: the remote link points to temporary storage and will be cleaned up,\nand the local file is under the system temporary directory and may also be reclaimed by the system. Recommend that the user save it to their own directory as soon as possible.\n\n## Error handling\n\nFor login, connection, and service binding issues, see `references/auth.md` (**when not logged in, the entire MCP namespace will not appear**; do not misjudge it as an uninstalled plugin, and never switch to another brand's MCP).\nFor common upstream error codes and handling, see `references/errors.md`; for credit and billing rule details, see `references/credits.md`;\nfor return field structures of each tool, see `references/workflow.md`.\n"Full snapshot data
{
"description": "Generate a music MV from audio and images (Enkio / enkiomv.ai). Use when the user wants to make an MV, music video, add visuals to a song, turn photos into a beat-synced video, or modify the storyline, lyrics, role image, cover image, or an individual shot of an already generated MV. The entire workflow is completed through the enkio MCP service.",
"included_files": [
{
"relative_path": "references/auth.md",
"size_in_bytes": 4896
},
{
"relative_path": "references/credits.md",
"size_in_bytes": 3605
},
{
"relative_path": "references/errors.md",
"size_in_bytes": 5460
},
{
"relative_path": "references/workflow.md",
"size_in_bytes": 9004
}
],
"name": "generate-mv",
"skill_md_contents": "---\nname: generate-mv\ndescription: Generate a music MV from audio and images (Enkio / enkiomv.ai). Use when the user wants to make an MV, music video, add visuals to a song, turn photos into a beat-synced video, or modify the storyline, lyrics, role image, cover image, or an individual shot of an already generated MV. The entire workflow is completed through the enkio MCP service.\n---\n\n# Generate MV\n\nUse the `enkio` MCP service to call enkiomv.ai's MV Agent and turn one audio track plus several images into an MV.\n\n## Service binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**. Codex normalizes `-` in server names to `_`,\n and tool names do not carry a prefix. Every tool name below (such as `get_user_profile`) refers to the tool of the same name in the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n authorization URL it prints, and give the user only that link to click -- do not lead with the\n `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are two services,\n two accounts, and two credit pools; cross-use will charge real credits to the wrong account). Also do not mix in\n a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, rely on the `brand` / `brand_website`\n returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`.\n Do not answer from memory or guesswork; if `brand` is not Enkio, stop immediately and report an error.\n\nThe workflow has two stages and is **entirely asynchronous**: submission tools return immediately, so you must poll query tools yourself.\n\n```\n0 Log in / check balance → 1 Upload materials → [GATE 1] 2 Choose model, confirm parameters and credits\n→ 3 Story creation (charged) → [GATE 2] cover + outline + lyrics + storyline\n→ 4 Edit storyline/lyrics (free), regenerate cover/role (charged)\n→ 5 Shot production (charged) + show shots → [GATE 3] segment images\n→ 6 Regenerate a single shot (optional, charged)\n→ 7 Retrieve final video (free) → Deliver\n```\n\n**Step 5 only shows shot images and does not deliver the final video**; retrieve the final video uniformly in step 7 with `mv_get_production`, which does not charge any credits.\n\n## Mandatory confirmation gates (read this before anything else)\n\nMV generation has **three mandatory user confirmation gates**. They are not suggestions and they\ncannot be merged, skipped, or pre-approved. **Clearing one gate never authorizes the next one.**\n**Every gate must be presented together with the credit cost of that step** (`step_credit` in the\ntool response).\n\n| Gate | Fires when | You must show | You must ask | Forbidden until the user answers |\n| --- | --- | --- | --- | --- |\n| 1 | `mv_get_options` returns `confirmation_gate: \"plan_and_credit\"` | every generation parameter (model, audio, images, prompt, aspect ratio, quality) + story-creation credit cost | confirm these parameters, or change them? | `mv_create_story` |\n| 2 | `mv_get_story` returns `confirmation_gate: \"story_assets\"` | cover image + story outline + lyrics + storyline shots, and the shot-production credit cost | edit anything, or start the charged shot production? | `mv_submit_production` |\n| 3 | `mv_get_production` returns `confirmation_gate: \"segments\"` | every shot image + the credit cost of this step | regenerate any shot, or accept them? | delivering `result_url` |\n\nThe MCP service reports each gate in its response:\n\n```\nrequires_user_confirmation: true\nconfirmation_gate: \"plan_and_credit\" | \"story_assets\" | \"segments\"\nblocked_until_user_confirms: [\"mv_submit_production\"]\nuser_confirmation_prompt: \"GATE 2 of 3 - STOP AND ASK THE USER. ...\"\nstep_credit: { step: \"storyboard_production\", credit: 150, charged_by: \"audio duration\", ... }\n```\n\n**Whenever `requires_user_confirmation` is `true`: present the artifacts, state the `step_credit`\namount, ask the question, and END YOUR TURN.** Do not call another tool in the same turn, do not\nkeep polling, and do not assume \"the user already said make an MV\" counts as an answer. Only a new\nuser message in this conversation clears a gate.\n\nIf you ever find yourself about to call `mv_create_story` or `mv_submit_production`, or to hand\nover `result_url`, without a user message in between, you have violated this section - stop and ask\ninstead.\n\n## Hard constraints\n\n- **The three confirmation gates above are absolute.** Never chain parameter confirmation → story creation → shot production → final video in one unattended run.\n- **Every gate must state the credit cost of that step** (`step_credit` from the tool response), not just the artifacts.\n- **Operations that charge credits must first explain the cost to the user and obtain confirmation**: story creation, role/cover regeneration, shot production, and single-shot regeneration.\n Free operations: editing the storyline, editing lyrics, compose-only (`compose_only=true`), and query tools (including retrieving the final video in step 7).\n- **After every display of a cover, role, or shot image, proactively tell the user they can spend credits to regenerate it**; see \"Regeneration prompt\".\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already handles them, and they do not exist in tool inputs.\n- Remember the `task_id` after every submission; every later call must include it.\n- Polling cadence: stage one once every 10 seconds, with an upper limit of about 5 minutes; stage two once every 20 seconds, with an upper limit of about 20 minutes.\n During polling, give the user brief progress updates; do not wait silently for a long time.\n- When any status is `fail`, do not blindly retry the whole order. First tell the user which\n item failed and the error message, then ask whether to regenerate that item or abandon it.\n Regenerating re-bills that step at the normal price--failed credits are refunded\n automatically, and this billing rule was already disclosed when quoting each step's cost, so\n no new price confirmation is needed here.\n- **Before showing images/videos, you must download them locally first**. Directly pasting a remote URL cannot be embedded for preview; see the next section.\n\n## Showing artifacts (important)\n\nThe cover image, role image, shot images, and final MV returned by MV Agent are all Enkio **temporary remote URLs**.\nCodex **cannot embed previews for images on these domains**; directly pasting a URL will only display a gray placeholder box.\n\nTherefore: **For every image or video that should be shown to the user, first download it locally with `curl`, then show it using the local path.**\n\nUse a task-isolated working directory by convention (to avoid polluting the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/<task_id>\"\nmkdir -p \"$WORKDIR\"\n\n# Use a meaningful <name>: cover / role / seg-00 / mv\n# Infer the extension from the URL path; if unavailable, use .png (use .mp4 for video)\ncurl -sS -L -o \"$WORKDIR/<name>.<ext>\" \"<remote URL>\"\n```\n\nAfter downloading:\n\n- Show images using the local absolute path so the user can see them directly in the conversation\n- Also include the original remote URL so the user can save it themselves\n- If download fails (non-200 / empty file), clearly state \"preview download failed\" and provide the remote URL so the user can open it themselves;\n do not falsely claim that the image has been shown\n- The working directory is under the system temporary directory; you do not need to clean it up proactively, and do not write it into the user's repository\n\nWhenever later steps mention \"show\", follow this section.\n\n## Regeneration prompt\n\n**Every time you finish showing a cover image, role image, or shot image, proactively tell the user, \"If you are not satisfied, you can spend credits to regenerate it.\"** Do not wait for the user to ask.\n\nThe prompt must include:\n\n1. What can be regenerated (cover / role / a shot with a specified index)\n2. How many credits each regeneration costs (from `mv_get_options`; see `references/credits.md`)\n3. The current credit balance (`credit` from `get_user_profile()`)\n4. That regeneration supports natural-language descriptions of the desired changes\n\nFor example:\n\n> The cover and role images are shown above. If you are not satisfied, you can regenerate them: cover 10 credits/image, role 10 credits/image.\n> Your current balance is 460 credits. If you want changes, say directly what to change, for example, \"Change the cover to a night scene with a cooler color tone.\"\n\nThen **wait for the user to state their choice explicitly before acting**. Do not initiate any charged regeneration on your own.\n\n## Step 0: Confirm service binding, login, and credit balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**. If not, it means the wrong service is connected; stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. `is_member` / `member_level_name` / `expire_time` are membership status.\nRemember the balance and compare it with the estimated cost when quoting in step 2.\n\n**Membership check (required).** Creating tasks with `mv_create_story` requires an active membership. If\n`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url`\nand give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare\naccount used to authorize this MCP, to purchase a membership. Do not continue with model selection,\nuploads, quoting, or task creation; after the user says the purchase is complete, call\n`get_user_profile()` again and continue only when `is_member` is `true`.\n\n## Step 1: Upload materials\n\n1. Call `create_upload_url()` to obtain `upload_url` and `headers`.\n2. Upload directly with shell (the form field name is fixed as `file`), once per file:\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@/path/to/song.mp3\" -H \"X-Client-Sn: <value from headers>\"\n# → {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../song.mp3\"}\n```\n\n3. The `d` in the response is the file URL. `c != 200` means failure; relay `m` to the user.\n4. Uploaded files are **temporary storage and will be cleaned up periodically**. After obtaining the URL, submit the task as soon as possible.\n\n## Step 2: Choose model, confirm parameters and credits (GATE 1)\n\nCall `mv_list_models()` to list the available MV models (`models[].model`, `model_name`, qualities, aspect ratios,\nand per-stage credits). If there is more than one, briefly list them for the user and let them choose; otherwise\nuse the only one. `default_model` is used whenever `model` is omitted. The model is fixed once the task is\ncreated, so it cannot be switched for regeneration or shot production later.\n\n`mv_get_options(model=<chosen model>, audio_duration_sec=<audio seconds>)` returns available qualities, aspect ratios, duration range, prompt length limit,\nand credits for each stage (shot production is estimated by duration). It always comes back with\n`confirmation_gate: \"plan_and_credit\"`, so **this is GATE 1**.\n\nList for the user, item by item:\n\n1. Every parameter you intend to pass to `mv_create_story`: `model`, audio file, image files, `prompt`, `ratio`, `quality`\n2. `step_credit.credit` — the story-creation cost of this step — plus the estimated shot-production cost (`qualities[].estimated_production_credit`)\n3. The `credit` balance from step 0; if the balance is insufficient, prompt recharge first (see\n references/credits.md for the recharge link and steps) and do not force-submit\n\nThen **end your turn** and wait for the user to confirm or change the parameters. **Do not call\n`mv_create_story` in the same turn.**\n\nAudio duration can be inferred from a local file (for example with `ffprobe`); if it cannot be obtained, omit this parameter for now and show only the unit-price rules.\n\n## Step 3: Story creation (stage one, charged)\n\n```\nmv_create_story(audio_urls=[...], image_urls=[...], prompt?, ratio?, quality?, model?)\n→ { task_id, task_status, model, model_name, quality, credit_cost }\n```\n\n- `model` must be the same `models[].model` you passed to `mv_get_options`; `ratio` and `quality` must come from that model's options.\n- `ratio` must be one of the available values from `mv_get_options` (such as `16:9` / `9:16` / `1:1`).\n- `prompt` uses the user's natural-language description of style and narrative, and may be left empty.\n\nThen poll `mv_get_story(task_id)` until the outline, cover, role, storyline, and lyrics statuses are all `success`.\nOutputs: story outline, cover image, role image, storyline shots (index/start-end time/description), and timestamped lyrics.\n\nShow them to the user (**first download `cover_url` and `role_url` according to \"Showing artifacts\", then paste the local paths**):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-mv/$TASK_ID\"; mkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/cover.png\" \"<cover_url>\"\ncurl -sS -L -o \"$WORKDIR/role.png\" \"<role_url>\"\n```\n\nThen provide, in order: cover image, role image, story outline, storyline shots, and lyrics summary.\n\nOnce the cover, outline, lyrics, and storyline are all `success`, `mv_get_story` returns\n`confirmation_gate: \"story_assets\"` — this is **GATE 2**:\n\n1. Show the cover image, the story outline, the timestamped lyrics, and the storyline shots\n2. State `step_credit.credit`, the credit cost of the shot production you are about to start\n3. Follow \"Regeneration prompt\" (cover/role regeneration is charged; storyline/lyrics edits are free)\n4. Ask whether to edit anything or to start the charged shot production, then **end your turn**\n\n**Do not call `mv_submit_production` in the same turn in which the gate fired.** Wait for the user's\nexplicit go-ahead.\n\n## Step 4: Edits and regeneration (optional)\n\n| Request | Tool | Billing |\n| --- | --- | --- |\n| Change shot descriptions or timeline | `mv_update_storyline(task_id, storyline)` | Free |\n| Change lyrics or timestamps | `mv_update_lyrics(task_id, lyrics)` | Free |\n| Role image is unsatisfactory | `mv_regenerate_asset(task_id, \"role\", prompt?)` | Charged |\n| Cover image is unsatisfactory | `mv_regenerate_asset(task_id, \"cover\", prompt?)` | Charged |\n\n- Both update tools require a **complete list** (not a delta). Modify the full result from `mv_get_story` and write it back.\n- Edits can only be made after stage one completes and before submitting shot production.\n- Regeneration is asynchronous; after submitting it, return to polling the corresponding status with `mv_get_story`.\n- After regeneration completes, **download and show the new image again** (the URL changes). Do not fool the user with the old local file.\n\nField structures are in `references/workflow.md`.\n\n## Step 5: Shot production (stage two, charged by duration)\n\n```\nmv_submit_production(task_id) # First call, charges credits\nmv_get_production(task_id) # Poll\n```\n\nAfter polling until all `segments[].image_status == 2`, **this step only shows shot images; do not rush to provide the final video**.\n\nDownload and show shot images according to \"Showing artifacts\":\n\n```bash\ncurl -sS -L -o \"$WORKDIR/seg-00.png\" \"<segments[0].image_url>\" # Name by index and download one by one\n```\n\nWhen there are many shots, show the first few plus any the user names; do not pull all of them at once.\n\nThis is **GATE 3**. After showing the shots, state `step_credit` (accepting the shots and\nretrieving the final video is free) and follow \"Regeneration prompt\" to tell the user which shots\ncan be regenerated and how many credits each costs, then **end your turn** and wait for their\nchoice:\n\n- If the user wants regeneration → go to step 6\n- If the user is satisfied → go to step 7 to retrieve the final video\n\n**Even if `result_url` is already present in the response, do not deliver it before the user\naccepts the shots.**\n\n## Step 6: Single-shot refinement (optional, charged)\n\n```\nmv_regenerate_segment(task_id, segment_index, image_prompt?, video_prompt?) # Charged\nmv_get_production(task_id) # Poll this shot\nmv_submit_production(task_id, compose_only=true) # Free, refresh final MV\n```\n\n- `segment_index` comes from `segments[].index` in `mv_get_production`; do not count it yourself.\n- **After regenerating a shot, you must run composition once with `compose_only=true`**, otherwise step 7 will still return the old final video.\n- After regeneration completes, download and show the new shot image again (the URL changes), then ask the user whether to keep editing.\n- When the user is done editing → go to step 7.\n\n## Step 7: Retrieve final video (no credits charged)\n\n```\nmv_get_production(task_id).result_url\n```\n\nCall `mv_get_production` again and take `result_url`, which is the composed final MV. **This step does not consume any credits**.\n\n**Only reach this step after the user has cleared GATE 3.**\n\n- If `result_url` is empty: composition has not finished; continue polling at the stage-two cadence.\n If step 6 was just performed and it still does not refresh, check whether the `compose_only=true` composition was missed.\n- After obtaining `result_url`, proceed to \"Deliver\".\n\n## Deliver\n\nFirst download the final MV to the local working directory, then deliver it:\n\n```bash\ncurl -sS -L -o \"$WORKDIR/mv.mp4\" \"<result_url>\"\n```\n\nProvide the local file path + original `result_url`, and remind the user: the remote link points to temporary storage and will be cleaned up,\nand the local file is under the system temporary directory and may also be reclaimed by the system. Recommend that the user save it to their own directory as soon as possible.\n\n## Error handling\n\nFor login, connection, and service binding issues, see `references/auth.md` (**when not logged in, the entire MCP namespace will not appear**; do not misjudge it as an uninstalled plugin, and never switch to another brand's MCP).\nFor common upstream error codes and handling, see `references/errors.md`; for credit and billing rule details, see `references/credits.md`;\nfor return field structures of each tool, see `references/workflow.md`.\n"
}SHA-256 of public snapshot: 8ccb15e22b4cb9f7b99137a8c58f2f45be3dc2cf1368c73adea9ec550e1bf0f1