XinYu.
Navigation
Developers
MCPCLI
Language
CLI

XinYu AI Command-Line Tool

Generate images, video, audio, and text from your terminal or CI — and tidy your canvases — on your own account and balance. One binary, xinyu, with a built-in MCP server (xinyu mcp).

Overview

The xinyu CLI is a thin wrapper over the XinYu AI generation API, authenticated with a user-level API key. Pricing is identical to the web app. Ideal for scripts, automation, and CI pipelines.

Pipe-friendly

--json goes to stdout, progress to stderr — pipe straight into jq.

Async, never lost

Generation is async; even if the wait times out you can retrieve it with job wait / job get.

Built-in MCP

xinyu mcp runs as an MCP server for agents.

Prerequisites: Node.js 18+ and a XinYu AI account.

Get an API Key

1

Log in to XinYu AI

Visit xinyuai.app and sign in to your account.
2

Open Settings → Developer API Keys

Click your avatar at the top right and choose Settings, then find "Developer API Keys" further down the page.
3

Create & copy the key

Enter a name for the key and click "Create key". The plaintext key (xys_live_...) is shown only once — copy it immediately. Want a script that can look things up but never spend Xins? Check "Read-only key (query only, cannot generate)" before creating.
An API key carries your account permissions and can spend your Xins. Never commit it or share it publicly. If leaked, revoke it immediately in the same place.

Install

bash
# Install the `xinyu` command globally
npm install -g @xinyuai/cli

# …or run any command without installing:
npx @xinyuai/cli <command>
Requires Node.js 18+. After installing, the xinyu command is available globally.

Log in

Login validates the key against the server and stores the credential in ~/.xinyu/credential.json (chmod 600).

bash
# Pass --key directly, or omit it to be prompted
xinyu login --key xys_live_xxxxxxxxxxxx --base-url https://xinyuai.app

You can skip login and use the env vars XINYU_API_KEY / XINYU_BASE_URL instead (they take precedence — handy in CI).

Commands

Account & models

xinyu loginSave & validate your API key
xinyu logoutRemove the stored credential
xinyu whoamiShow the current login target
xinyu balanceShow your Xins balance
xinyu model listList models (filter by type)
xinyu pricePrice an image generation before running it (images only) — the same function that bills

Projects & files

xinyu project listList my projects (canvases) for a --project id
xinyu project createCreate a new empty canvas, returns its id
xinyu project assetsSearch / list the assets already on a canvas, with reusable URLs (-q searches title and full prompt)
xinyu project readCanvas overview: node / edge totals and counts per type
xinyu project arrangeTidy the canvas: grid-pack loose content nodes
xinyu uploadUpload a local image / video / audio file and print a URL usable for generation (--place also puts it on the canvas)

Generate & edit

xinyu generate imageText-to-image / image-to-image
xinyu generate videoText-to-video / image-to-video / reference-to-video
xinyu generate finalRender the 1080p final of a Seedance 2.5 draft
xinyu generate audioText-to-speech, or Seed Audio
xinyu generate textRun a text LLM
xinyu generate enhanceUpscale & enhance an image (Topaz)
xinyu generate rembgRemove the background (transparent PNG)
xinyu generate outpaintOutpaint: expand an image by a number of pixels on any side
xinyu generate image-editEdit an image with a text instruction (redraw or erase)
xinyu generate video-editEdit a video with a text instruction (Kling O3; source at least 720px tall)
xinyu generate video-actionUpscale or extend a Grok video you generated earlier

Canvas nodes

xinyu node renameSet a canvas node's title
xinyu node connectDraw a reference edge between two nodes
xinyu node disconnectRemove a reference edge between nodes
xinyu node deleteDelete nodes and their edges (irreversible; finished or generating nodes need a --confirm-* flag)
xinyu node set-paramsChange a node's generation params in place (draft only — no regeneration, no Xins spent)

Jobs & MCP

xinyu job getGet a job's status & assets
xinyu job waitWait until a job finishes — the way to recover a result after a wait timeout
xinyu job listList recent jobs (filter by status / canvas)
xinyu mcpRun the built-in MCP server

Common flags

bash
xinyu login [--key <key>] [--base-url <url>]
xinyu logout
xinyu whoami
xinyu balance [--json]
xinyu model list [--type IMAGE|VIDEO|AUDIO] [--json]
xinyu price --model <m> [--size <s>] [--count <n>] [--refs <n>] [--json]

xinyu project list    [--search <text>] [--limit <n>] [--json]
xinyu project create  --name <name> [--description <text>] [--json]
xinyu project assets  <projectId> [-q <text>] [--type IMAGE|VIDEO|AUDIO]
                      [--page <n>] [--limit <n>] [--json]
xinyu project read    <projectId> [--limit <n>] [--json]
xinyu project arrange <projectId> [--columns <n>] [--gap <n>] [--json]
xinyu upload <file> [--project <id>] [--place] [--json]

xinyu generate image --prompt <p> --project <id> [--model <m>] [--aspect <r>]
                     [--size <s>] [--ref <url...>] [--count <n>] [--x <n>] [--y <n>]
                     [--no-place-on-canvas] [--no-wait] [--timeout <s>] [--json]
