
Skywork Music Maker
- 309 installs
- 196 repo stars
- Updated April 2, 2026
- skyworkai/skywork-skills
skywork-music-maker is a Claude Code skill that generates music loops, stems, or full tracks via Skywork agent workflows with style prompts, structure control, and export for developers who need audio assets for apps or
About
skywork-music-maker is a generative audio skill from skyworkai/skywork-skills that uses Skywork agent workflows to create music content. It supports generating loops, individual stems, or full tracks from style prompts with structure control, then exports assets ready for apps, demos, or marketing campaigns. Developers reach for skywork-music-maker when a product needs background music, app soundtracks, or campaign audio and they want agent-driven generation instead of licensing stock tracks or building a separate audio pipeline.
- prompted music generation
- loop and stem exports
- genre and mood control
- iterative refinement
- agent media pipelines
Skywork Music Maker by the numbers
- 309 all-time installs (skills.sh)
- +9 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #506 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/skyworkai/skywork-skills --skill skywork-music-makerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 309 |
|---|---|
| repo stars | ★ 196 |
| Last updated | April 2, 2026 |
| Repository | skyworkai/skywork-skills ↗ |
How do you generate music assets for apps with AI?
Generate music loops, stems, or full tracks via Skywork agent workflows with style prompts, structure control, and export for apps or campaigns.
Who is it for?
Developers and creators building apps, demos, or campaigns who need custom music loops or tracks generated through Skywork agent workflows with exportable audio files.
Skip if: Professional DAW production workflows, voice-over generation, or teams requiring licensed commercial music with legal clearance documentation.
When should I use this skill?
User asks to generate music loops, stems, tracks, background audio, or campaign soundtracks via Skywork workflows.
What you get
Exported music loops, stems, or full tracks with style-controlled structure ready for app or campaign use
- Music loops
- Audio stems
- Full track exports
By the numbers
- Supports 3 output modes: loops, stems, and full tracks
Files
Skywork Music Maker (Mureka API)
Generate professional-quality music using the Mureka API at https://api.mureka.ai. This skill covers the complete music production workflow: lyrics writing → song/instrumental generation.
First-Time Setup
Before running any API command, check if MUREKA_API_KEY is set. If not, guide the user to get an API key at https://platform.mureka.ai/ (register → API Keys → generate key → export MUREKA_API_KEY="..."), then STOP — do not attempt any API calls until the key is configured.
---
Smart Prompt Conversion (CRITICAL WORKFLOW)
Default behavior: When the user doesn't specify song type, always generate a song with lyrics (use mureka.py song). Only use mureka.py instrumental when the user explicitly asks for instrumental, BGM, background music, or "no vocals".
Output defaults: Use mp3 format unless the user requests otherwise. The --output flag specifies a directory — the script creates it and saves all results inside (audio files + lyrics.txt for songs). If the user doesn't specify a location, choose a user-friendly path with a descriptive folder name based on the song theme (e.g., summer_pop_song/).
When users provide music descriptions in natural language (in any language), you MUST convert them to structured Mureka API prompts using this workflow:
Conversion Process
User Input Examples:
- "upbeat pop song, female vocals, guitar, perfect for summer"
- "sad piano ballad about lost love"
- "epic orchestral music for a fantasy game"
- "traditional Chinese music with bamboo flute and zither, misty atmosphere"
Your Task: 1. Extract structured parameters using the extraction rules below 2. Validate the prompt meets quality standards (see Quality Checklist) 3. Present to user for confirmation before generating 4. Run the generation command with the structured prompt
Parameter Extraction Rules
When users provide natural language music descriptions, directly extract and structure the following parameters:
Required Parameters:
- genres: music genres including fusion styles (e.g., Pop, Rock, Jazz, Pop Rap Fusion, Alternative Rock, Guofeng)
- moods: emotional tones (e.g., Happy, Melancholic, Energetic, Nostalgic, Bright)
- instruments: specific instruments (e.g., Piano, Guitar, Drums, Erhu, Guzheng, Synth Pads, Dizi)
- rhythms: rhythm characteristics (e.g., 4/4, Slow, Syncopated, Driving, Flowing)
- vocals: vocal attributes (e.g., Female, Husky, Whispered, Male, Soft, Clear) or "instrumental only"
- key: musical key if specified (e.g., C Major, A Minor, C# Major)
- bpm: beats per minute (e.g., 120) or tempo descriptor (e.g., "slow groove", "uptempo")
- description: concise summary (under 50 words) capturing mood progression, melody, harmony, timbre, texture, dynamics
Extraction Instructions: 1. Translate non-English terms: Convert ALL non-English musical terms to English while preserving cultural and musical meaning 2. Preserve specificity: Keep detailed information including specific styles, subgenres, and cultural context (e.g., "Chinese traditional guofeng" not just "Chinese music") 3. Design dynamic arc: Include mood progression where appropriate (e.g., "sparse opening → building tension → cathartic chorus") 4. Infer intelligently: Make reasonable assumptions based on genre conventions when parameters are not explicitly stated 5. English output: Final prompt string MUST be entirely in English
Generate Structured Prompt: Combine all extracted parameters into a comprehensive, natural-flowing description that captures the essence of the user's vision.
Quality Checklist (Validate BEFORE Generation)
Before running the generation command, verify the prompt meets these criteria:
MUST HAVE:
- [ ] Specific genre (NOT "pop song" but "synth-pop, 2020s")
- [ ] BPM or tempo descriptor (e.g., "120 BPM" or "slow groove")
- [ ] 3-5 instruments explicitly named
- [ ] Mood/emotion descriptors (2-3 words)
- [ ] Vocal style (or "instrumental only")
- [ ] Structure tags in lyrics: [Verse], [Chorus], [Bridge], [Outro]
WATCH OUT FOR:
- Vague terms: "nice", "good", "beautiful" → replace with specific descriptors
- Contradictions: "slow" + "energetic", "sad" + "uplifting" → pick one direction
- Too short: <50 chars → add more detail
- Long lyric lines: >10 words per line → split into shorter lines
- No dynamic arc: add mood progression (e.g., "sparse → building → full")
AVOID:
- Command verbs: "create a song" → use descriptions "upbeat pop song"
- Famous artist names: "sounds like Taylor Swift" → describe qualities instead
- Unrealistic combos: melody_id cannot combine with other control options
After validation, present the generated prompt to the user for confirmation before proceeding.
---
Core Workflow: Production Pipeline
1. Conceptualize → User describes in natural language → YOU convert to structured prompt
2. Validate → Check prompt quality against Quality Checklist (see above)
3. Write Lyrics → Use lyrics/generate or write manually
4. Upload References → Optional: reference track, vocal sample, melody
5. Generate → Submit song/instrumental task (async) with validated prompt
6. Evaluate → Listen to all N choices, pick best
7. Iterate → Refine prompt based on what you heardCritical Steps:
- Step 1 is mandatory when user provides natural language input (especially non-English)
- Step 2 validation prevents 80% of common generation failures
- Step 3: Read
references/prompt_guide.mdfor prompt crafting examples, lyrics structure rules (line length, syllable count, rhyme patterns, hook writing), and iteration best practices - Do NOT skip conceptualization — jumping straight to generation without a clear concept is the #1 reason for generic results
Your Role as AI Assistant: 1. Convert user's natural language → structured Mureka prompt (using Smart Prompt Conversion) 2. Validate prompt quality → flag issues → suggest fixes 3. Write or generate lyrics with proper structure 4. Present prompt to user for confirmation 5. Execute generation command with validated prompt 6. Help iterate and refine based on generation results
---
CLI Tool
All operations go through a single script: scripts/mureka.py
mureka.py song Generate a song with lyrics and vocals
mureka.py instrumental Generate an instrumental track
mureka.py lyrics Generate or extend lyrics
mureka.py upload Upload reference audio, vocals, melodiesRun python scripts/mureka.py --help for full usage. Note: use -n 2 (single dash) to generate multiple choices, not --n.
---
Common Scenarios
"I just want background music for my video"
python scripts/mureka.py instrumental \
--prompt "ambient electronic, calm, 80 BPM, soft pads, no percussion, background music for tech product video" \
--output ./bg_music"I want a song but don't have lyrics"
# Step 1: Generate lyrics with proper structure
python scripts/mureka.py lyrics generate "a nostalgic summer love song, bittersweet, looking back at memories"
# Step 2: Copy/refine the output, then generate the song
python scripts/mureka.py song \
--lyrics "[Verse]\n(paste lyrics here)\n[Chorus]\n(paste chorus here)" \
--prompt "indie pop, warm, 110 BPM, acoustic guitar, soft drums, male vocal" \
--output ./summer_song---
Advanced Features
Reference-Based Generation
Upload a reference track (must be exactly 30s, mp3/m4a) to guide the style:
python scripts/mureka.py upload my_reference.mp3 --purpose reference
# → File ID: 542321
python scripts/mureka.py song --lyrics "[Verse]\n..." --reference-id 542321 --output ./songVocal Cloning
Upload a vocal sample (15-30s, mp3/m4a) to use a specific voice:
python scripts/mureka.py upload my_voice.mp3 --purpose vocal
# → File ID: 789012
python scripts/mureka.py song --lyrics "[Verse]\n..." --vocal-id 789012 --prompt "R&B, smooth, 90 BPM" --output ./song---
Control Options & Rules
Song Generation Control Combos
When generating songs, these control options work together:
| Combo | prompt | reference_id | vocal_id | melody_id |
|---|---|---|---|---|
| Style only | ✅ | |||
| Reference only | ✅ | |||
| Voice only | ✅ | |||
| Melody only | ✅ | |||
| Style + Voice | ✅ | ✅ | ||
| Reference + Voice | ✅ | ✅ |
Important:
- melody_id does NOT support any combination — use it alone
- prompt and reference_id are mutually exclusive — use one or the other
Instrumental Generation Rules
For instrumentals, prompt and instrumental_id are mutually exclusive — use one or the other.
File Upload Requirements
| Purpose | Format | Duration | Notes |
|---|---|---|---|
reference | mp3/m4a | exactly 30s | Excess trimmed |
vocal | mp3/m4a | 15-30s | Excess trimmed |
melody | mp3/m4a/mid | 5-60s | MIDI recommended |
instrumental | mp3/m4a | exactly 30s | For instrumental reference |
Model Selection
Always use mureka-8 — it is the latest and highest quality model.
---
Error Handling
Scripts raise RuntimeError or requests.HTTPError on failure. Handle common errors:
| Error | Cause | Action |
|---|---|---|
401 Unauthorized | Invalid or expired API key | Ask user to verify MUREKA_API_KEY |
429 Too Many Requests | Rate limit exceeded | Wait 30-60 seconds, then retry |
402 / Insufficient balance | Account balance depleted | Direct user to https://platform.mureka.ai to top up |
Task ended with status: failed | Generation failed (bad prompt, server error) | Check prompt against Quality Checklist, retry |
Task ended with status: timeouted | Generation took too long | Retry; if persistent, simplify the prompt or try a different model |
ConnectionError / Timeout | Network issue | Retry after a few seconds |
General strategy: Read the error message carefully. If it's a client error (4xx), fix the input. If it's a server error (5xx) or timeout, retry once before escalating to the user.
---
Troubleshooting Common Issues
| Problem | Solution |
|---|---|
| Task failed or timeouted | • Check prompt meets quality checklist<br>• Verify lyrics have structure tags<br>• Retry the generation |
| Vocals sound rushed | • Shorten lyric lines (≤10 words)<br>• Reduce syllables per line |
| Listed instruments not audible | • Verify each instrument named explicitly in prompt<br>• Add more specific descriptors (e.g., "acoustic guitar strumming") |
| Prompt doesn't match output | • Increase specificity (exact genre, BPM, instruments)<br>• Add mood progression ("sparse → full")<br>• Generate n=3 choices |
| melody_id error | • melody_id MUST be used alone<br>• Remove --prompt, --reference-id, --vocal-id |
| Invalid file_id | • File IDs only valid for account that uploaded<br>• Re-upload file if from another session |
For parameter help:
python scripts/mureka.py --help
python scripts/mureka.py song --help---
Environment
- API Key:
MUREKA_API_KEYenvironment variable (required) - Base URL:
https://api.mureka.ai - Dependencies: Python 3,
requestslibrary - Billing: Check balance with
curl -H "Authorization: Bearer $MUREKA_API_KEY" https://api.mureka.ai/v1/account/billing
Skywork Music Maker 1.0.0
AI-powered music generation skill for Claude Code and other AI agent frameworks. Create professional songs, instrumentals, and lyrics using Mureka AI API with natural language descriptions in any language.
Quick Links
- [SKILL.md](SKILL.md) - Complete agent guide (start here)
- [references/prompt_guide.md](references/prompt_guide.md) - Music craftsmanship guide (MANDATORY reading for lyrics tasks)
- [scripts/mureka.py](scripts/mureka.py) - Unified CLI tool for all operations
Installation
For Claude Code / Codex
# Option 1: Use directly from this repo
# Reference as: @skywork-music-maker-1.0.0
# Option 2: Install to ~/.claude/skills
cp -r skywork-music-maker-1.0.0 ~/.claude/skills/For Gemini CLI
# Install to skills directory (check your platform's docs)
cp -r skywork-music-maker-1.0.0 /path/to/gemini/skills/For Other AI Frameworks
Copy the directory to your framework's skills location. The skill follows standard conventions and should work with any framework supporting tool-based agents.
Key Features
✅ Natural language to music - Describe in any language, get structured prompts ✅ Smart validation - Quality checks before generation ✅ Complete workflow - Lyrics → Song/Instrumental → Analysis → Extension ✅ Unified CLI - Single mureka.py script for all operations ✅ Agent-optimized - Self-documenting code, clear documentation structure ✅ Production-ready - Best practices from real music production practitioners
Quick Start
1. Set up API key
# Get your API key from https://platform.mureka.ai
export MUREKA_API_KEY="your_api_key"2. Generate music with natural language
# The AI agent will convert your description to a structured prompt
User: "create an upbeat summer pop song with female vocals"
AI: [Converts to structured prompt, validates, generates]
# Or use the CLI directly
cd scripts/
python mureka.py song \
--lyrics "[Verse]\nWalking down the beach..." \
--prompt "indie pop, 110 BPM, acoustic guitar, female vocal, warm and nostalgic" \
--output ./my_song3. Check the results
# Generated files will be in the output directory:
ls ./my_song/
# output_0.mp3 output_1.mp3 lyrics.txtCLI Tool
All operations use a single unified script: scripts/mureka.py
mureka.py song Generate a song with lyrics and vocals
mureka.py instrumental Generate an instrumental track
mureka.py lyrics Generate or extend lyrics using AI
mureka.py upload Upload reference audio, vocals, melodiesUsage:
python scripts/mureka.py --help # Show all commands
python scripts/mureka.py song --help # Song-specific options
python scripts/mureka.py instrumental --help # Instrumental options
python scripts/mureka.py lyrics --help # Lyrics generation options
python scripts/mureka.py upload --help # Upload optionsImportant: Use -n 2 (single dash) to generate multiple choices, not --n.
Common Scenarios
Background music for videos
python scripts/mureka.py instrumental \
--prompt "ambient electronic, calm, 80 BPM, soft pads, no percussion" \
--output ./bg_musicSong without lyrics yet
# Step 1: Generate lyrics
python scripts/mureka.py lyrics generate \
"a nostalgic summer love song, bittersweet, looking back at memories"
# Step 2: Use the generated lyrics for your song
python scripts/mureka.py song \
--lyrics "[Verse]\n(paste generated lyrics here)\n[Chorus]\n..." \
--prompt "indie pop, warm, 110 BPM, acoustic guitar, male vocal" \
--output ./summer_songWith reference track (style transfer)
# Upload 30-second reference track
python scripts/mureka.py upload my_reference.mp3 --purpose reference
# Returns: File ID: 542321
# Generate song using that style
python scripts/mureka.py song \
--lyrics "[Verse]\n..." \
--reference-id 542321 \
--output ./song_with_styleVocal cloning
# Upload 15-30 second vocal sample
python scripts/mureka.py upload my_voice.mp3 --purpose vocal
# Returns: File ID: 789012
# Generate song with cloned voice
python scripts/mureka.py song \
--lyrics "[Verse]\n..." \
--vocal-id 789012 \
--prompt "R&B, smooth, 90 BPM, emotional" \
--output ./cloned_voice_songFile Structure
skywork-music-maker-1.0.0/
├── SKILL.md # Complete agent guide
├── README.md # This file
├── references/
│ └── prompt_guide.md # Music craftsmanship guide (MANDATORY for lyrics)
└── scripts/
└── mureka.py # Unified CLI tool (use --help for docs)Smart Prompt Conversion
When you describe music in natural language (in any language), the AI agent automatically:
1. Extracts structured parameters - Genres, moods, instruments, BPM, vocals, key 2. Validates quality - Checks against quality checklist to prevent generation failures 3. Presents for confirmation - Shows you the structured prompt before generation 4. Executes generation - Runs the API call with the validated prompt
This prevents 80% of common generation failures and ensures high-quality results.
Control Options & Requirements
Song Generation Combinations
| Combo | prompt | reference_id | vocal_id | melody_id |
|---|---|---|---|---|
| Style only | ✅ | |||
| Reference only | ✅ | |||
| Voice only | ✅ | |||
| Melody only | ✅ | |||
| Style + Voice | ✅ | ✅ | ||
| Reference + Voice | ✅ | ✅ |
Important:
melody_iddoes NOT support any combination — use it alonepromptandreference_idare mutually exclusive
File Upload Requirements
| Purpose | Format | Duration | Notes |
|---|---|---|---|
reference | mp3/m4a | exactly 30s | Excess trimmed |
vocal | mp3/m4a | 15-30s | Excess trimmed |
melody | mp3/m4a/mid | 5-60s | MIDI recommended |
instrumental | mp3/m4a | exactly 30s | For instrumental reference |
Model Selection
Always use mureka-8 — it is the latest and highest quality model (default in scripts).
Error Handling
Common errors and solutions:
| Error | Cause | Action |
|---|---|---|
401 Unauthorized | Invalid/expired API key | Verify MUREKA_API_KEY |
429 Too Many Requests | Rate limit exceeded | Wait 30-60 seconds, retry |
402 / Insufficient balance | Account depleted | Top up at https://platform.mureka.ai |
Task failed | Bad prompt/server error | Check Quality Checklist, retry |
Task timeouted | Generation took too long | Simplify prompt, retry |
ConnectionError | Network issue | Retry after a few seconds |
Troubleshooting
| Problem | Solution |
|---|---|
| Task failed or timeouted | • Check prompt meets quality checklist<br>• Verify lyrics have structure tags<br>• Retry |
| Vocals sound rushed | • Shorten lyric lines (≤10 words)<br>• Reduce syllables per line |
| Instruments not audible | • Name each instrument explicitly<br>• Add specific descriptors (e.g., "acoustic guitar strumming") |
| Output doesn't match prompt | • Increase specificity (exact genre, BPM)<br>• Add mood progression ("sparse → full")<br>• Generate n=3 choices |
| melody_id error | • melody_id MUST be used alone<br>• Remove --prompt, --reference-id, --vocal-id |
| Invalid file_id | • File IDs only valid for uploading account<br>• Re-upload if from another session |
Environment Requirements
- Python: 3.7+
- Dependencies:
requestslibrary (pip install requests) - API Key:
MUREKA_API_KEYenvironment variable (required) - API Base URL:
https://api.mureka.ai
Support & Resources
- Issues & Feedback: github.com/anthropics/claude-code/issues
- Mureka API Docs: platform.mureka.ai
- Get API Key: platform.mureka.ai → Register → API Keys → Generate
- Check Balance:
curl -H "Authorization: Bearer $MUREKA_API_KEY" https://api.mureka.ai/v1/account/billing
Examples
Traditional Chinese Music
python scripts/mureka.py song \
--lyrics "[Verse]\n春风拂面..." \
--prompt "Chinese traditional guofeng, 90 BPM, bamboo flute (dizi), guzheng, erhu, misty atmosphere, ancient poetry aesthetic" \
--output ./chinese_styleElectronic Dance Music
python scripts/mureka.py instrumental \
--prompt "progressive house, 128 BPM, synth leads, deep bass, atmospheric pads, building energy" \
-n 3 \
--output ./edm_trackJazz Ballad
python scripts/mureka.py song \
--lyrics "[Verse]\nUnder the midnight sky..." \
--prompt "jazz ballad, slow groove, piano, upright bass, soft brushed drums, female husky vocal, intimate" \
--output ./jazz_balladLicense
Same as parent repository.
---
For detailed music production guidance, prompt crafting examples, and lyric writing best practices, see [references/prompt_guide.md](references/prompt_guide.md).
Music Prompt Crafting Guide
Comprehensive guide to writing effective music prompts for Mureka AI.
The Golden Rule: DESCRIBE, Don't Command
❌ "Create an energetic pop song with drums"
✅ "energetic pop, driving four-on-the-floor drums, bright synth hooks, 128 BPM, female vocal, festival anthem vibe"The AI responds to descriptions of the music, not instructions to "make" or "create" it.
---
Design a Dynamic Arc, Not a Static Description
The most common reason AI-generated songs sound flat is that the prompt describes one mood level throughout. Great songs are tension/release journeys — design yours explicitly.
Express the arc as a mood progression string in your prompt:
✅ "sparse and intimate opening → rising tension → full cathartic chorus → stripped-back bridge → bigger final chorus"
✅ "melancholic and sparse → building urgency → explosive release → quiet resolution"The AI interprets this as an emotional journey across the song. Without it, every section gets the same energy and density.
---
Effective Prompt Structure
Minimum Viable Prompt (always include these)
[genre + sub-genre], [mood/emotion], [tempo/BPM], [key instruments], [vocal style]Standard Prompt (recommended for good results)
Genre: [specific genre + era, e.g., "90s trip-hop"]
Mood: [2-3 descriptors, e.g., "melancholic, introspective, nocturnal"]
Tempo: [BPM or description, e.g., "85 BPM, slow groove"]
Instruments: [3-5 key instruments, e.g., "turntable scratches, Rhodes piano, upright bass"]
Vocals: [style, e.g., "breathy female vocals, intimate delivery"]
Scene: [usage context, e.g., "late-night city driving"]Production Brief (for maximum control)
Genre: trip-hop | Era: mid-90s Bristol
BPM: 85 | Key: D minor
Mood: melancholic → building tension → cathartic release
Lead: Rhodes piano, tremolo
Rhythm: breakbeat, vinyl crackle texture
Bass: deep sub-bass, Moog-style
Texture: tape saturation, lo-fi warmth
Vocals: breathy female, close-mic intimacy
Structure: Intro(8bars) / Verse / Chorus / Verse / Bridge / Chorus / Outro
Avoid: auto-tune, bright synths, four-on-the-floor kick
Reference: Portishead "Roads" (breakbeat texture, Rhodes tone)Note on references: Only use specific songs as sonic benchmarks when all other parameters are already specified. Different from "sound like [artist]" — use for named production qualities (e.g., "Roads-style breakbeat texture").
---
What Makes Prompts FAIL (Top 7 Mistakes)
| # | Mistake | Why It Fails | Fix |
|---|---|---|---|
| 1 | Vague prompts ("nice pop song") | AI defaults to the statistical average — generic, forgettable | Be ruthlessly specific: sub-genre + era + mood + instruments + BPM |
| 2 | Contradictions ("slow and relaxing, high energy, 160 BPM") | Conflicting signals make the AI unpredictable | Check every descriptor agrees with the mood. Pick one direction |
| 3 | "Sound like [famous artist]" | Copyright risk + AI interprets literally, often misses the point | Describe the qualities you like: "warm analog synths, driving bass, 80s production style" |
| 4 | Too many words per lyric line | AI rushes through words → slurred, unnatural vocals | Keep lines ≤10 words. Short lines = better vocal delivery |
| 5 | No structure tags in lyrics | Song has no shape — verse/chorus blur together | Always use [Verse], [Chorus], [Bridge], [Outro] tags |
| 6 | Rewriting entire prompt between iterations | Can never isolate what improved (or worsened) the output | Change ONE element at a time. A/B test systematically |
| 7 | Ignoring negative prompts | Unwanted elements creep in (auto-tune, trap hi-hats, reverb) | Explicitly state what to avoid: "no auto-tune, avoid heavy reverb" |
---
Effective vs Ineffective — Side-by-Side Examples
Example 1: Pop Song
❌ "A pop song about love that sounds good"
✅ "bright synth-pop, uplifting, 120 BPM, arpeggiated synths, punchy electronic drums, female vocal with light reverb, 2020s clean production, summer anthem feel"Example 2: Lo-Fi Background
❌ "lofi music for studying"
✅ "lo-fi hip-hop, warm and mellow, 75 BPM, dusty vinyl crackle, jazzy Rhodes chords, muted boom-bap drums, no vocals, late-night study session atmosphere"Example 3: Cinematic
❌ "epic movie music"
✅ "cinematic orchestral, tension building to triumphant climax, 95 BPM, strings staccato → legato swell, French horns, timpani rolls, choir in final section, Hans Zimmer-style layered percussion"Example 4: Rock Song
❌ "energetic rock song, male vocals, guitar solo"
✅ "alternative rock, energetic and raw, 140 BPM, distorted electric guitar riffs, driving bass line, punchy drums, raspy male vocals, anthemic chorus, guitar solo section, garage rock aesthetic, festival anthem energy"Example 5: Traditional Chinese
❌ "Chinese music, sad"
✅ "Chinese traditional guofeng, melancholic and nostalgic, 60 BPM, dizi bamboo flute lead melody, guzheng plucked strings, subtle erhu, misty atmosphere, Jiangnan water town imagery, rain and mist soundscape, instrumental only"---
Lyrics Writing: What Separates Good from Bad
Structure Tags (always use these)
[Intro]
[Verse]
[Pre-Chorus]
[Chorus]
[Bridge]
[Break]
[Outro]Standard structure order: Verse → Chorus → Verse → Chorus → Bridge → Final Chorus → Outro. The Bridge always appears after the second chorus — never before the first.
If your generated bridge sounds like a second verse, regenerate it with:
python generate_lyrics.py extend "<existing lyrics>" "write a contrasting bridge that shifts perspective, strips back to a single instrument, and sets up the final chorus"Golden Rules for Lyrics That Sing Well
1. Keep lines short — 6-10 words per line. Long lines get rushed.
❌ "I've been walking through the streets of this old town thinking about everything we used to do together"
✅ "Walking through the old town streets\n Thinking of what we used to be"2. Match syllable count across verse lines — Creates natural rhythm.
✅ "Shadows fall on empty streets" (7 syllables)
"Whispers lost in evening heat" (7 syllables)
"Dancing lights through window panes" (7 syllables)3. Use rhyme patterns intentionally — ABAB or AABB, not random.
✅ [Verse]
The city sleeps beneath the stars (A)
While dreamers chase the fading light (B)
We trace our names on passing cars (A)
And disappear into the night (B)4. Chorus should be simpler and more repetitive than verses — Fewer words, not more. Whitespace and repetition create impact; repetition IS the melody.
5. Don't over-explain in lyrics — Imagery > exposition.
---
Writing a Memorable Hook
The hook is the most important line in your song. Get it right:
1. Length and singability
4-8 words, singable on first listen, usually contains the song's title.
✅ "I will always love you" — simple, universal, title, singable
✅ "Rolling in the deep" — 4 words, vivid, singable
❌ "I feel the way I feel when I think about our story" — too long, too vague2. End chorus lines on open vowels
AI vocals hold the last syllable of each line. Open vowels (oh, ah, ay, ee) sustain beautifully. Closed consonants (mm, th, ff, ss) sound awkward when held.
✅ "Let me go" → ends on "oh" — sustains well
❌ "Let me breathe" → ends on closed "th" sound — awkward to hold3. Chorus density
A chorus should have FEWER words than a verse, not more. The space around the hook gives it impact.
❌ "I feel sad because you left me and now I'm alone"
✅ "Empty chair across the table\n Coffee cold, the morning grey"---
Auto-Generate Lyrics First, Then Refine
# Generate lyrics from a concept
python generate_lyrics.py generate "a bittersweet farewell song, two old friends parting ways after summer"
# Extend if you need more sections
python generate_lyrics.py extend "[Verse]\nThe last light paints the pier in gold..."---
Iteration Strategy (How Pros Refine)
1. First generation: Use your best-guess prompt + n=3 2. Listen to all choices: Note what's good and what's off 3. Adjust ONE element: If rhythm is wrong → change BPM/drums description. If mood is off → change mood descriptors 4. Re-generate: Same lyrics, tweaked prompt 5. Compare: Does the change improve or worsen? 6. Repeat until satisfied
What to Listen For
For vocal songs:
| Symptom | Fix |
|---|---|
| Vocals feel rushed / words swallowed | Shorten lyric lines, reduce syllables per line |
| No energy build between verse and chorus | Add mood progression arc to prompt (e.g., "sparse → full cathartic release") |
| Hook doesn't stick | Simplify chorus to 4-8 words, repeat title phrase, check lines end on open vowels |
| Tempo feels wrong | Adjust BPM ±10 and regenerate |
| Listed instruments not audible | Verify each instrument is named explicitly in the prompt |
For instrumentals / ambient:
| Symptom | Fix |
|---|---|
| Tempo feels wrong | Adjust BPM ±10 |
| Mood doesn't match intent | Audit all mood descriptors for internal consistency |
| Instruments missing | Verify each is named explicitly in the prompt |
Never rewrite the entire prompt at once. You'll lose track of what works.
---
Production Checklist (Before You Generate)
Before hitting generate, verify:
- [ ] Genre is specific: Not just "pop" but "synth-pop, 2020s, clean production"
- [ ] Mood is consistent: No contradictions (slow + energetic = confused AI)
- [ ] BPM is set: Even approximate ("~90 BPM, slow groove") helps
- [ ] 3-5 instruments listed: Gives the AI sonic anchors
- [ ] Vocal style specified: Or "no vocals" / "instrumental only"
- [ ] Lyrics have structure tags: [Verse], [Chorus], [Bridge], [Outro]
- [ ] Lines are short: ≤10 words per line
- [ ] Avoid list included: What you DON'T want (auto-tune, trap hi-hats, etc.)
- [ ] N > 1: Generate 2-3 choices and pick the best. Never rely on a single generation
"""Mureka AI music generation CLI — single entry point for all operations."""
import argparse
import json
import os
import sys
import time
import requests
# ---------------------------------------------------------------------------
# API Client
# ---------------------------------------------------------------------------
API_BASE = "https://api.mureka.ai"
POLL_INTERVAL = 5
POLL_TIMEOUT = 600
def get_api_key():
key = os.getenv("MUREKA_API_KEY")
if not key:
print("Error: MUREKA_API_KEY is not set", file=sys.stderr)
sys.exit(1)
return key
def headers(api_key=None):
key = api_key or get_api_key()
return {"Authorization": f"Bearer {key}", "Content-Type": "application/json"}
def post_json(path, payload, api_key=None, timeout=60):
url = f"{API_BASE}{path}"
resp = requests.post(url, json=payload, headers=headers(api_key), timeout=timeout)
resp.raise_for_status()
return resp.json()
def get_json(path, api_key=None, timeout=30):
url = f"{API_BASE}{path}"
resp = requests.get(url, headers=headers(api_key), timeout=timeout)
resp.raise_for_status()
return resp.json()
def upload_file_api(file_path, purpose, api_key=None):
key = api_key or get_api_key()
url = f"{API_BASE}/v1/files/upload"
with open(file_path, "rb") as f:
resp = requests.post(
url,
headers={"Authorization": f"Bearer {key}"},
files={"file": f},
data={"purpose": purpose},
timeout=120,
)
resp.raise_for_status()
return resp.json()
def poll_task(query_path, task_id, api_key=None, interval=POLL_INTERVAL, timeout=POLL_TIMEOUT):
key = api_key or get_api_key()
path = f"{query_path}/{task_id}"
deadline = time.time() + timeout
terminal = {"succeeded", "failed", "timeouted", "cancelled"}
while True:
data = get_json(path, api_key=key)
status = data.get("status", "")
print(f" [{status}] task {task_id}", file=sys.stderr)
if status in terminal:
if status != "succeeded":
reason = data.get("failed_reason", status)
raise RuntimeError(f"Task {task_id} ended with status: {status}. Reason: {reason}")
return data
if time.time() > deadline:
raise RuntimeError(f"Task {task_id} timed out after {timeout}s (last status: {status})")
time.sleep(interval)
def download_audio(url, output_path):
resp = requests.get(url, timeout=120)
resp.raise_for_status()
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
with open(output_path, "wb") as f:
f.write(resp.content)
return output_path
def download_choices(result, args):
"""Download audio files into output directory."""
choices = result.get("choices", [])
if not choices:
print("No results generated.", file=sys.stderr)
sys.exit(1)
out_dir = args.output
os.makedirs(out_dir, exist_ok=True)
format_key = {"mp3": "url", "flac": "flac_url", "wav": "wav_url"}[args.format]
for choice in choices:
idx = choice.get("index", 0)
url = choice.get(format_key) or choice.get("url")
duration_ms = choice.get("duration", 0)
if len(choices) > 1:
filename = f"audio_{idx}.{args.format}"
else:
filename = f"audio.{args.format}"
output_path = os.path.join(out_dir, filename)
print(f"Downloading choice {idx} ({duration_ms / 1000:.1f}s) → {output_path}", file=sys.stderr)
download_audio(url, output_path)
print(output_path)
# ---------------------------------------------------------------------------
# Subcommands
# ---------------------------------------------------------------------------
def cmd_song(args):
"""Generate a song with lyrics and vocals."""
payload = {"lyrics": args.lyrics, "model": args.model}
if args.prompt:
payload["prompt"] = args.prompt
if args.reference_id:
payload["reference_id"] = args.reference_id
if args.vocal_id:
payload["vocal_id"] = args.vocal_id
if args.melody_id:
payload["melody_id"] = args.melody_id
if args.n:
payload["n"] = args.n
# Save lyrics and prompt to output directory
os.makedirs(args.output, exist_ok=True)
lyrics_path = os.path.join(args.output, "lyrics.txt")
with open(lyrics_path, "w", encoding="utf-8") as f:
f.write(args.lyrics)
if args.prompt:
f.write(f"\n\n---\nPrompt: {args.prompt}\n")
print(f"Lyrics saved → {lyrics_path}", file=sys.stderr)
print("Submitting song generation task...", file=sys.stderr)
task = post_json("/v1/song/generate", payload)
task_id = task["id"]
print(f"Task ID: {task_id}", file=sys.stderr)
print("Polling for completion...", file=sys.stderr)
result = poll_task("/v1/song/query", task_id,
interval=args.poll_interval, timeout=args.poll_timeout)
download_choices(result, args)
def cmd_instrumental(args):
"""Generate an instrumental track."""
payload = {"model": args.model}
if args.prompt:
payload["prompt"] = args.prompt
if args.instrumental_id:
payload["instrumental_id"] = args.instrumental_id
if args.n:
payload["n"] = args.n
print("Submitting instrumental generation task...", file=sys.stderr)
task = post_json("/v1/instrumental/generate", payload)
task_id = task["id"]
print(f"Task ID: {task_id}", file=sys.stderr)
print("Polling for completion...", file=sys.stderr)
result = poll_task("/v1/instrumental/query", task_id,
interval=args.poll_interval, timeout=args.poll_timeout)
download_choices(result, args)
def cmd_lyrics(args):
"""Generate or extend lyrics."""
if args.lyrics_command == "generate":
result = post_json("/v1/lyrics/generate", {"prompt": args.prompt})
title = result.get("title", "")
lyrics = result.get("lyrics", "")
if title:
print(f"Title: {title}\n")
print(lyrics)
elif args.lyrics_command == "extend":
result = post_json("/v1/lyrics/extend", {"lyrics": args.lyrics})
print(result.get("lyrics", ""))
def cmd_upload(args):
"""Upload a file to Mureka."""
print(f"Uploading {args.file} (purpose={args.purpose})...", file=sys.stderr)
result = upload_file_api(args.file, args.purpose)
file_id = result.get("id", "")
print(f"File ID: {file_id}")
print(json.dumps(result, indent=2))
# ---------------------------------------------------------------------------
# Shared argument helpers
# ---------------------------------------------------------------------------
def add_generation_args(parser, default_output="./output"):
"""Add common generation arguments."""
parser.add_argument("--model", default="mureka-8",
help="Model (default: mureka-8)")
parser.add_argument("-n", "--n", type=int, default=None, dest="n",
help="Number of results to generate (default 2, max 3)")
parser.add_argument("--output", default=default_output,
help=f"Output directory (default: {default_output})")
parser.add_argument("--format", choices=["mp3", "flac", "wav"], default="mp3",
help="Download format (default: mp3)")
parser.add_argument("--poll-interval", type=int, default=5,
help="Poll interval in seconds (default: 5)")
parser.add_argument("--poll-timeout", type=int, default=600,
help="Poll timeout in seconds (default: 600)")
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(
description="Mureka AI music generation CLI",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""examples:
%(prog)s song --lyrics "[Verse]\\nHello world" --prompt "pop, 120 BPM, female vocal"
%(prog)s instrumental --prompt "ambient, 80 BPM, soft pads"
%(prog)s lyrics generate "a summer love song"
%(prog)s lyrics extend "[Verse]\\nExisting lyrics..."
%(prog)s upload my_voice.mp3 --purpose vocal
""")
sub = parser.add_subparsers(dest="command", required=True)
# --- song ---
p_song = sub.add_parser("song", help="Generate a song with lyrics and vocals")
p_song.add_argument("--lyrics", required=True,
help="Song lyrics (max 3000 chars). Use structure tags: [Verse], [Chorus], etc.")
p_song.add_argument("--prompt", default=None,
help="Style/scene prompt (max 1024 chars)")
p_song.add_argument("--reference-id", default=None,
help="Reference audio file ID (purpose=reference)")
p_song.add_argument("--vocal-id", default=None,
help="Vocal file ID (purpose=vocal)")
p_song.add_argument("--melody-id", default=None,
help="Melody file ID (purpose=melody). Cannot combine with other control options")
add_generation_args(p_song, "./output")
# --- instrumental ---
p_inst = sub.add_parser("instrumental", help="Generate an instrumental track")
p_inst.add_argument("--prompt", default=None,
help="Style/scene prompt (max 1024 chars)")
p_inst.add_argument("--instrumental-id", default=None,
help="Reference instrumental file ID (purpose=instrumental)")
add_generation_args(p_inst, "./instrumental")
# --- lyrics ---
p_lyrics = sub.add_parser("lyrics", help="Generate or extend lyrics")
lyrics_sub = p_lyrics.add_subparsers(dest="lyrics_command", required=True)
p_lyrics_gen = lyrics_sub.add_parser("generate", help="Generate lyrics from a prompt")
p_lyrics_gen.add_argument("prompt", help="Theme or description for lyrics")
p_lyrics_ext = lyrics_sub.add_parser("extend", help="Extend existing lyrics")
p_lyrics_ext.add_argument("lyrics", help="Existing lyrics to continue writing")
# --- upload ---
p_upload = sub.add_parser("upload", help="Upload a file to Mureka")
p_upload.add_argument("file", help="Path to the audio file (mp3, m4a, or mid for melody)")
p_upload.add_argument("--purpose", required=True,
choices=["reference", "vocal", "melody", "instrumental", "voice", "audio"],
help="Purpose: reference (30s), vocal (15-30s), melody (5-60s), instrumental (30s), voice (5-15s), audio (general)")
args = parser.parse_args()
{"song": cmd_song,
"instrumental": cmd_instrumental,
"lyrics": cmd_lyrics,
"upload": cmd_upload}[args.command](args)
if __name__ == "__main__":
main()
Related skills
How it compares
Choose skywork-music-maker for agent-driven music generation; choose blog-chart for inline SVG data visuals in written content.
FAQ
What audio formats can skywork-music-maker create?
skywork-music-maker generates music loops, stems, or full tracks through Skywork agent workflows with style prompts and structure control, then exports the results for integration into applications or marketing campaigns.
When should developers use skywork-music-maker?
Developers should use skywork-music-maker when an app, demo, or campaign needs custom background music or structured tracks and they want Skywork agent workflows to produce exportable audio instead of manual composition.