← Plugin catalog
Productivity

Enkio

Enkio v1.0.1

Create AI images and videos

Full description ↓

Save this plugin to Following and return to review observed changes. Follow up to 10 plugins free.

Description

From the marketplace listing

Enkio connects to enkiomv.ai's AI visual creation tools: upload audio and images to generate a story, cover, character designs, storyboard, and final music video; animate a single image; create smooth first-to-last-frame transitions; combine multiple reference images into a new video; generate a video from a text prompt without source media; and create or edit images by changing style, background, or details with a prompt.

Language: English · Automatically detected from descriptions.

What changed

Enkio

Oct 28, 2026 · 1 saved observations

Metadata · Oct 28, 2026 · 12:50 UTC · Compared with Oct 26, 2026 · 06:08 UTC

WHAT CHANGED

Package or technical metadata updated

Package or technical metadata updated

Observed in package metadata. These changes alone do not establish a new customer-facing feature.

Open full comparison.

Is v2 template

Before

Oct 26, 2026 · 06:08 UTC

Not present

After

Oct 28, 2026 · 12:50 UTC

false

Metadata: full comparison →
Earlier changes · 1 more observation days on this page
Enkio

Oct 26, 2026 · 9 saved observations

Capabilities & instructions

Added instruction text: “**Membership check (required).** Creating tasks with `t2v_create_task` requires an active membership. If”. 5 additional added or edited lines are in the evidence.

Skill evidence →
Capabilities & instructions

Added instruction text: “**Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If”. 5 additional added or edited lines are in the evidence.

Skill evidence →Skill evidence →Skill evidence →
Capabilities & instructions

Instruction wording changed from “Confirm ” to “Choose model, confirm ”. 19 additional added or edited lines are in the evidence.

Skill evidence →
4 more changes that day

Instruction wording changed from “are two different upstream pipelines, ” to “use separate tool groups, ”. 8 additional added or edited lines are in the evidence.

Skill evidence →

