by jieshuo-ai
AI Agent skill for narrator-ai-cli — CLI client for Narrator AI video narration API
# Add to your Claude Code skills
git clone https://github.com/jieshuo-ai/narrator-ai-cli-skillname: narrator-ai-cli version: "1.0.1" license: MIT description: >- Create AI-narrated film/drama commentary videos via CLI. Two workflow paths (Original & Adapted narration), 93 movies, 146 BGM tracks, 63 dubbing voices in 11 languages, 90+ narration templates. Use when creating narration videos, film commentary, short drama dubbing, or video production. user-invocable: true tags:
CLI client for Narrator AI video narration API. Designed for AI Agents and developers.
CLI Repo: https://github.com/jieshuo-ai/narrator-ai-cli Resources Preview: https://ceex7z9m67.feishu.cn/wiki/WLPnwBysairenFkZDbicZOfKnbc
# From GitHub release (recommended — pinned to a specific version)
pip install "narrator-ai-cli @ https://github.com/jieshuo-ai/narrator-ai-cli/archive/refs/tags/v1.0.0.zip"
# Or from GitHub latest (tracks main branch)
pip install "narrator-ai-cli @ git+https://github.com/jieshuo-ai/narrator-ai-cli.git"
# Or clone + editable install
git clone https://github.com/jieshuo-ai/narrator-ai-cli.git
cd narrator-ai-cli && pip install -e .
Requires Python 3.10+. Dependencies: typer, httpx[socks], httpx-sse, pyyaml, rich.
# Interactive setup (server URL + API key)
narrator-ai-cli config init
# Or set directly
narrator-ai-cli config set app_key <your_app_key>
# No API key yet? Contact support: WeChat `gezimufeng` or email merlinyang@gridltd.com
# Verify
narrator-ai-cli config show
narrator-ai-cli user balance
Config stored at ~/.narrator-ai/config.yaml (permissions 0600).
Server defaults to https://openapi.jieshuo.cn.
Install this Skill in your AI agent (OpenClaw, Windsurf, WorkBuddy, etc.), then just say "create a movie narration video" — the AI handles the rest.
A machine-readable skill file (SKILL.md) that teaches AI agents how to use the narrator-ai-cli tool for automated video narration production.
You say: "Create a narration video for Pegasus in a comedy style"
AI executes: Search movie → Select template → Choose BGM → Pick voice → Generate script → Compose video → Return download link
| | CLI (command-line tool) | Skill (capability description) | |---|---|---| | What it is | A set of executable commands | Instructions that teach AI how to use those commands | | Analogy | Kitchen tools | A recipe book | | Works alone? | Yes, in terminal manually | No, requires CLI |
In short: CLI is the hands. Skill is the brain. Together, the AI agent can produce videos end-to-end.
pip install "narrator-ai-cli @ git+https://github.com/jieshuo-ai/narrator-ai-cli.git"
See narrator-ai-cli for detailed installation options.
narrator-ai-cli config set app_key <your_app_key>
📧 Need an API key? Email or scan the QR code at the bottom of this page.
No comments yet. Be the first to share your thoughts!
Environment variable overrides (take precedence over config file):
| Variable | Description | Default |
|----------|-------------|---------|
| NARRATOR_SERVER | API server URL | https://openapi.jieshuo.cn |
| NARRATOR_APP_KEY | API key | (from config) |
| NARRATOR_TIMEOUT | Request timeout in seconds | 30 |
src/narrator_ai/
├── cli.py # Typer main entry point, 7 sub-command groups
├── client.py # httpx client: GET/POST/DELETE/SSE/upload, auto auth via app-key header
├── config.py # YAML config (~/.narrator-ai/config.yaml), env var override
├── output.py # Rich table + JSON dual output (--json flag)
├── commands/
│ ├── config_cmd.py # config init/show/set
│ ├── user.py # balance/login/keys/create-key
│ ├── task.py # 9 task types, create/query/list/budget/verify/search-movie/narration-styles/templates/get-writing/save-writing/save-clip
│ ├── file.py # 3-step upload (presigned URL → OSS PUT → callback), download/list/info/storage/delete
│ ├── materials.py # 93 pre-built movies (--genre, --search filters)
│ ├── bgm.py # 146 BGM tracks (--search filter)
│ └── dubbing.py # 63 voices, 11 languages (--lang, --tag, --search filters)
└── models/
└── responses.py # API response codes (SUCCESS=10000, FAILED=10001, etc.) + task status constants
Key design choices:
--json for machine-readable output (always use when parsing programmatically)-d '{"key": "value"}' or -d @file.jsonapp-key header (not Bearer token)--stream)| Concept | Description |
|---------|-------------|
| file_id | UUID for uploaded files. Via file upload or task results |
| task_id | UUID returned on task creation. Poll with task query |
| task_order_num | Assigned after task creation. Used as order_num for downstream tasks |
| file_ids | Output file IDs in completed task results. Input for next steps |
| learning_model_id | Narration style model. From popular-learning OR pre-built template (90+) |
| learning_srt | Reference SRT file_id. Only needed when NOT using learning_model_id |
popular-learning → generate-writing → clip-data → video-composing → magic-video(optional)
search-movie → fast-writing → fast-clip-data → video-composing → magic-video(optional)
| Mode | Name | Required Input |
|------|------|----------------|
| "1" | 热门影视 (Hot Drama) | confirmed_movie_json from search-movie |
| "2" | 原声混剪 (Original Mix) | episodes_data[{srt_oss_key, num}] |
| "3" | 冷门/新剧 (New Drama) | episodes_data[{srt_oss_key, num}] |
Before creating any task, gather these resources first.
# Option A: Pre-built materials (93 movies, recommended)
narrator-ai-cli material list --json
narrator-ai-cli material list --search "飞驰人生" --json
narrator-ai-cli material list --genre 喜剧片 --json
narrator-ai-cli material genres --json
# Returns: video_id (= video_oss_key & negative_oss_key), srt_id (= srt_oss_key)
# Option B: Upload your own
narrator-ai-cli file upload ./movie.mp4 --json # Returns file_id
narrator-ai-cli file upload ./subtitles.srt --json
narrator-ai-cli file list --json
narrator-ai-cli file transfer --link "<url>" --json # transfer by HTTP/Baidu/PikPak link
narrator-ai-cli file info <file_id> --json
narrator-ai-cli file download <file_id> --json
narrator-ai-cli file storage --json
narrator-ai-cli file delete <file_id> --json
Supported formats: .mp4, .mkv, .mov, .mp3, .m4a, .wav, .srt, .jpg, .jpeg, .png
narrator-ai-cli bgm list --json # 146 tracks
narrator-ai-cli bgm list --search "单车" --json
# Returns: id (= bgm parameter in task creation)
narrator-ai-cli dubbing list --json # 63 voices, 11 languages
narrator-ai-cli dubbing list --lang 普通话 --json
narrator-ai-cli dubbing list --tag 喜剧 --json
narrator-ai-cli dubbing languages --json
narrator-ai-cli dubbing tags --json
# Returns: id (= dubbing), type (= dubbing_type)
Languages: 普通话(39), English(4), 日语(3), 韩语(2), Spanish(3), Portuguese(2), German(2), French(2), Arabic(2), Thai(2), Indonesian(2).
narrator-ai-cli task narration-styles --json
narrator-ai-cli task narration-styles --genre 爆笑喜剧 --json
Genres: 热血动作, 烧脑悬疑, 励志成长, 爆笑喜剧, 灾难求生, 悬疑惊悚, 惊悚恐怖, 东方奇谈, 家庭伦理, 情感人生, 奇幻科幻, 传奇人物
Use learning_model_id from template directly — no need for popular-learning step.
Required for target_mode=1. Do NOT fabricate confirmed_movie_json.
narrator-ai-cli task search-movie "飞驰人生" --json
Returns up to 3 results with: title, local_title, original_title, year, director, stars, genre, summary, poster_url, is_partial.
⚠️ May take 60+ seconds (Gradio backend). Results cached 24h.
narrator-ai-cli task create fast-writing --json -d '{
"learning_model_id": "<from narration-styles>",
"target_mode": "1",
"playlet_name": "飞驰人生",
"confirmed_movie_json": <paste search-movie result>,
"model": "flash"
}'
Full parameters:
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| learning_model_id | str | One of two | - | Style model ID (from template or popular-learning) |
| learning_srt | str | One of two | - | Reference SRT file_id (when no template available) |
| target_mode | str | Yes | - | "1"=Hot Drama, "2"=Original Mix, "3"=New Drama |
| playlet_name | str | Yes | - | Movie/drama name |
| confirmed_movie_json | obj | mode=1 | - | From search-movie (MUST use search result) |
| episodes_data | list | mode=2,3 | - | [{srt_oss_key, num}] |
| model | str | No | "pro" | "pro" (higher quality, 15pts/char) or "flash" (faster, 5pts/char) |
| language | str | No | "Chinese (中文)" | Output language |
| perspective | str | No | "third_person" | "first_person" or "third_person" |
| target_character_name | str | 1st person | - | Required when perspective=first_person |
| custom_script_result_path | str | No | - | Custom script result path |
| webhook_url | str | No | - | Async callback URL |
| webhook_token | str | No | - | Callback authentication token |
| webhook_data | str | No | - | Passthrough data for callback |
Output: task_id → poll until status=2 → extract task_id + results.file_ids[0]
narrator-ai-cli task create fast-clip-data --json -d '{
"task_id": "<task_id from step 1>",
"file_id": "<results.file_ids[0] from step 1>",
"bgm": "<bgm_id>",
"dubbing": "<voice_id>",
"dubbing_type": "普通话",
"episodes_data": [{"video_oss_key": "<video_file_id>", "srt_oss_key": "<srt_file_id>", "negative_oss_key": "<video_file_id>", "num": 1}]
}'
Optional: narration_script_file, custom_cover, subtitle_style, font_path
Output: task_order_num (used as order_num in video-composing)
IMPORTANT: order_num comes from fast-clip-data (step 2).
narrator-ai-cli task create video-composing --json -d '{
"order_num": "<task_order_num from step 2>",
"bgm": "<bgm_id>",
"dubbing": "<voice_id>",
"dubbing_type": "普通话"
}'
Optional: custom_cover, subtitle_style, font_path
Output: task_id, video URLs in results
# List templates first
narrator-ai-cli task templates --json
# One-stop mode (from video-composing task_id)
narrator-ai-cli task create magic-video --json -d '{
"task_id": "<task_id from step 3>",
"template_name": ["template_name"]
}'
# Staged mode (from clip data file_id)
narrator-ai-cli task create magic-video --json -d '{
"file_id": "<file_id from step 2 results.file_ids[0]>",
"template_name": ["template_name"]
}'
Optional: template_params (per-template params dict), mode (one_stop/staged), clip_data (JSON object for staged mode)
Output: sub_tasks with rendered video URLs
narrator-ai-cli task create popular-learning --json -d '{
"video_srt_path": "<srt_file_id>",
"video_path": "<video_file_id>",
"narrator_type": "movie",
"model_version": "advanced"
}'
Output: learning_model_id (query task until status=2, extract from results)
narrator-ai-cli task create generate-writing --json -d '{
"learning_model_id": "<from step 1 or pre-built template>",
"learning_srt": "",
"native_video": "",
"native_srt": "",
"playlet_name": "Movie Name",
"playlet_num": "1",
"target_platform": "抖音",
"vendor_requirements": "",
"task_count": 1,
"target_character_name": "<main_character_name>",
"story_info": "",
"episodes_data": [{"video_oss_key": "<video_file_id>", "srt_oss_key": "<srt_file_id>", "negative_oss_key": "<video_file_id>", "num": 1}]
}'
Output: task_order_num + results.file_ids[0]
narrator-ai-cli task create clip-data --json -d '{
"order_num": "<task_order_num from step 2>",
"bgm": "<bgm_id>",
"dubbing": "<voice_id>",
"dubbing_type": "普通话"
}'
Output: file_ids[0] (for magic-video staged mode)
IMPORTANT: video-composing uses order_num from generate-writing (step 2), NOT from clip-data.
narrator-ai-cli task create voice-clone --json -d '{"audio_file_id": "<file_id>"}'
Optional: clone_model (default: pro). Output: task_id, voice_id.
narrator-ai-cli task create tts --json -d '{"voice_id": "<voice_id>", "audio_text": "Text to speak"}'
Optional: clone_model (default: pro). Output: task_id with audio result.
# Query task status (poll until status 2=success or 3=failed)
narrator-ai-cli task query <task_id> --json
# List tasks with filters
narrator-ai-cli task list --json
narrator-ai-cli task list --status 2 --type 9 --json # completed fast-writing
narrator-ai-cli task list --category commentary --json
# Estimate points cost before creating
narrator-ai-cli task budget --json -d '{
"learning_model_id": "<id>",
"native_video": "<file_id>",
"native_srt": "<file_id>"
}'
# Returns: viral_learning_points, commentary_generation_points, video_synthesis_points, visual_template_points, total_consume_points
# Verify materials before task creation
narrator-ai-cli task verify --json -d '{
"bgm": "<file_id>",
"dubing_id": "<voice_id>",
"native_video": "<file_id>",
"native_srt": "<file_id>"
}'
# Returns: is_valid (bool), errors (list), warnings (list)
# Retrieve/save narration scripts
narrator-ai-cli task get-writing --json
narrator-ai-cli task save-writing -d '{...}'
narrator-ai-cli task save-clip -d '{...}'
# List task types with details
narrator-ai-cli task types -V
Task type IDs (for --type filter):
| ID | Type | |----|------| | 1 | popular_learning | | 2 | generate_writing | | 3 | video_composing | | 4 | voice_clone | | 5 | tts | | 6 | clip_data | | 7 | magic_video | | 8 | subsync | | 9 | fast_writing | | 10 | fast_clip_data |
Task status codes: 0=init, 1=in_progress, 2=success, 3=failed, 4=cancelled.
narrator-ai-cli file upload ./video.mp4 --json # 3-step: presigned → OSS → callback
narrator-ai-cli file list --json # pagination, --search filter
narrator-ai-cli file info <file_id> --json # name, path, size, category, timestamps
narrator-ai-cli file download <file_id> --json # returns presigned URL (time-limited)
narrator-ai-cli file storage --json # used_size, max_size, usage_percentage
narrator-ai-cli file delete <file_id> --json # irreversible
File categories: 1=video, 2=audio, 3=image, 4=doc, 5=torrent, 6=other.
narrator-ai-cli user balance --json # account points balance
narrator-ai-cli user login --json # login with username/password
narrator-ai-cli user keys --json # list sub API keys
narrator-ai-cli user create-key --json # create a new sub API key
Support Contact (for balance/billing, app_key issues — including obtaining, renewing, or troubleshooting API keys): WeChat
gezimufeng, or emailmerlinyang@gridltd.com
| Code | Meaning | Action |
|------|---------|--------|
| 10000 | Success | - |
| 10001 | Failed | Check params |
| 10002 | App key expired | Contact support to renew key (see Support Contact above) |
| 10003 | Sign expired | Check timestamp |
| 10004 | Invalid app key | Run config show to verify; if incorrect, contact support to obtain a valid key (see Support Contact above) |
| 10005 | Invalid sign | Check app_key config; contact support if issue persists (see Support Contact above) |
| 10006 | Invalid timestamp | Check clock sync |
| 10007 | Not found | Check resource ID |
| 10008 | Invalid method | Check HTTP method |
| 10009 | Insufficient balance | Contact support to top up (see Support Contact above) |
| 10010 | Task not found | Verify task_id |
| 10011 | Task create failed | Retry or check params |
| 10012 | Task type not found | Use task types to list valid types |
| 10013 | Insufficient balance (key) | Contact support to top up sub-key quota (see Support Contact above) |
| 40000 | Gradio timeout | Retry (backend overloaded) |
| 50000 | Unauthorized | Check app_key config; contact support if key is missing or invalid (see Support Contact above) |
| 50001 | Database error | Retry later |
| 50002 | System busy | Retry later |
| 50003 | System error | Contact support |
| 60000 | Retryable error | Safe to retry |
CLI exits code 1 on any error, prints to stderr.
material list / file upload → video_file_id, srt_file_id
bgm list → bgm_id
dubbing list → dubbing, dubbing_type
narration-styles → learning_model_id
│
┌───────────────────┼───────────────────────┐
│ Standard Path │ Fast Path │
▼ │ ▼
popular-learning │ search-movie
OUT: learning_model_id │ OUT: confirmed_movie_json
(or use template) │ │
│ │ ▼
▼ │ fast-writing
generate-writing │ OUT: task_id, file_ids[0]
OUT: task_order_num ─┐ │ │
file_ids[0] │ │ ▼
│ │ │ fast-clip-data
▼ │ │ IN: task_id + file_id from above
clip-data │ │ OUT: task_order_num
OUT: file_ids[0] │ │ │
│ │ │ │
└─────────────────┼─┼────────────────────────┘
│ ▼
video-composing
IN: order_num (from writing step!)
bgm, dubbing, dubbing_type
OUT: task_id, video URLs
│
▼
magic-video (optional)
IN: task_id (one-stop) OR file_id (staged)
template_name (from 'task templates')
OUT: sub_tasks with rendered video URLs
search-movie before fast-writing with target_mode=1. Never fabricate confirmed_movie_json — it produces nonsensical narration.file list or material list. Never guess file_ids.task_id → poll task query <task_id> --json until status 2 (success) or 3 (failed).search-movie may take 60+ seconds (Gradio backend, cached 24h). Set adequate timeout.task narration-styles --json to list, browse https://ceex7z9m67.feishu.cn/wiki/WLPnwBysairenFkZDbicZOfKnbc for preview.-d @file.json for large request bodies to avoid shell quoting issues.task verify before creating expensive tasks to catch missing/invalid materials early.task budget to estimate points cost before committing to a task.https://openapi.jieshuo.cn (the Narrator AI service). No data is sent to any other third-party service.NARRATOR_APP_KEY) is required and stored locally at ~/.narrator-ai/config.yaml. Keep this file private and do not commit it to version control.Choose the method for your agent platform:
OpenClaw:
mkdir -p ~/.openclaw/skills/narrator-ai-cli
cp SKILL.md ~/.openclaw/skills/narrator-ai-cli/SKILL.md
WorkBuddy / QClaw (Tencent):
Upload SKILL.md through the skill management UI.
Windsurf:
cp SKILL.md /path/to/your/project/.skills/narrator-ai-cli/SKILL.md
Claude Code / Cursor:
cp SKILL.md /path/to/your/project/.skills/narrator-ai-cli/SKILL.md
Any markdown-reading agent:
cp SKILL.md /path/to/agent/skills/narrator-ai-cli/SKILL.md
💡 Tip: You can also just give the agent this repo URL — most agents can read the GitHub repo structure and auto-configure.
Once installed, use natural language:
| Platform | Setup | Status | |----------|-------|--------| | OpenClaw | Native skill loading | ✅ Verified | | Windsurf | .skills directory | ✅ Verified | | WorkBuddy (Tencent) | Upload SKILL.md | ✅ Verified | | QClaw (Tencent) | Upload SKILL.md | ✅ Verified | | Youdao Lobster | Skill loading | ✅ Verified | | Yuanqi AI | Skill loading | ✅ Verified | | Claude Code | SKILL.md in project root | ✅ Verified | | Cursor | rules/skills directory | ✅ Verified | | Any markdown-skill agent | Point to SKILL.md | ✅ Compatible |
| Feature | Details | |---------|---------| | Two workflow paths | Adapted Narration and Original Narration | | Three creation modes | Hot Drama / Original Mix / New Drama | | Built-in resources | 93 movies, 146 BGM tracks, 63 dubbing voices, 90+ narration templates | | Full pipeline | Script → Clip data → Video composing → Visual template | | Standalone tasks | Voice cloning, text-to-speech | | Data flow mapping | Which output feeds into which input | | Error handling | All 18 API error codes with recommended actions | | Cost estimation | Budget verification before task creation |
| Section | Description | |---------|-------------| | Frontmatter | Skill metadata (name, description, requirements) | | Architecture | CLI source structure and design choices | | Core Concepts | Key terms: file_id, task_id, order_num, etc. | | Workflow Paths | Two complete pipelines with step-by-step commands | | Prerequisites | How to select resources (materials, BGM, dubbing, templates) | | Fast Path | Recommended workflow: search → write → clip → compose → magic | | Standard Path | Full workflow: learn → write → clip → compose → magic | | Standalone Tasks | Voice clone and TTS | | Task Management | Query, list, budget, verify, save | | File Operations | Upload, download, list, delete | | Error Handling | All 18 API error codes with actions | | Data Flow | ASCII diagram of complete pipeline | | Important Notes | 9 critical gotchas and best practices |
Need an API key or help?

MIT