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/GridLtd-ProductDev/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.
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.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 merlinyang@gridltd.com or scan the QR code at the bottom of this page.
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
No comments yet. Be the first to share your thoughts!