Declared skills changed from “[{"description":"Generate transition videos from a fixed first-frame image and end-frame image (Enkio / enkiomv.ai). Use when the user wants a first/end-frame video, specifies a starting image and an ending image, asks to turn one image ...” to “[{"description":"Generate transition videos from a fixed first-frame image and end-frame image (Enkio / enkiomv.ai). Use when the user wants a first/end-frame video, specifies a starting image and an ending image, asks to turn one image ...”.

Metadata evidence →

Full description changed from “Enkio helps users create music videos, animate images, make fixed first-to-last-frame and reference-image videos, generate videos from text, and create or edit images with prompts through their signed-in account.” to “Enkio: an AI visual creation suite. It connects to enkiomv.ai through the remote gx-mcp MCP service to create music videos from audio and images, animate a single image, create first-to-last-frame transitions, generate videos from multip...”.

Listing evidence →

Package contents changed in 26 files: .app.json, .codex-plugin/plugin.json, assets/composer-icon.png, …. Open the file diff to inspect the edits.

Files evidence →

Competitor profile

From the developer’s listing and package; capabilities are not independently tested. Package observed Nov 3, 2026.

Declared capabilities

  • Interactive
  • Read
  • Write

Declared limitations

Specific limitations have not been established. Missing information does not mean unrestricted capabilities.

Cost & access

Pricing and account requirements have not been established from the available package declarations. Unknown pricing does not mean free access.

Starter prompt

Create a music video from this song and these photos

View package source →

Keywords

Matches for “story to video”

Exact text from the indicated source. A mention alone does not establish support for your task.

Publisher keywords · listing

enkio enkiomv mv music-video aigc video storyboard image-to-video first-end-frame reference-to-video text-to-video text-to-image image-to-image image-generation wondershare

Publisher full description

Enkio connects to enkiomv.ai's AI visual creation tools: upload audio and images to generate a story, cover, character designs, storyboard, and final music video; animate a single image; create smooth first-to-last-frame transitions; combine multiple reference images into a new video; generate a video from a text prompt without source media; and create or edit images by changing style, background, or details with a prompt.

Publisher description

Enkio: an AI visual creation suite. It connects to enkiomv.ai through the remote gx-mcp MCP service to create music videos from audio and images, animate a single image, create first-to-last-frame transitions, generate videos from multiple reference images, generate videos from text prompts, and create or edit images with text prompts (text-to-image / image-to-image).

Publisher subtitle

Create AI images and videos

Files & skills

File archives

Plugin package35 files · 382 KBBrowse files →
Skill instructions
first-end-frame-video12.9 KB

View saved version →

---
name: first-end-frame-video
description: Generate transition videos from a fixed first-frame image and end-frame image (Enkio / enkiomv.ai). Use when the user wants a first/end-frame video, specifies a starting image and an ending image, asks to turn one image into another, or wants a transition, transformation, or outfit-change effect between two images. If there is only one image and no need to specify an ending image, use the enkio:image-to-video skill instead; if the user wants to combine multiple reference images into a new scene, use the enkio:reference-to-video skill instead. The whole flow is completed through the enkio MCP service.
---

# Fixed First/End-Frame Video Generation

Call enkiomv.ai's image-to-video capability through the `enkio` MCP service to generate a video that
smoothly transitions from a **first-frame image + end-frame image**. The first frame of the finished
video is exactly the first-frame image you provide, and the last frame is exactly the end-frame image you provide.

## Service Binding

All capabilities in this skill come from the single `enkio` MCP server and **must not be replaced**:

- Its tool namespace in Codex is **`mcp__enkio`**. Codex normalizes `-` in server names to `_`, and the
  tool names themselves have no prefix. Every tool name mentioned below (such as `get_user_profile`) refers to
  the tool of the same name under the `mcp__enkio` namespace.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Under no circumstances may you substitute another brand's MCP** (`mcp__selfyz_ai` and `mcp__enkio` are two
  different services, two accounts, and two credit pools; cross-use will really charge the wrong account), and do
  not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.
- When you need to explain which service this skill is connected to, use the `brand` / `brand_website` returned by
  `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`. Do not answer from
  memory or guesswork; if `brand` is not Enkio, stop immediately and report an error.

Tasks are **asynchronous**: `i2v_create_task` returns `task_id` immediately, and you must poll
`i2v_get_task` yourself.

```
0 Log in/check balance -> 1 Choose a model that supports first/end frames -> 2 Set parameters and quote (confirm before charging)
-> 3 Crop both images to the same ratio -> 4 Upload each image to get URLs -> 5 Create the task (charges credits)
-> 6 Poll -> 7 Download, preview, and deliver
```

## Hard Constraints (Specific to This Skill)

- **You must choose a model whose `supports_fixed_end_frame` is true**, retrieved with
  `i2v_list_models(end_frame=true)`. Ordinary image-to-video models will be rejected directly by the server if you pass two images.
- **You must provide two images**: the `image_urls` order is fixed as `[first-frame URL, end-frame URL]`,
  **If the order is wrong, the finished video will be reversed**. Before submission, confirm with the user which image
  is the starting image and which is the ending image.
- **Both images must be cropped to the same ratio**, and you **must not use the `free` ratio**. Inconsistent
  first/end-frame sizes can cause a jump in the transition.
- **The prompt should describe the process of changing from the first frame to the end frame**, not a standalone
  description of either frame. The `fixed_end_frame_prompt_hint` returned by the model is the upstream guidance for
  this scenario; prefer it.

## General Hard Constraints

- **Creating a task charges credits. Before submitting, you must explain the cost to the user and obtain explicit confirmation**.
  All query tools are free.
- **Images must be cropped before upload**. The crop specification is provided by `crop` from `i2v_get_options`, and
  **the server does not accept image binaries; cropping is done locally**.
- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server has already handled them,
  and they do not exist in the tool inputs.
- Allowed values for `quality` / `duration` / `mode` **must come from `i2v_list_models`**. Do not invent them.
- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes; briefly report progress.
- When `task_status` is `fail`, do not retry blindly. First tell the user the `task_reason`,
  then ask whether to retry or give up. Retrying re-submits the task at the normal
  price--failed credits are refunded automatically, and this billing rule was already disclosed
  when quoting the cost, so no new price confirmation is needed here.
- **Before showing the video, you must download it locally first**. A remote URL pasted directly cannot be previewed.

## Showing the Artifact

The finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files from these domains**;
if you paste the URL directly, the user will not be able to open it.

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-i2v/<task_id>"
mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/result.mp4" "<video_url>"
```

Video cannot be embedded for display. Provide the local absolute path, and also include the original remote URL.
If the download fails (non-200 / empty file), clearly state "preview download failed" and provide the remote URL.
Do not falsely claim it has been displayed.

## Step 0: Confirm Service Binding, Login, and Credit Balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Validate that the returned `brand` must be **Enkio**. If not, it means the call is connected to the wrong service;
  stop immediately and tell the user.

The returned `credit` is the current balance; record it for later.

**Membership check (required).** Creating tasks with `i2v_create_task` 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: Choose a Model That Supports First/End Frames

```
i2v_list_models(end_frame=true)
-> { end_frame_only: true, count, models: [...] }
```

**You must include `end_frame=true`**. All returned models support fixed first/end frames. If `count` is 0, there are
currently no available models; tell the user truthfully and do not fall back to forcing a single-image model.

List the selectable models for the user together with their supported resolutions, durations, and modes. If the user
has no preference, choose a cost-effective default combination from `combinations` and explain why.

## Step 2: Set Parameters and Quote

```
i2v_get_options(model, quality?, duration?, mode?, ratio?, end_frame=true)
-> { quality, duration_sec, mode, ratio, credit_cost, image_count, image_role, crop, ... }
```

**Remember to include `end_frame=true`**. The server will also validate whether the model supports the capability and
whether the ratio is legal, and will mark `image_count` as 2 and `image_role` as `["First frame", "End frame"]`.

If the model's default ratio is `free`, the server will report an error requiring a fixed ratio instead. Choose a
non-`free` ratio from `ratios`, such as `9:16` for vertical video or `16:9` for horizontal video.

**Tell the user the `credit_cost` together with the `credit` balance from Step 0 and wait for
confirmation**. If the balance is insufficient, prompt the user to recharge first (see
references/credits.md for the recharge link and steps).

## Step 3: Crop Both Images to the Same Ratio

`crop` provides the target ratio and pixel dimensions. **Run exactly the same crop command for the first frame and the end frame**:

```bash
W=<target_width>; H=<target_height>
for NAME in first end; do
  ffmpeg -y -i "<$NAME original image>" \
    -vf "crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H" \
    "$WORKDIR/$NAME.jpg"
done
```

If ffmpeg is unavailable, use macOS's built-in `sips`:

```bash
for NAME in first end; do
  cp "<$NAME original image>" "$WORKDIR/$NAME.jpg"
  sips --cropToHeightWidth "$H" "$W" "$WORKDIR/$NAME.jpg" >/dev/null
  sips --resampleHeightWidth "$H" "$W" "$WORKDIR/$NAME.jpg" >/dev/null
done
```

After cropping, **you must verify that the two images have exactly identical dimensions** before continuing:

```bash
sips -g pixelWidth -g pixelHeight "$WORKDIR/first.jpg" "$WORKDIR/end.jpg"
```

## Step 4: Upload Each Image to Get URLs

```
create_upload_url() -> { upload_url, headers }
```

Upload the two images separately, and **remember clearly which URL is the first frame and which is the end frame**:

```bash
curl -sS -X POST "<upload_url>" -F "file=@$WORKDIR/first.jpg" -H "X-Client-Sn: <value from headers>"
curl -sS -X POST "<upload_url>" -F "file=@$WORKDIR/end.jpg"   -H "X-Client-Sn: <value from headers>"
# Each returns {"c":200,"m":"Success","d":"https://.../xxx.jpg"}
```

The `d` in the response is the image URL. If `c != 200`, it failed; report `m` to the user.
Uploaded files are **temporary storage and will be cleaned up periodically**. Submit the task as soon as possible after obtaining the URLs.

## Step 5: Create the Task (Charges Credits)

```
i2v_create_task(model, image_urls=[<first-frame URL>, <end-frame URL>], prompt?, ratio?,
                quality?, duration?, mode?, movement_amplitude?)
-> { task_id, task_status, end_frame, credit_cost, ... }
```

- **`image_urls` must contain two elements, with the first being the first frame and the second being the end frame**.
  The order must not be reversed.
- `ratio` must match the ratio used for cropping in Step 3.
- Parameters must match the combination confirmed during the Step 2 quote; otherwise the actual charge may not match the quote.
- `prompt` describes **how the first frame changes into the end frame** (motion, camera movement, transition method),
  referencing `fixed_end_frame_prompt_hint`.
- The returned `end_frame` should be `true`; if it is `false`, only one image was passed, so stop and check.

## Step 6: Poll

```
i2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }
```

- `task_status == "success"`: `video_url` is the finished video; proceed to Step 7.
- `task_status == "fail"`: relay `task_reason` to the user and ask whether to retry after
  adjustments or abandon the task. Retrying re-bills at the normal price (failed credits are
  refunded automatically); this was already disclosed up front, so you do not need to reconfirm
  the price.
- Other values: queued or generating. Wait 10 seconds, query again, and briefly tell the user the progress.

## Step 7: Download and Deliver

Follow "Showing the Artifact" to download `video_url` to `$WORKDIR/result.mp4`, then provide the local path + original URL.
When delivering, remind the user to check whether the first and end frames match expectations, and explain that both
the remote link and the local temporary file may be cleaned up, so they should save another copy promptly.

## Error Handling

For login, connection, and service binding issues, see `references/auth.md` (**when not logged in, the entire MCP namespace
will not appear**; do not misjudge this as the plugin not being installed, and especially do not switch to another brand's MCP).
Common error codes and handling are in `references/errors.md`; credit and billing rules are in `references/credits.md`;
return field structures for each tool are in `references/workflow.md`.

Referenced files: 4 — file references are metadata, not package contents.

generate-image15.6 KB

View saved version →

---
name: generate-image
description: Generate images with AI (Enkio / enkiomv.ai), supporting text-to-image and image-to-image. Use when the user wants to generate an image, turn a photo into a certain style, change a photo's background/outfit/art style, says text-to-image / image-to-image / AI drawing, or asks which image-generation models are supported, how many credits they cost, or what resolution they can produce. The output is images; to generate videos, use the enkio:image-to-video, enkio:first-end-frame-video, enkio:reference-to-video, or enkio:text-to-video skills instead. The entire flow is completed through the enkio MCP service.
---

# AI Image Generation

Call enkiomv.ai's image-generation capability through the `enkio` MCP service: provide a prompt,
and optionally several input images, to generate images. **The same `any2i_*` tool set covers both
text-to-image and image-to-image**--with no input images it is text-to-image; with input images it is
image-to-image. Whether a model needs images, and how many, is determined entirely by that model's
own configuration.

## Service binding

All capabilities in this skill come from the single `enkio` MCP server and **must not be replaced**:

- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, 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 under the `mcp__enkio` namespace.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Under no circumstances may you substitute another brand's MCP** (`mcp__selfyz_ai` and
  `mcp__enkio` are two services, two accounts, and two credit pools; cross-use will really charge the
  wrong account). Do not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained
  elsewhere.
- When you need to explain which service this skill is connected to, rely on the `brand` /
  `brand_website` returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this
  plugin's `.mcp.json`; do not answer from memory or guesswork. If `brand` is not Enkio, stop
  immediately and report the error.

Tasks are **asynchronous**: `any2i_create_task` returns a `job_id` immediately, and you must poll
`any2i_get_task` yourself.

```
0 Log in/check balance -> 1 Choose model -> 2 Set quality and quote (confirm before charging)
-> 3 Only with input images: crop locally -> 4 Only with input images: upload each image to get URLs
-> 5 Create task (charges credits) -> 6 Poll -> 7 Download, preview, and deliver
```

## Hard constraints

- **Image generation and video generation use separate tool groups, and their tools are
  not interchangeable**. The image-generation task identifier is **`job_id`** (not the video's
  `task_id`), and the result is an **`image_urls` array** (not a single `video_url`). Always poll
  with `any2i_get_task`; a video query tool returns no `image_urls`.
- **Creating a task charges credits; before submitting, you must explain the cost to the user and get
  explicit confirmation**. All query tools are free.
- **`prompt` is required**. An empty prompt, or one containing only whitespace, will be rejected
  directly.
- **The number of input images is decided by the model**: `any2i_get_options` returns
  `image_count = { min, max }`. `min` equal to 0 means images may be omitted (text-to-image);
  `max` equal to 0 means the model **does not accept input images at all**, and forcing them in will
  be rejected. Any count outside the interval is rejected.
- **Credits vary only with quality**, not with aspect ratio, number of input images, or prompt
  length. Therefore, within the image-count limit, adding another image or writing a longer prompt is
  "free".
- **When there are input images, every image must be cropped to the target ratio before uploading**.
  The crop specification comes from `crop` in `any2i_get_options`; **the server does not accept image
  binaries, and cropping is done locally**. When `ratio` is `free`, no cropping is needed.
- **Do not construct or guess `user_id`, `example`, signatures, or similar parameters**. The server
  already handles them, and they do not exist in the tool inputs.
- The allowed values for `quality` / `ratio` **must come from `any2i_list_models`**.
- Polling cadence: once every 5 seconds, with a limit of about 5 minutes. Image generation is usually
  much faster than video generation, but still give the user brief progress updates; do not wait
  silently for a long time.
- When a task's `job_status` is `fail`, do not blindly retry. Tell the user the `job_reason`
  first, then ask whether to retry or give up. Retrying re-submits the task at the normal
  price--failed credits are refunded automatically, and this billing rule was already disclosed
  when quoting the cost, so no new price confirmation is needed here.
- **Before showing images, you must download them locally first**. Pasting a remote URL directly
  cannot preview it; see "Displaying artifacts".

## How to write prompts

**Text-to-image** (no input images): the model has no visual reference, so describe the image
clearly--subject + action/pose + scene + composition/viewpoint + lighting/style.

```
✅ A corgi wearing sunglasses sits on a vintage motorcycle, afternoon backlight, film grain, shallow-depth-of-field close-up
❌ A dog                                <- The scene, style, and composition are all left for the model to guess
```

**Image-to-image** (with input images): the prompt describes **what you want this image to become**.
You do not need to repeat what is already in the image; focus on "what to change and what to keep".

```
✅ Replace the background with snowy mountains, keep the person and clothing unchanged, and make the overall tone cool
✅ Convert it to a watercolor illustration style while preserving the original composition
❌ A person standing in front of snowy mountains                        <- It does not say whether to "modify" or "redraw", so original-image features are easily lost
```

When there are multiple input images, refer to them in natural language by submission order ("the
person in the first image", "the clothing in the second image"). **Do not use reference syntax such
as `@1` or `{img1}`**; the upstream does not support it and will treat it as plain text.

Do not exceed `prompt_limit_length`. The model's `prompt_hint` is upstream guidance on writing
prompts, and `prompt_guide_url` is the upstream prompt guide page. You may paraphrase them to the
user, but do not open the page on the user's behalf.

## Displaying artifacts

The finished images are **temporary remote URLs** from Enkio. Codex **cannot embed-preview media
files from these domains**, and users cannot open a bare pasted URL.

Use a per-task isolated working directory (so the user's repository is not polluted):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-any2i/<job_id>"
mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/result1.png" "<image_urls[0]>"
```

