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.
--json goes to stdout, progress to stderr — pipe straight into jq.
Generation is async; even if the wait times out you can retrieve it with job wait / job get.
xinyu mcp runs as an MCP server for agents.
Get an API Key
Log in to XinYu AI
Open Settings → Developer API Keys
Create & copy the key
Install
# Install the `xinyu` command globally
npm install -g @xinyuai/cli
# …or run any command without installing:
npx @xinyuai/cli <command>Log in
Login validates the key against the server and stores the credential in ~/.xinyu/credential.json (chmod 600).
# Pass --key directly, or omit it to be prompted
xinyu login --key xys_live_xxxxxxxxxxxx --base-url https://xinyuai.appYou 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 keyxinyu logoutRemove the stored credentialxinyu whoamiShow the current login targetxinyu balanceShow your Xins balancexinyu model listList models (filter by type)xinyu pricePrice an image generation before running it (images only) — the same function that billsProjects & files
xinyu project listList my projects (canvases) for a --project idxinyu project createCreate a new empty canvas, returns its idxinyu 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 typexinyu project arrangeTidy the canvas: grid-pack loose content nodesxinyu 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-imagexinyu generate videoText-to-video / image-to-video / reference-to-videoxinyu generate finalRender the 1080p final of a Seedance 2.5 draftxinyu generate audioText-to-speech, or Seed Audioxinyu generate textRun a text LLMxinyu 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 sidexinyu 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 earlierCanvas nodes
xinyu node renameSet a canvas node's titlexinyu node connectDraw a reference edge between two nodesxinyu node disconnectRemove a reference edge between nodesxinyu 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 & assetsxinyu job waitWait until a job finishes — the way to recover a result after a wait timeoutxinyu job listList recent jobs (filter by status / canvas)xinyu mcpRun the built-in MCP serverCommon flags
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
# 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"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.
$ 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 idA 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.
{
"mcpServers": {
"xinyu": {
"command": "xinyu",
"args": ["mcp"]
}
}
}For the full MCP connection guide, see the MCP guide.