xinyu generate video --prompt <p> --project <id> [--model <m>] [--duration <s>]
                     [--resolution <r>] [--audio] [--start-image <url>] [--end-image <url>]
                     [--element-image <url...>] [--ref-video <url...>] [--ref-audio <url...>]
                     [--draft] [--x <n>] [--y <n>] [--no-place-on-canvas]
                     [--no-wait] [--timeout <s>] [--json]
xinyu generate final <draftJobId> --project <id> [--resolution <r>]
                     [--no-wait] [--timeout <s>] [--json]
xinyu generate audio --text <t> --project <id> [--model <m>] [--voice <v>] [--no-wait] [--json]
xinyu generate text  --prompt <p> [--model <m>] [--media <url...>] [--project <id>] [--json]

xinyu generate enhance      --image <url> --project <id> [--upscale-factor <n>]
                            [--no-face-enhancement]
xinyu generate rembg        --image <url> --project <id> [--mask]
xinyu generate outpaint     --image <url> --project <id> [--top <n>] [--right <n>]
                            [--bottom <n>] [--left <n>]
xinyu generate image-edit   --prompt <t> --image <url> --project <id> [--model <m>] [--mode <m>]
xinyu generate video-edit   --prompt <t> --video <url> --project <id>
                            [--duration <s>] [--keep-audio]
xinyu generate video-action --action <a> --source-task-id <id> --project <id>
                            [--extend-times <n>]

xinyu node rename <nodeId> --project <id> --title <title>
xinyu node connect <sourceId> <targetId> --project <id>
xinyu node disconnect <sourceId> <targetId> --project <id>
xinyu node delete <nodeId...> --project <id> [--confirm-finished] [--confirm-running]
xinyu node set-params <nodeId> --project <id> --set <key=value...>

xinyu job get  <jobId> [--json]
xinyu job wait <jobId> [--timeout <s>] [--json]
xinyu job list [--status <s>] [--project <id>] [--limit <n>] [--json]

xinyu mcp

# --project is required for every generate command except `generate text`:
# every result belongs to a canvas. Get an id with `xinyu project list`
# or `xinyu project create`. Run `xinyu <command> --help` for every flag.
# Valid values for --size / --duration / --resolution depend on the model:
# see `xinyu model list --json`.

Examples

bash
# Create (or pick) a canvas first — every generation needs one
PID=$(xinyu project create --name "My Canvas" --json | jq -r '.id')

# Ask what an image would cost before spending anything
xinyu price --model nano-banana-2 --size 2K --count 2

# Grab a generated image URL in CI (clean JSON on stdout)
URL=$(xinyu generate image --prompt "a beach at sunset" \
        --model nano-banana-2 --size 2K --project "$PID" --json | jq -r '.assets[0]')

# Upload a local image, then animate it as the first frame
IMG=$(xinyu upload ./character.png)
xinyu generate video --prompt "she turns and smiles" --model seedance-2 \
        --start-image "$IMG" --duration 5 --project "$PID"

# Lost the id after a timeout? Find the job, then wait for it
xinyu job list --status RUNNING --project "$PID"
xinyu job wait <jobId>

# Ask an LLM
xinyu generate text --prompt "summarize MCP in one sentence"
Generation commands wait for the job and print the asset URL(s) to stdout by default; add --no-wait to return the jobId immediately, then fetch the result with xinyu job wait or xinyu job get. generate can be shortened to gen, and project can be written as canvas. The node commands (rename / connect / disconnect / delete / set-params) work on personal canvases only — team canvases are refused.

Async & Timeouts (no result is ever lost)

Generation runs asynchronously on the platform, fully decoupled from whether the CLI is still waiting. --timeout only controls how long the CLI waits locally: 300s by default for image and audio commands, 2400s (40 min) for the video commands (generate video / final / video-edit / video-action), and 600s for job wait. The platform fails and refunds any job that produces nothing for about 60 minutes, so setting --timeout up to 3600s (60 min) is enough.

bash
$ xinyu generate video --prompt "..." --model seedance-2 --project "$PID" --timeout 1200
Job 7f3a… queued (40 Xins) — waiting...
Stopped waiting after 1200s — the job is STILL RUNNING and you have already paid 40 Xins for it.
Do not run the generate command again; resume it instead:
  xinyu job wait 7f3a…          # blocks until it finishes
  xinyu job list --status RUNNING  # if you lost the id

A wait timeout is not an error: the CLI prints the jobId and how to resume, then exits, while the job keeps running server-side. Keep waiting with xinyu job wait, check once with xinyu job get, or find a lost id with xinyu job list --status RUNNING. When it finishes, the asset is saved to your account (and into the canvas project if you passed --project). Billing is charged at creation and auto-refunded if the job fails; a job that produces nothing for a long time (about 60 minutes or more) is also failed and refunded automatically — so you're never double-charged and never lose a successful result. Please don't re-run the generate command just because a wait timed out.

Use as an MCP server

xinyu mcp starts a stdio MCP server using your stored credential, exposing every tool listed on the MCP page (generation, editing, jobs, canvas reading and editing) to any MCP client.

json
{
  "mcpServers": {
    "xinyu": {
      "command": "xinyu",
      "args": ["mcp"]
    }
  }
}

For the full MCP connection guide, see the MCP guide.

FAQ