`image_urls` may contain multiple images; **download every image** and name them in order. Images can
be shown directly to the user, and the original remote URLs should be included as well so the user can
save them manually. If download fails (non-200 / empty file), clearly say "preview download failed"
and provide the remote URL; do not falsely claim it has been displayed.

## Step 0: Confirm service binding, login, and credit balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Validate that the returned `brand` must be **Enkio**; otherwise the call is connected to the wrong
  service. Stop immediately and tell the user.

The returned `credit` is the current credit balance. Record it and compare it with the estimated cost
when quoting in step 2.

**Membership check (required).** Creating tasks with `any2i_create_task` 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: Choose a model

```
any2i_list_models()
-> { count, models: [ { model, model_name, model_desc, qualities, ratios, default_ratio,
                       min_image_count, max_image_count, accepts_images, requires_images,
                       prompt_limit_length, prompt_hint, prompt_guide_url,
                       credits: [{ quality, quality_display, credit }] } ] }
```

`models[].model` is the model identifier; use it for all subsequent calls.

**First filter models based on whether the user has images**:
- User only provided text -> choose a model with `min_image_count == 0`
- User provided images to modify -> choose a model with `accepts_images == true` whose count interval
  can accommodate the number of images

Briefly list the available models for the user, including each model's supported qualities, ratios,
and required number of images. If the user has no preference, choose the default quality from
`credits` with a reasonable cost-performance tradeoff and explain why.

## Step 2: Set quality and quote

```
any2i_get_options(model, quality?, ratio?)
-> { model, model_name, quality, ratio, credit_cost,
    image_count: { min, max }, accepts_images, requires_images, crop,
    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url }
```

If parameters are omitted, they fall back to the model defaults, and the response clearly states the
final effective values.

**Tell the user both `credit_cost` and the `credit` balance from step 0, then wait for
confirmation**. If the balance is insufficient, prompt the user to recharge first (see
references/credits.md for the recharge link and steps); do not force submission. Quality is the only
dimension that affects credits, so if the user thinks it is expensive, suggest lowering quality
first.

## Step 3: Crop input images locally (skip if there are no input images)

The `crop` field gives the target ratio and pixel dimensions:

```
crop = { ratio, crop_required, target_width, target_height, strategy, hint }
```

When `crop_required` is `false` (the ratio is `free`), skip this step and upload the original images
directly. Otherwise, **every input image** must first be center-cropped to the target aspect ratio and
then scaled to `target_width × target_height`:

```bash
W=<target_width>; H=<target_height>
i=1
for SRC in "<input image 1>" "<input image 2>"; do
  ffmpeg -y -i "$SRC" \
    -vf "crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H" \
    "$WORKDIR/src$i.jpg"
  i=$((i+1))
done
```

If ffmpeg is unavailable, use the macOS built-in `sips` (note that `--cropToHeightWidth` is **height
first, then width**):

```bash
cp "<input image 1>" "$WORKDIR/src1.jpg"
sips --cropToHeightWidth "$H" "$W" "$WORKDIR/src1.jpg" >/dev/null
sips --resampleHeightWidth "$H" "$W" "$WORKDIR/src1.jpg" >/dev/null
```

After cropping, confirm that every output file exists and has the correct dimensions
(`sips -g pixelWidth -g pixelHeight`) before moving on. **Keep the order unchanged**; it is the order
of `image_urls` when submitting.

## Step 4: Upload each image to get URLs (skip if there are no input images)

The upload endpoint accepts only one file per request, so **call `create_upload_url` separately for
every image**:

```
create_upload_url() -> { upload_url, headers }
```

```bash
curl -sS -X POST "<upload_url>" -F "file=@$WORKDIR/src1.jpg" -H "X-Client-Sn: <value from headers>"
# -> {"c":200,"m":"Success","d":"https://.../src1.jpg"}
```

The `d` in the response is the image URL. `c != 200` means failure; report `m` to the user.
**Collect these URLs in order**. Uploaded files are **temporary storage and are cleaned up
periodically**; after getting the URLs, submit the task as soon as possible.

## Step 5: Create the task (charges credits)

```
any2i_create_task(model, prompt, image_urls?, quality?, ratio?)
-> { job_id, job_status, model, image_count, quality, ratio, credit_cost }
```

- `prompt` is **required**; see "How to write prompts".
- Do **not pass** `image_urls` for text-to-image; for image-to-image, pass them in order, and ensure
  the count falls within the `image_count` interval from step 2.
- `ratio` must **match** the ratio used for cropping in step 3.
- `quality` must match what was confirmed during the step-2 quote; otherwise the actual charge will
  not match the quote.

## Step 6: Poll

```
any2i_get_task(job_id) -> { job_status, job_reason, image_urls, image_count, finished }
```

Note that the input parameter name is **`job_id`**, not `task_id`.

- `job_status == "success"`: `image_urls` are the finished images; proceed to step 7.
- `job_status == "fail"`: pass `job_reason` to the user and ask whether to adjust the prompt
  and retry or give up. Retrying re-bills at the normal price (failed credits are refunded
  automatically); this was already disclosed up front, so you do not need to reconfirm the
  price.
- Other values: queued or generating; wait 5 seconds and check again, with a brief progress update to
  the user.

## Step 7: Download and deliver

Following "Displaying artifacts", download **every image** in `image_urls` to `$WORKDIR`, show them
to the user, and provide the local paths + original URLs. Remind the user: remote links point to
temporary storage and will be cleaned up; local files under the system temporary directory may also be
reclaimed by the system, so they should save the images to their own directory as soon as possible.

It is normal for the same prompt to generate different results each time. If the user is unhappy,
first suggest **making the prompt more specific** rather than directly switching models and retrying.

## Error handling

For login, connection, and service-binding issues, see `references/auth.md` (**when not logged in, the
entire MCP namespace will not appear**; do not misjudge this as the plugin not being installed, and
especially do not switch to another brand's MCP). See `references/errors.md` for common error codes
and handling; `references/credits.md` for credits and billing rules; and `references/workflow.md` for
the return-field structures of each tool.

Referenced files: 4 — file references are metadata, not package contents.

generate-mv19.3 KB

View saved version →

---
name: generate-mv
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.
---

# Generate MV

Use the `enkio` MCP service to call enkiomv.ai's MV Agent and turn one audio track plus several images into an MV.

## Service binding

All capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:

- Its tool namespace in Codex is **`mcp__enkio`**. Codex normalizes `-` in server names to `_`,
  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.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are two services,
  two accounts, and two credit pools; cross-use will charge real credits to the wrong account). Also do not mix in
  a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.
- When you need to explain which service this skill is connected to, rely on the `brand` / `brand_website`
  returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`.
  Do not answer from memory or guesswork; if `brand` is not Enkio, stop immediately and report an error.

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 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
→ 6 Regenerate a single shot (optional, charged)
→ 7 Retrieve final video (free) → Deliver
```

**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.

## Mandatory confirmation gates (read this before anything else)

MV generation has **three mandatory user confirmation gates**. They are not suggestions and they
cannot be merged, skipped, or pre-approved. **Clearing one gate never authorizes the next one.**
**Every gate must be presented together with the credit cost of that step** (`step_credit` in the
tool response).

| 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 (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` |

The MCP service reports each gate in its response:

```
requires_user_confirmation: true
confirmation_gate: "plan_and_credit" | "story_assets" | "segments"
blocked_until_user_confirms: ["mv_submit_production"]
user_confirmation_prompt: "GATE 2 of 3 - STOP AND ASK THE USER. ..."
step_credit: { step: "storyboard_production", credit: 150, charged_by: "audio duration", ... }
```

**Whenever `requires_user_confirmation` is `true`: present the artifacts, state the `step_credit`
amount, ask the question, and END YOUR TURN.** Do not call another tool in the same turn, do not
keep polling, and do not assume "the user already said make an MV" counts as an answer. Only a new
user message in this conversation clears a gate.

If you ever find yourself about to call `mv_create_story` or `mv_submit_production`, or to hand
over `result_url`, without a user message in between, you have violated this section - stop and ask
instead.

## Hard constraints

- **The three confirmation gates above are absolute.** Never chain parameter confirmation → story creation → shot production → final video in one unattended run.
- **Every gate must state the credit cost of that step** (`step_credit` from the tool response), not just the artifacts.
- **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.
  Free operations: editing the storyline, editing lyrics, compose-only (`compose_only=true`), and query tools (including retrieving the final video in step 7).
- **After every display of a cover, role, or shot image, proactively tell the user they can spend credits to regenerate it**; see "Regeneration prompt".
- **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.
- Remember the `task_id` after every submission; every later call must include it.
- 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.
  During polling, give the user brief progress updates; do not wait silently for a long time.
- When any status is `fail`, do not blindly retry the whole order. First tell the user which
  item failed and the error message, then ask whether to regenerate that item or abandon it.
  Regenerating re-bills that step at the normal price--failed credits are refunded
  automatically, and this billing rule was already disclosed when quoting each step's cost, so
  no new price confirmation is needed here.
- **Before showing images/videos, you must download them locally first**. Directly pasting a remote URL cannot be embedded for preview; see the next section.

## Showing artifacts (important)

The cover image, role image, shot images, and final MV returned by MV Agent are all Enkio **temporary remote URLs**.
Codex **cannot embed previews for images on these domains**; directly pasting a URL will only display a gray placeholder box.

Therefore: **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.**

Use a task-isolated working directory by convention (to avoid polluting the user's repository):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-mv/<task_id>"
mkdir -p "$WORKDIR"

# Use a meaningful <name>: cover / role / seg-00 / mv
# Infer the extension from the URL path; if unavailable, use .png (use .mp4 for video)
curl -sS -L -o "$WORKDIR/<name>.<ext>" "<remote URL>"
```

After downloading:

- Show images using the local absolute path so the user can see them directly in the conversation
- Also include the original remote URL so the user can save it themselves
- If download fails (non-200 / empty file), clearly state "preview download failed" and provide the remote URL so the user can open it themselves;
  do not falsely claim that the image has been shown
- 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

Whenever later steps mention "show", follow this section.

## Regeneration prompt

**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.

The prompt must include:

1. What can be regenerated (cover / role / a shot with a specified index)
2. How many credits each regeneration costs (from `mv_get_options`; see `references/credits.md`)
3. The current credit balance (`credit` from `get_user_profile()`)
4. That regeneration supports natural-language descriptions of the desired changes

For example:

> 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.
> 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."

Then **wait for the user to state their choice explicitly before acting**. Do not initiate any charged regeneration on your own.

## Step 0: Confirm service binding, login, and credit balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Verify that the returned `brand` must be **Enkio**. If not, it means the wrong service is connected; stop immediately and tell the user.

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`.
2. Upload directly with shell (the form field name is fixed as `file`), once per file:

```bash
curl -sS -X POST "<upload_url>" -F "file=@/path/to/song.mp3" -H "X-Client-Sn: <value from headers>"
# → {"c":200,"m":"Success","d":"https://.../song.mp3"}
```

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: 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(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`: `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

Then **end your turn** and wait for the user to confirm or change the parameters. **Do not call
`mv_create_story` in the same turn.**

Audio 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.

## Step 3: Story creation (stage one, charged)

```
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.

Then poll `mv_get_story(task_id)` until the outline, cover, role, storyline, and lyrics statuses are all `success`.
Outputs: story outline, cover image, role image, storyline shots (index/start-end time/description), and timestamped lyrics.

Show them to the user (**first download `cover_url` and `role_url` according to "Showing artifacts", then paste the local paths**):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-mv/$TASK_ID"; mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/cover.png" "<cover_url>"
curl -sS -L -o "$WORKDIR/role.png"  "<role_url>"
```

Then provide, in order: cover image, role image, story outline, storyline shots, and lyrics summary.

Once the cover, outline, lyrics, and storyline are all `success`, `mv_get_story` returns
`confirmation_gate: "story_assets"` — this is **GATE 2**:

1. Show the cover image, the story outline, the timestamped lyrics, and the storyline shots
2. State `step_credit.credit`, the credit cost of the shot production you are about to start
3. Follow "Regeneration prompt" (cover/role regeneration is charged; storyline/lyrics edits are free)
4. Ask whether to edit anything or to start the charged shot production, then **end your turn**

**Do not call `mv_submit_production` in the same turn in which the gate fired.** Wait for the user's
explicit go-ahead.

## Step 4: Edits and regeneration (optional)

| Request | Tool | Billing |
| --- | --- | --- |
| Change shot descriptions or timeline | `mv_update_storyline(task_id, storyline)` | Free |
| Change lyrics or timestamps | `mv_update_lyrics(task_id, lyrics)` | Free |
| Role image is unsatisfactory | `mv_regenerate_asset(task_id, "role", prompt?)` | Charged |
| Cover image is unsatisfactory | `mv_regenerate_asset(task_id, "cover", prompt?)` | Charged |

- Both update tools require a **complete list** (not a delta). Modify the full result from `mv_get_story` and write it back.
- Edits can only be made after stage one completes and before submitting shot production.
- Regeneration is asynchronous; after submitting it, return to polling the corresponding status with `mv_get_story`.
- After regeneration completes, **download and show the new image again** (the URL changes). Do not fool the user with the old local file.

Field structures are in `references/workflow.md`.

## Step 5: Shot production (stage two, charged by duration)

```
mv_submit_production(task_id)     # First call, charges credits
mv_get_production(task_id)               # Poll
```

After polling until all `segments[].image_status == 2`, **this step only shows shot images; do not rush to provide the final video**.

Download and show shot images according to "Showing artifacts":

```bash
curl -sS -L -o "$WORKDIR/seg-00.png" "<segments[0].image_url>"   # Name by index and download one by one
```

When there are many shots, show the first few plus any the user names; do not pull all of them at once.

This is **GATE 3**. After showing the shots, state `step_credit` (accepting the shots and
retrieving the final video is free) and follow "Regeneration prompt" to tell the user which shots
can be regenerated and how many credits each costs, then **end your turn** and wait for their
choice:

- If the user wants regeneration → go to step 6
- If the user is satisfied → go to step 7 to retrieve the final video

**Even if `result_url` is already present in the response, do not deliver it before the user
accepts the shots.**

## Step 6: Single-shot refinement (optional, 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
```

- `segment_index` comes from `segments[].index` in `mv_get_production`; do not count it yourself.
- **After regenerating a shot, you must run composition once with `compose_only=true`**, otherwise step 7 will still return the old final video.
- After regeneration completes, download and show the new shot image again (the URL changes), then ask the user whether to keep editing.
- When the user is done editing → go to step 7.

## Step 7: Retrieve final video (no credits charged)

```
mv_get_production(task_id).result_url
```

Call `mv_get_production` again and take `result_url`, which is the composed final MV. **This step does not consume any credits**.

**Only reach this step after the user has cleared GATE 3.**

- If `result_url` is empty: composition has not finished; continue polling at the stage-two cadence.
  If step 6 was just performed and it still does not refresh, check whether the `compose_only=true` composition was missed.
- After obtaining `result_url`, proceed to "Deliver".

## Deliver

First download the final MV to the local working directory, then deliver it:

```bash
curl -sS -L -o "$WORKDIR/mv.mp4" "<result_url>"
```

Provide the local file path + original `result_url`, and remind the user: the remote link points to temporary storage and will be cleaned up,
and 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.

## Error handling

For 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).
For common upstream error codes and handling, see `references/errors.md`; for credit and billing rule details, see `references/credits.md`;
for return field structures of each tool, see `references/workflow.md`.

Referenced files: 4 — file references are metadata, not package contents.

image-to-video11.9 KB

View saved version →

---
name: image-to-video
description: Generate an AI video from one image (Enkio / enkiomv.ai). Use this when the user wants to turn a photo into a video, make an image move, create image-to-video, add motion effects to a static image, or asks how many credits image-to-video costs and which models and resolutions are supported. If the user needs a fixed first-frame + end-frame transition effect, use the enkio:first-end-frame-video skill instead; if the user wants to combine multiple reference images into a new scene, use the enkio:reference-to-video skill instead. The entire workflow is completed through the enkio MCP service.
---

# Image-to-video

Use the `enkio` MCP service to call enkiomv.ai's image-to-video capability and turn
**one image** + a prompt into a video clip.

## Service binding

All capabilities in this skill come from the single `enkio` MCP server, **and it cannot be
replaced**:

- In Codex, its tool namespace is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and
  tool names do not include a prefix. Every tool name mentioned below (such as `get_user_profile`)
  refers to the same-named tool under the `mcp__enkio` namespace.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and
  `mcp__enkio` are two services, two accounts, and two credit pools; cross-use will charge real
  credits to the wrong account). Do not mix in a `task_id` / `job_id`, credit balance, or output URL
  obtained elsewhere.
- When you need to explain which service this skill is connected to, use the `brand` /
  `brand_website` returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this
  plugin's `.mcp.json`. Do not answer from memory or guesswork; if `brand` is not Enkio, stop
  immediately and report an error.

Tasks are **asynchronous**: `i2v_create_task` returns a `task_id` immediately, and you must poll
`i2v_get_task` yourself.

```
0 Log in / check balance -> 1 Choose model -> 2 Decide parameters and quote (confirm before charging)
-> 3 Crop the image locally -> 4 Upload and get URL -> 5 Create task (charges credits)
-> 6 Poll -> 7 Download, display, and deliver
```

## Hard constraints

- **Creating a task charges credits. Before submitting, you must explain the cost to the user and
  obtain explicit confirmation**. Query tools are all free.
- **The image must be cropped to the target aspect ratio before upload**; otherwise the upstream
  service processes it by its own rules, and the composition of the finished video can easily drift.
  The crop specification is provided by `crop` returned from `i2v_get_options`. **The server does
  not accept image binaries; cropping is done locally**.
- **Do not construct or guess parameters such as `user_id`, `example`, signatures, and so on**. The
  server already handles them, and these parameters do not exist in the tool inputs.
- The selectable values for `quality` / `duration` / `mode` **must come from `i2v_list_models`**;
  do not invent them. These three parameters jointly determine the billing template; if the
  combination does not exist, the server will reject it directly.
- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,
  give the user brief progress updates; do not wait silently for a long time.
- When the task `task_status` is `fail`, do not retry blindly. Tell the user the `task_reason`
  first, then ask what to do. Retrying re-submits the task at the normal price--failed credits
  are refunded automatically, and this billing rule was already disclosed when quoting the
  cost, so no new price confirmation is needed here.
- **Before displaying a video, you must download it locally first**. Pasting the remote URL directly
  cannot provide a preview; see "Displaying the output".

## Displaying the output

The finished video is an Enkio **temporary remote URL**. Codex **cannot embed previews for media
files from these domains**, and users cannot open a bare pasted URL.

Use a per-task isolated working directory (so the user's repository is not polluted):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-i2v/<task_id>"
mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/result.mp4" "<video_url>"
```

Videos cannot be embedded for display. Provide the local absolute path, and include the original
remote URL as well so the user can save it themselves. If the download fails (non-200 / empty file),
state clearly that "preview download failed" and provide the remote URL; do not falsely claim that
it has been displayed.

## Step 0: Confirm service binding, login, and credit balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Validate that the returned `brand` must be **Enkio**. If not, it means the wrong service is
  connected; stop immediately and tell the user.

The returned `credit` is the current credit balance. Record it and compare it with the estimated
cost during the quote in Step 2.

**Membership check (required).** Creating tasks with `i2v_create_task` 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: Choose a model

```
i2v_list_models()
-> { count, models: [ { model, model_name, model_desc, qualities, durations_sec,
                        modes, ratios, default_ratio, movement_amplitudes,
                        prompt_limit_length, prompt_hint, combinations, ... } ] }
```

`models[].model` is the model identifier; use it in all later calls. List the available models for
user selection, together with each model's supported resolutions, durations, and modes. If the user
has no preference, choose a cost-effective default combination from `combinations` and explain why.

`combinations` directly gives the credit cost for each "mode + quality + duration" combination;
prioritize it when choosing parameters.

## Step 2: Decide parameters and quote

```
i2v_get_options(model, quality?, duration?, mode?, ratio?)
-> { quality, duration_sec, mode, ratio, credit_cost, crop, prompt_limit_length, prompt_hint }
```

If parameters are omitted, they fall back to the model defaults. The return value explicitly tells
you the final effective values.

**Tell the user the `credit_cost` together with the `credit` balance from Step 0 and wait for
confirmation**. If the balance is insufficient, prompt the user to recharge first (see
references/credits.md for the recharge link and steps); do not force a submission.

## Step 3: Crop the image locally

The `crop` field gives the target aspect ratio and pixel dimensions:

```
crop = { ratio, crop_required, target_width, target_height, strategy, hint }
```

When `crop_required` is `false` (the ratio is `free`), skip this step and upload the original image
directly. Otherwise, first center-crop to the target aspect ratio, then scale to
`target_width x target_height`:

```bash
W=<target_width>; H=<target_height>
ffmpeg -y -i "<original image>" \
  -vf "crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H" \
  "$WORKDIR/input.jpg"
```

If ffmpeg is unavailable, use macOS's built-in `sips`:

```bash
cp "<original image>" "$WORKDIR/input.jpg"
sips --cropToHeightWidth "$H" "$W" "$WORKDIR/input.jpg" >/dev/null
sips --resampleHeightWidth "$H" "$W" "$WORKDIR/input.jpg" >/dev/null
```

After cropping, confirm that the output file exists and that its dimensions are correct
(`sips -g pixelWidth -g pixelHeight`) before proceeding to the next step.

## Step 4: Upload and get a URL

```
create_upload_url() -> { upload_url, headers }
```

```bash
curl -sS -X POST "<upload_url>" -F "file=@$WORKDIR/input.jpg" -H "X-Client-Sn: <value from headers>"
# -> {"c":200,"m":"Success","d":"https://.../input.jpg"}
```

The `d` field in the response is the image URL. `c != 200` means failure; report `m` to the user.
Uploaded files are **temporarily stored and cleaned up on a schedule**. Submit the task as soon as
you get the URL.

## Step 5: Create the task (charges credits)

```
i2v_create_task(model, image_urls=[<image URL>], prompt?, ratio?, quality?, duration?,
                mode?, movement_amplitude?)
-> { task_id, task_status, credit_cost, quality, duration_sec, mode, ratio }
```

- Pass exactly **one** image in `image_urls` (this skill is the single-image workflow).
- `ratio` must **match** the ratio used for cropping in Step 3.
- Parameters must match the set confirmed during the quote in Step 2; otherwise the actual charge
  may not match the quote.
- `prompt` describes the action and camera movement you want in the scene. Its length must not
  exceed `prompt_limit_length`; the model's returned `prompt_hint` is upstream guidance for prompt
  writing and may be used as a reference.

## Step 6: Poll

```
i2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }
```

- `task_status == "success"`: `video_url` is the finished video; proceed to Step 7.
- `task_status == "fail"`: relay `task_reason` to the user and ask whether to adjust parameters
  and retry or give up. Retrying re-bills at the normal price (failed credits are refunded
  automatically); this was already disclosed up front, so you do not need to reconfirm the
  price.
- Other values: queued or generating. Wait 10 seconds, query again, and briefly update the user on
  progress.

## Step 7: Download and deliver

Following "Displaying the output", download `video_url` to `$WORKDIR/result.mp4`, provide the local
path + original URL, and remind the user: the remote link points to temporary storage and will be
cleaned up, and local files under the system temporary directory may also be reclaimed by the
system. They should save the file to their own directory as soon as possible.

## Error handling

Login, connection, and service-binding issues are covered in `references/auth.md` (**when not logged
in, the entire MCP namespace will not appear**; do not misdiagnose it as the plugin being missing,
and never switch to another brand's MCP).
Common error codes and handling are covered in `references/errors.md`; credit and billing rules are
covered in `references/credits.md`; each tool's returned field structure is covered in
`references/workflow.md`.

Referenced files: 4 — file references are metadata, not package contents.

reference-to-video15.9 KB

View saved version →

---
name: reference-to-video
description: Generate AI videos from multiple reference images (Enkio / enkiomv.ai). Use when the user wants to combine several images into a video, use one person image plus one clothing/scene/object image to make a video, create reference-image-to-video / multi-image-to-video / reference video, or asks how many images, how many credits, or which models are supported for reference-image-to-video. If the user only wants to animate a single image, use the enkio:image-to-video skill instead; if the user wants a fixed first-frame + end-frame transition, use the enkio:first-end-frame-video skill instead. The entire workflow is completed through the enkio MCP service.
---

# Reference-Image-to-Video

Use the `enkio` MCP service to call enkiomv.ai's reference-image-to-video capability: provide several
**reference images** plus a **prompt**, and the model synthesizes the people, clothing, scenes, objects,
and other elements from those reference images to generate a brand-new video.

## Service Binding

All capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:

- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and tool
  names have no prefix. Every tool name mentioned below (such as `get_user_profile`) refers to the tool of
  the same name under the `mcp__enkio` namespace.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are
  two separate services, two accounts, and two credit pools; cross-use will charge real credits on the wrong
  account). Also do not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.
- When you need to explain which service this skill is connected to, use the `brand` / `brand_website`
  returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`;
  do not answer from memory or guesswork. If `brand` is not Enkio, stop immediately and report an error.

The essential difference from `enkio:image-to-video`: single-image-to-video **animates this image**, while
reference-image-to-video **uses these images as references to redraw a video**. The frame does not need
to match any input image exactly.

Tasks are **asynchronous**: `i2v_create_task` returns `task_id` immediately, and you must poll
`i2v_get_task` yourself.

```
0 Log in/check balance -> 1 Choose model (kind=reference) -> 2 Set parameters, image count, and quote (confirm before charging)
-> 3 Crop each reference image locally -> 4 Upload each image to get URLs -> 5 Create task (charges credits)
-> 6 Poll -> 7 Download, display, and deliver
```

## Hard Constraints

- **Every `i2v_*` call in this skill must include `kind="reference"`**. Reference-image-to-video and
  image-to-video use completely different model lists. If `kind` is omitted, you will get image-to-video
  models, and submission will fail with "nonexistent reference-image-to-video model".
- **Creating a task charges credits; before submitting, you must explain the cost to the user and obtain
  explicit confirmation**. All query tools are free.
- **The number of reference images is determined by the model**: `i2v_get_options` returns
  `image_count = { min, max }`; fewer than `min` or more than `max` will be rejected directly by the
  server. The maximum is 3 images.
- **`prompt` is required**, and it is the core input for this mode--reference images only provide material;
  the prompt must clearly state how the frame should combine them. Empty or whitespace-only prompts
  will be rejected directly.
- **Refer to reference images in natural language in the prompt; do not use reference syntax such as
  `@1` or `{img1}`**. The upstream service does not support it and will treat it as ordinary text.
  See "How to Write Prompts" below for the correct style.
- **Each reference image must be cropped to the target ratio before upload**. The cropping specification
  comes from `crop` in `i2v_get_options`, and **the server does not accept image binaries; cropping is
  done locally**.
- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already
  handles them, and they do not exist in the tool inputs.
- The allowed values for `quality` / `duration` / `mode` **must come from
  `i2v_list_models(kind="reference")`**.
- Reference-image-to-video **does not have a fixed first/end frame mode**; passing `end_frame=true` will
  fail directly.
- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,
  briefly tell the user progress; do not wait silently for a long time.
- When the task `task_status` is `fail`, do not retry blindly. First tell the user the
  `task_reason`, then ask what to do. Retrying re-submits the task at the normal price--failed
  credits are refunded automatically, and this billing rule was already disclosed when quoting
  the cost, so no new price confirmation is needed here.
- **Before showing the video, you must download it locally first**. A remote URL cannot be previewed
  directly; see "Displaying the Artifact".

## How to Write Prompts

Reference images correspond to "reference image 1 / 2 / 3" **in submission order**; the order itself is
semantic. In the prompt, use natural language to describe what role each image plays, how they combine,
and what happens in the frame.

Recommended practice: first confirm with the user what each image is (person? clothing? scene? object?
style?), then write that information into the prompt.

```
✅ The girl in the first image wears the red dress from the second image and slowly walks on the seaside
   wooden boardwalk in the third image, backlit by sunset, with the camera slowly panning right
✅ Let the cat from image one sit on the sofa from image two and yawn, warm indoor lighting, static camera
❌ @1 wears @2 and walks in @3               <- Reference syntax is not supported
❌ Generate a nice-looking video             <- Does not clarify the relationship between the reference images
```

Do not exceed `prompt_limit_length`. The model's `prompt_hint` is upstream guidance on prompt writing;
`prompt_guide_url` is the upstream prompt guide page. You may paraphrase them for the user, but do not
open the page on the user's behalf.

## Displaying the Artifact

The finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files from
these domains**; if you paste the URL directly, the user cannot open it.

Use a task-isolated working directory by convention (do not pollute the user's repository):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-r2v/<task_id>"
mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/result.mp4" "<video_url>"
```

Videos cannot be embedded for display. Provide the local absolute path, and also include the original
remote URL so the user can save it themselves. If download fails (non-200 / empty file), clearly state
"preview download failed" and provide the remote URL; do not falsely claim it was displayed.

## Step 0: Confirm Service Binding, Login, and Credit Balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Verify that the returned `brand` must be **Enkio**; if not, it means the call is connected to the wrong
  service. Stop immediately and tell the user.

The returned `credit` is the current credit balance. Record it so you can compare it with the estimated
cost in Step 2.

**Membership check (required).** Creating tasks with `i2v_create_task` 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: Choose a Model

```
i2v_list_models(kind="reference")
-> { kind, count, models: [ { model, model_name, model_desc, qualities, durations_sec,
                              modes, ratios, default_ratio, movement_amplitudes,
                              min_image_count, max_image_count,
                              prompt_limit_length, prompt_hint, prompt_guide_url,
                              combinations, ... } ] }
```

`models[].model` is the model identifier; use it in all subsequent calls. Briefly list the available
models for the user, including each model's supported resolutions, durations, modes, and **how many
reference images it needs**, and let the user choose. If the user has no preference, choose a cost-effective
default combination from `combinations` and explain why.

`combinations` directly gives the credit cost for each "mode + quality + duration" combination. Prefer it
when choosing parameters.

## Step 2: Set Parameters, Image Count, and Quote

```
i2v_get_options(model, kind="reference", quality?, duration?, mode?, ratio?)
-> { kind, quality, duration_sec, mode, ratio, credit_cost,
    image_count: { min, max }, image_role, crop,
    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url }
```

If parameters are omitted, they fall back to model defaults. The returned object explicitly states the final
effective values.

After you get `image_count`, **first align with the user on which images to submit and what each one
represents**, then decide how to write the prompt. If the user provided fewer images than `min`, do not
pad with filler images; directly explain how many images the model requires at minimum.

**Tell the user both `credit_cost` and the `credit` balance from Step 0, and wait for
confirmation**. If the balance is insufficient, prompt the user to recharge first (see
references/credits.md for the recharge link and steps); do not force submission.

## Step 3: Crop Each Reference Image Locally

The `crop` field gives the target ratio and pixel dimensions:

```
crop = { ratio, crop_required, target_width, target_height, strategy, hint }
```

If `crop_required` is `false` (the ratio is `free`), skip this step and upload the original images directly.
Otherwise, **every reference image** must first be center-cropped to the target aspect ratio, then scaled to
`target_width x target_height`:

```bash
W=<target_width>; H=<target_height>
i=1
for SRC in "<reference image 1>" "<reference image 2>" "<reference image 3>"; do
  ffmpeg -y -i "$SRC" \
    -vf "crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H" \
    "$WORKDIR/ref$i.jpg"
  i=$((i+1))
done
```

If ffmpeg is unavailable, use macOS built-in `sips` (note that `--cropToHeightWidth` takes **height
before width**):

```bash
cp "<reference image 1>" "$WORKDIR/ref1.jpg"
sips --cropToHeightWidth "$H" "$W" "$WORKDIR/ref1.jpg" >/dev/null
sips --resampleHeightWidth "$H" "$W" "$WORKDIR/ref1.jpg" >/dev/null
```

After cropping, confirm that every output file exists and has the correct dimensions
(`sips -g pixelWidth -g pixelHeight`) before moving to the next step. **Keep the order**: the order of
`ref1/ref2/ref3` is the order of `image_urls` during submission.

## Step 4: Upload Each Image to Get URLs

The upload interface accepts only one file at a time. **Call `create_upload_url` separately for each
reference image**:

```
create_upload_url() -> { upload_url, headers }
```

```bash
curl -sS -X POST "<upload_url>" -F "file=@$WORKDIR/ref1.jpg" -H "X-Client-Sn: <value from headers>"
# -> {"c":200,"m":"Success","d":"https://.../ref1.jpg"}
```

The `d` in the response is the image URL. `c != 200` means failure; report `m` to the user.
**Collect these URLs in reference-image order**; if the order is wrong, the visual composition relationship
will be wrong. Uploaded files are **temporary storage and will be cleaned periodically**; submit the task
as soon as you get the URLs.

## Step 5: Create the Task (Charges Credits)

```
i2v_create_task(model, kind="reference", image_urls=[<URL1>, <URL2>, ...], prompt,
                ratio?, quality?, duration?, mode?, movement_amplitude?)
-> { task_id, task_status, kind, image_count, credit_cost, quality, duration_sec, mode, ratio }
```

- `kind` must be `"reference"`.
- Pass `image_urls` in **reference image 1/2/3 order**, with the count inside the `image_count` range from
  Step 2.
- `prompt` is **required**; see "How to Write Prompts".
- `ratio` must **stay consistent** with the ratio used for cropping in Step 3.
- Parameters must match the set confirmed during the quote in Step 2, otherwise the actual charge may not
  match the quote.
- The returned `end_frame` is always `false`--reference-image-to-video has no first/end frame concept, so
  ignore this field.

## Step 6: Poll

```
i2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }
```

The query interface is shared with image-to-video; there is no need to pass `kind`.

- `task_status == "success"`: `video_url` is the finished video; proceed to Step 7.
- `task_status == "fail"`: relay `task_reason` to the user, and ask whether to adjust
  parameters and retry or give up. Retrying re-bills at the normal price (failed credits are
  refunded automatically); this was already disclosed up front, so you do not need to reconfirm
  the price.
- Other values: the task is queued or generating. Wait 10 seconds, query again, and briefly tell the user
  progress.

## Step 7: Download and Deliver

Download `video_url` to `$WORKDIR/result.mp4` according to "Displaying the Artifact", provide the local
path + original URL, and remind the user: the remote link points to temporary storage and will be cleaned;
the local file is also under the system temporary directory and may be reclaimed by the system. The user
should save it to their own directory as soon as possible.

It is normal for the finished video to differ significantly from the reference images (this mode is
"reference", not "reproduction"). If the user is dissatisfied, first suggest **rewriting the prompt to make
the reference relationship more specific**, rather than immediately switching models and retrying.

## Error Handling

For login, connection, and service-binding issues, see `references/auth.md` (**when not logged in, the
entire MCP namespace will not appear**; do not misdiagnose it as the plugin not installed, and do not switch
to another brand's MCP). For common error codes and remedies, see `references/errors.md`; for credits and
billing rules, see `references/credits.md`; for each tool's returned field structures, see
`references/workflow.md`.

Referenced files: 4 — file references are metadata, not package contents.

text-to-video13.7 KB

View saved version →

---
name: text-to-video
description: Generate an AI video directly from a text prompt (Enkio / enkiomv.ai). Use this when the user has no source image and wants a video based only on a written description, says text-to-video / text generated video / text to video / AI generate a video clip, or asks which text-to-video models are supported, how many credits it costs, or how long the output can be. If there is an input image and the user wants to animate it, use the enkio:image-to-video skill instead; if multiple reference images should be combined, use the enkio:reference-to-video skill instead; if the transition must be fixed by a first frame + last frame, use the enkio:first-end-frame-video skill instead. The whole workflow is completed through the enkio MCP service.
---

# Text-to-video

Call enkiomv.ai's text-to-video capability through the `enkio` MCP service: **no input image is
required**. Provide only a prompt plus parameters such as quality, duration, and aspect ratio, and
the model directly generates a brand-new video.

## Service binding

All capabilities in this skill come from the single `enkio` MCP server, which **must not be
replaced**:

- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and
  tool names have no prefix. Every tool name below (such as `get_user_profile`) refers to the tool of
  the same name under the `mcp__enkio` namespace.
- **If the `mcp__enkio` namespace is not visible, the first judgment is "not logged in", not "plugin
  not installed"**: an MCP server that has not completed OAuth will not register its entire namespace.
  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`
  authorization URL it prints, and give the user only that link to click -- do not lead with the
  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has
  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and
  explain that after login they must open a new conversation for it to take effect.
- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and
  `mcp__enkio` are two separate services, accounts, and credit pools; cross-use will charge the
  wrong account for real). Also do not mix in a `task_id` / `job_id`, credit balance, or artifact URL
  obtained elsewhere.
- When you need to explain which service this skill is connected to, rely on the `brand` /
  `brand_website` returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this
  plugin's `.mcp.json`. Do not answer from memory or guesswork; if `brand` is not Enkio, stop
  immediately and report an error.

The essential difference from the other three video skills: those three all start from images;
this skill **has no asset upload and no cropping step**. The prompt is the only content input.

Tasks are **asynchronous**: `t2v_create_task` immediately returns a `task_id`, and you must poll
`t2v_get_task` yourself.

```
0 Log in / check balance -> 1 Choose model -> 2 Set parameters and quote (confirm before charging)
-> 3 Create task (charges credits) -> 4 Poll -> 5 Download, preview, and deliver
```

## Hard constraints

- **This skill uses its own independent `t2v_*` tools. Do not mix them with `i2v_*` tools**. The
  text-to-video model list comes from a different upstream field. Passing an image-to-video model
  name into `t2v_*` reports "nonexistent text-to-video model", and vice versa.
- **Creating a task charges credits. Before submitting, you must tell the user the cost and obtain
  explicit confirmation**. All query tools are free.
- **`prompt` is required** and is the only content input for this mode. Empty or whitespace-only
  prompts are rejected directly. Prompt quality almost determines output quality, so it must be
  specific. See "How to write prompts" below.
- **`ratio` must be a concrete aspect ratio (such as `16:9` / `9:16` / `1:1`), not `free`**.
  There is no input image from which the canvas can be inferred, so the server cannot decide for
  you. If omitted, it falls back to the model's default ratio, but **you should proactively confirm
  landscape vs. portrait with the user**.
- **Do not call `create_upload_url`, and do not perform any cropping**. Text-to-video does not
  accept assets. Even if the user provides images, they are not usable for this mode--that request
  should use `enkio:image-to-video` or `enkio:reference-to-video` instead.
- **Do not construct or guess `user_id`, `example`, signatures, or similar parameters**. The server
  already handles them, and they do not exist in the tool inputs.
- Allowed values for `quality` / `duration` / `mode` **must come from `t2v_list_models`**, and the
  four dimensions must form a combination that appears in `combinations`.
- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,
  give the user brief progress updates; do not wait silently for a long time.
- If a task's `task_status` is `fail`, do not retry blindly. First tell the user the
  `task_reason`, then ask what to do. Retrying re-submits the task at the normal price--failed
  credits are refunded automatically, and this billing rule was already disclosed when quoting
  the cost, so no new price confirmation is needed here.
- **Before showing a video, you must download it locally first**. Pasting the remote URL directly
  cannot be previewed. See "Showing artifacts".

## How to write prompts

Text-to-video has **no visual reference at all**; the model can understand the scene only from the
text. If the prompt lacks information, the result will be very random. Therefore the prompt should
cover **subject + action + scene + camera + lighting/style**.

```
✅ An orange cat sits beside a neon street on a rainy night and yawns; the wet ground reflects the
   sign lights, the camera slowly pushes in from the side, cool tones, cinematic feel
✅ An aerial view sweeps over an autumn valley; golden forests ripple in the wind, morning fog has
   not yet dispersed, and the camera keeps tracking forward
❌ A cat                              <- Only the subject; action, scene, and camera are all left for the model to guess
❌ Generate a beautiful video          <- No executable information at all
```

If the user's description is too brief, **help fill it out first and then confirm**. Do not submit
with a single vague sentence--one submission is one charge. You may proactively ask: what is the
subject, what is it doing, what is the scene, what camera movement and mood are desired?

The prompt length must not exceed `prompt_limit_length`. The model's `prompt_hint` is the upstream
prompt-writing hint, and `prompt_guide_url` is the upstream prompt guide page. You may summarize
these for the user, but do not open the page on the user's behalf.

The aspect ratio should match the content: portrait (`9:16`) fits character close-ups and short-form
videos; landscape (`16:9`) fits scenery and cinematic shots.

## Showing artifacts

The finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files
from these domains**; if you paste the URL directly, the user cannot open it.

Use a task-isolated working directory (so the user's repository is not polluted):

```bash
WORKDIR="${TMPDIR:-/tmp}/enkio-t2v/<task_id>"
mkdir -p "$WORKDIR"
curl -sS -L -o "$WORKDIR/result.mp4" "<video_url>"
```

Videos cannot be embedded for preview. Give the absolute local path and also include the original
remote URL so the user can save it themselves. If the download fails (non-200 / empty file), clearly
state "preview download failed" and provide the remote URL; do not falsely claim that it was shown.

## Step 0: Confirm service binding, login, and credit balance

**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and
do not switch to another MCP. Tell the user that `enkio` is not logged in, then run
`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and
hand the user only that link to click (do not lead with the unreliable
`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that
**after login they must open a new Codex conversation** for it to take effect (the tool table in the
current conversation will not hot-refresh).

After the namespace is ready, call `get_user_profile()`:

- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then
  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same
  way as above (not the `codex://` deep link), and again they need to open a new conversation. See
  `references/auth.md`.
- Verify that the returned `brand` must be **Enkio**. If it is not, the call is connected to the
  wrong service; stop immediately and tell the user.

Record the returned `credit` as the current credit balance, and compare it with the estimated cost
when quoting in Step 2.

**Membership check (required).** Creating tasks with `t2v_create_task` 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: Choose a model

```
t2v_list_models()
-> { count, models: [ { model, model_name, model_desc, qualities, durations_sec,
                       modes, ratios, default_ratio, movement_amplitudes, supports_audio,
                       prompt_limit_length, prompt_hint, prompt_guide_url,
                       combinations, ... } ] }
```

`models[].model` is the model identifier; all later calls use it. Briefly list the available models
for the user together with each model's supported resolutions, durations, modes, and aspect ratios,
and let the user choose. If the user has no preference, choose a cost-effective default combination
from `combinations` and explain why.

`combinations` directly provides the credit cost for each "mode + quality + duration" combination;
prioritize it when choosing parameters.

It is normal that the response **does not contain any image-related fields** (image count, crop,
first/last frame).

## Step 2: Set parameters and quote

```
t2v_get_options(model, quality?, duration?, mode?, audio?, ratio?)
-> { model, model_name, quality, duration_sec, mode, audio, ratio, credit_cost,
    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url, next_step }
```

Omitted parameters fall back to the model defaults, and the response explicitly states the final
effective values.

- Passing `free` or a value unsupported by the model for `ratio` reports an error directly. If it is
  omitted, the model default ratio is used, but **landscape vs. portrait has a major impact on the
  finished video, so proactively ask the user**.
- `duration_sec` is the actual effective duration and is strongly tied to credits.

**Tell the user both `credit_cost` and the Step 0 `credit` balance, then wait for confirmation**. If
the balance is insufficient, prompt the user to recharge first (see references/credits.md for the
recharge link and steps); do not force submission. This step is also when the prompt should be
finalized--confirm parameters and prompt together to avoid back-and-forth changes.

## Step 3: Create the task (charges credits)

```
t2v_create_task(model, prompt, ratio?, quality?, duration?, mode?, audio?, movement_amplitude?)
-> { task_id, task_status, model, quality, duration_sec, mode, ratio, credit_cost }
```

- `prompt` is **required**. See "How to write prompts" for wording.
- Use the `ratio` confirmed in Step 2; it must be a concrete aspect ratio.
- Parameters must match the set confirmed during the Step 2 quote, otherwise the actual charge may
  not match the quote.
- **Do not pass `image_urls`**--that parameter does not exist on `t2v_create_task`.

## Step 4: Poll

```
t2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }
```

- `task_status == "success"`: `video_url` is the finished video; proceed to Step 5.
- `task_status == "fail"`: relay `task_reason` to the user, then ask whether to adjust the
  prompt and retry or give up. Retrying re-bills at the normal price (failed credits are
  refunded automatically); this was already disclosed up front, so you do not need to reconfirm
  the price.
- Any other value: queued or generating; wait 10 seconds, query again, and briefly update the user.

## Step 5: Download and deliver

Following "Showing artifacts", download `video_url` to `$WORKDIR/result.mp4`, provide the local path
+ original URL, and remind the user: the remote link points to temporary storage and may be cleaned
up, and the local file under the system temporary directory may also be reclaimed by the system. The
user should save it to their own directory as soon as possible.

Different generations from the same prompt will differ; this is normal. If the user is dissatisfied,
prefer recommending **making the prompt more specific** (add subject details, camera movement,
lighting, and mood) rather than immediately switching models and retrying.

## Error handling

For login, connection, and service binding issues, see `references/auth.md` (**when not logged in,
the entire MCP namespace will not appear**; do not misdiagnose this as the plugin not being
installed, and do not switch to another brand's MCP). See `references/errors.md` for common error
codes and handling; see `references/credits.md` for credits and billing rules; see
`references/workflow.md` for each tool's response field structure.

Referenced files: 4 — file references are metadata, not package contents.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Enkio
Keywords
See keywords

Declared capabilities

  • Interactive
  • Read
  • Write

Package observed Nov 3, 2026.

Technical details
First seen
Oct 24, 2026 · 12:40 UTC
Last seen
Nov 3, 2026 · 18:00 UTC
Latest observed change
Oct 26, 2026 · 06:08 UTC
Collection status
Collected

plugin_asdk_app_6aba19886fd8819190c14403ef902f5c

Download plugin data (JSON)