Suno Upload
Automatically upload Suno prompt files to suno.com using Chrome automation. This skill parses your prompt.md files and fills the Suno Create interface with all the necessary fields.
✅ Fully Automated - No Human Intervention Required
This skill achieves complete end-to-end automation of the Suno song creation process:
- ✅ Parses prompt.md files - Extracts title, lyrics, style, model, and all parameters
- ✅ Navigates to Suno automatically - Opens suno.com/create and switches to Custom mode
- ✅ Fills ALL form fields - Including complex React slider components
- ✅ Slider automation working - Uses coordinate-based dragging for precise control
- ✅ Submits and monitors - Clicks Create button and tracks generation
- ✅ Validated and tested - Successfully generated songs with full parameter control
No manual intervention needed - Just point it at a prompt.md file and let it work.
Prerequisites
- Chrome MCP server must be installed and active
- Suno account with available credits
- Prompt.md file in the standard Suno song creator format
When to Use
Use this skill to:
- Upload generated prompt.md files to Suno
- Automate the song creation process on suno.com
- Submit multiple prompts efficiently
- Avoid manual copy-paste of lyrics and settings
Workflow
Step 1: Locate Prompt Files
Search for prompt.md files in the current directory and subdirectories.
If multiple files found:
- Display list with:
- File path
- Song title (from YAML frontmatter)
- Project name (from YAML frontmatter)
- Last modified date
- Use AskUserQuestion for interactive selection
- Present options clearly with full context
If single file found:
- Automatically select it
- Display which file was selected
- Show basic info (title, project)
If no files found:
- Error message: "No prompt.md files found in the current directory or subdirectories."
- Guidance: "Please navigate to a directory containing Suno prompt files, or create a prompt using the suno-song-creator skill first."
- Exit gracefully
Tools used:
- Glob - Search for
**/prompt.mdpattern - Read - Extract YAML frontmatter for file listing
- AskUserQuestion - Interactive file selection
Step 2: Parse Prompt File
Read and extract data from the selected prompt.md file.
Parsing Strategy:
1. YAML Frontmatter (lines 1-12):
---
title: "Song Title Here"
project: "Project Name"
---
- Extract
title:value - Remove surrounding quotes if present
- This becomes the "Song Title" field
2. Structured Prompt (under "### Structured Prompt" heading):
Find the heading ### Structured Prompt, then extract everything between the triple backticks:
genre: "bubblegum pop, synth-pop, disco-influenced pop..."
vocal: "bright female pop vocals, playful delivery..."
instrumentation: "synth bass, disco-inspired drums..."
production: "polished modern pop, wide stereo mix..."
mood: "playful, sarcastic, witty, upbeat..."
IMPORTANT:
- Copy the entire block as-is (all 5 lines)
- Do NOT parse individual fields
- This complete block goes into Suno's "Styles" field
- Keep all quotes and formatting
3. Lyrics Section (after "## Lyrics" heading):
Find ## Lyrics, then extract everything between the triple backticks:
///*****///
[Verse 1 | playful | bright production]
Lyrics text here...
[Chorus | upbeat | full production]
Chorus lyrics here...
CRITICAL Parsing Rules:
- REMOVE the divider line: Skip
///*****///at the start (this is just a separator in the file) - KEEP all meta tags:
[Verse 1 | playful | bright production]- Suno uses these! - KEEP section markers:
[Verse],[Chorus],[Bridge], etc. - KEEP all blank lines: Preserve formatting exactly
- Start from first actual lyric content: After removing divider, begin with the first
[Verse...]tag
Example extraction:
File contains:
///*****///
[Verse 1 | playful | bright production]
You showed up late...
Extract as:
[Verse 1 | playful | bright production]
You showed up late...
4. Model Selection (from "### Model and Parameters" section):
Look for the model specification near the top of this section:
**Model:** v5 (cleanest audio, most natural vocals - best for modern pop)
Extraction rules:
- Model: Extract value after
**Model:**and before the opening parenthesis- Expected values: "v5", "v4.5", "v4.5+", "v4"
- Trim whitespace: "v5"
- Default to "v5" if not specified
5. Parameters (from "### Model and Parameters" section):
Look for bullet points under this heading:
- Weirdness: 40%
- Style Influence: 60%
- Vocal Gender: Female
- Exclude Styles: Rock, Metal, Country
Extraction rules:
- Weirdness: Extract number before
%(e.g., "40" from "40%")- If range like "30-40%", use midpoint (35)
- Convert to slider value: use as-is (0-100 scale)
- Style Influence: Extract number before
%(e.g., "60" from "60%")- If range like "60-70%", use midpoint (65)
- Convert to slider value: use as-is (0-100 scale)
- Vocal Gender: Extract value after
:and trim whitespace- Expected values: "Female", "Male", or unspecified
- Map to Suno's gender buttons
- Exclude Styles: Extract comma-separated list after
:- Trim whitespace: "Rock, Metal, Country"
- Keep as comma-separated string
Graceful Handling:
- If field missing: use sensible default or skip
- If malformed YAML: try regex extraction as fallback
- If lyrics section empty: error (lyrics required for Suno)
- If parameters missing: use Suno defaults (50% for sliders)
Tools used:
- Read - Read the prompt.md file
- Regex/string parsing - Extract structured data
Validation:
- Title exists and non-empty
- Lyrics exist and non-empty
- Structured prompt exists and non-empty
- Parameters are within valid ranges (0-100 for sliders)
Step 3: Display Parsed Data
Show the user what was extracted from the file for verification:
Format:
📋 Parsed Prompt Data:
Title: "Fixer-Upper"
Project: "Pop Songs I Love"
Model: v5
Lyrics Preview (first 200 chars):
[Verse 1 | playful | bright production]
You showed up late with pizza stains
On that shirt you wore last Tuesday
Asked me if I'd do your laundry
While you played your gam...
(Note: Divider line removed for Suno upload)
Style/Genre (from structured prompt):
genre: "bubblegum pop, synth-pop, disco-influenced pop..."
[Full 5-line structured prompt shown]
Parameters:
- Weirdness: 40%
- Style Influence: 60%
- Vocal Gender: Female
- Exclude Styles: Rock, Metal, Country
Ready to upload to Suno!
Purpose:
- User can verify parsing was correct
- Catch any issues before automation starts
- Builds confidence in the process
Step 4: Initialize Chrome Session
Set up the browser automation environment.
Steps:
- Call
tabs_context_mcpto get current tab state- Check if MCP tab group exists
- Get available tab IDs
- If no MCP tab group: call
tabs_context_mcpwithcreateIfEmpty: true - Create new tab:
tabs_create_mcp- Fresh tab for Suno automation
- Prevents interfering with user's existing tabs
- Navigate to suno.com:
navigate(url: "https://suno.com") - Wait for page load:
computer(action: wait, duration: 3)
Error handling:
- If navigation fails: retry once, then ask user to check connection
- If tab creation fails: inform user and exit
- If already on suno.com: ask if should create new tab or use existing
Tools used:
- tabs_context_mcp - Get tab context
- tabs_create_mcp - Create new tab
- navigate - Navigate to URL
- computer (wait) - Wait for page load
Step 5: Navigate to Create Interface
Navigate from the home page to the Create page in Custom mode.
Steps:
-
Navigate to Create page:
- Use navigate tool: "https://suno.com/create" - OR use find + computer tools to click "Create" button - Wait 2 seconds for page load -
Switch to Custom mode:
- Use find tool: query="Custom tab button" - Use computer tool: left_click on the Custom button ref - Wait 1 second for mode switch -
Verify Custom mode loaded:
- Take screenshot for debugging (optional) - Use read_page to verify "Lyrics" field is present
UI Elements to find:
- Create button/link (ref varies, use find tool)
- Custom tab button (vs "Simple" mode)
- Lyrics textarea (confirms Custom mode loaded)
Error handling:
- If Create page doesn't load: retry navigation once
- If Custom button not found: take screenshot, inform user
- If timeout: ask user to check Suno status
Tools used:
- navigate - Direct URL navigation
- find - Locate UI elements by description
- computer - Click buttons
- read_page - Verify page loaded correctly
Step 6: Fill Form Fields
Fill each form field with the parsed data.
Field-by-field process:
a. Model Selector (at top of Create area)
- Use find: query="v5" or "model selector dropdown"
- Location: Top of create area, near Simple/Custom tabs
- Current default: v5
- Click to open dropdown if not already showing target model
- Select the parsed model (v5, v4.5, v4.5+, or v4)
Data: Model from Step 2 (e.g., "v5") Note: Based on UI exploration, the model selector is visible at the top Implementation:
- If model is "v5" (default): may skip (already selected)
- If model is different: click dropdown and select appropriate option
- Use find to locate the specific model option
- Use computer.left_click to select
b. Lyrics Textarea
- Use find: query="lyrics textarea"
- Use form_input: ref=<lyrics_ref>, value=<full_lyrics_text>
- Or use computer.type if form_input fails
Data: Full lyrics from Step 2 (with divider line ///*****/// removed, but all meta tags like [Verse 1 | ...] preserved)
c. Styles Field (Structured Prompt)
- Use find: query="styles textbox" or "style of music"
- Use form_input: ref=<styles_ref>, value=<structured_prompt_block>
Data: Complete 5-line structured prompt block
d. Song Title (Optional)
- Use find: query="song title optional"
- Use form_input: ref=<title_ref>, value=<song_title>
Data: Title from YAML frontmatter
e. Expand Advanced Options
- Use find: query="Advanced Options"
- Use computer: left_click on Advanced Options button
- Wait 1 second for expansion
f. Exclude Styles
- Use find: query="exclude styles"
- Use form_input: ref=<exclude_ref>, value=<exclude_styles_list>
Data: Comma-separated exclusion list (e.g., "Rock, Metal, Country")
g. Vocal Gender
- Use find: query="Female" (or "Male" based on parsed data)
- Use computer: left_click on the appropriate gender button
Data: "Female" or "Male" from parameters Note: If unspecified, skip this field (use Suno default)
h. Weirdness Slider
Data: Parsed weirdness value (0-100)
Working Method (Coordinate-Based Dragging):
Sliders in Suno are custom React components (DIVs with ARIA roles), not standard HTML inputs. They require coordinate-based mouse dragging to set values.
Step-by-step implementation:
-
Find the slider element:
Use find: query="Weirdness slider" This returns a ref to the slider with role="slider" -
Calculate target position with JavaScript:
const slider = document.querySelector('[role="slider"][aria-label*="Weirdness"]'); const thumb = slider.children[slider.children.length - 1]; const sliderRect = slider.getBoundingClientRect(); const thumbRect = thumb.getBoundingClientRect(); // Current thumb center position const startX = thumbRect.left + thumbRect.width / 2; const startY = thumbRect.top + thumbRect.height / 2; // Target position (e.g., 40% along slider width) const targetPercent = 40; // Use parsed value const targetX = sliderRect.left + (sliderRect.width * (targetPercent / 100)); const targetY = sliderRect.top + sliderRect.height / 2;Use javascript_tool to execute this and return coordinates
-
Drag thumb to target position:
Use computer: left_click_drag - start_coordinate: [startX, startY] (from JavaScript) - coordinate: [targetX, targetY] (from JavaScript)
Why this works:
- React state updates when the mouse drag event completes
- Coordinate calculation ensures accurate positioning
- getBoundingClientRect() provides precise pixel positions
- Dragging the thumb (last child element) triggers React's onChange handler
i. Style Influence Slider
Data: Parsed style influence value (0-100)
Working Method (Same as Weirdness):
Use the identical coordinate-based dragging approach:
-
Find the slider:
Use find: query="Style Influence slider" -
Calculate coordinates with JavaScript:
const slider = document.querySelector('[role="slider"][aria-label*="Style Influence"]'); const thumb = slider.children[slider.children.length - 1]; const sliderRect = slider.getBoundingClientRect(); const thumbRect = thumb.getBoundingClientRect(); const startX = thumbRect.left + thumbRect.width / 2; const startY = thumbRect.top + thumbRect.height / 2; const targetPercent = 60; // Use parsed value const targetX = sliderRect.left + (sliderRect.width * (targetPercent / 100)); const targetY = sliderRect.top + sliderRect.height / 2; -
Drag to target:
Use computer: left_click_drag from [startX, startY] to [targetX, targetY]
Important notes for both sliders:
- Do NOT use form_input (fails with "Element type 'DIV' is not a supported form input")
- Do NOT set ARIA attributes directly (doesn't update React state)
- Do NOT use keyboard events (Arrow keys don't trigger state updates)
- DO use left_click_drag with calculated coordinates
- Precision: Usually accurate within ±1%, which is acceptable
Implementation Notes:
- Fill fields sequentially, not in parallel
- Wait 0.5 seconds between field fills for UI stability
- Take screenshot after critical fields for debugging
- If field not found, log warning and continue (optional fields)
- If required field fails, error and exit
Tools used:
- find - Locate form elements
- form_input - Fill text fields
- computer (left_click) - Click buttons, interact with sliders
- computer (type) - Fallback for text input
- computer (wait) - Stability pauses
Step 7: Confirmation & Review
Before submitting, show the user what will be submitted and ask for confirmation.
Process:
-
Take screenshot of filled form:
- Use computer: screenshot action - Capture the entire Create form area - User can visually verify all fields -
Display summary to user:
✅ Suno Form Ready for Submission: Title: "Fixer-Upper" Lyrics: 140 lines (with meta tags preserved) Style: bubblegum pop, synth-pop, disco-influenced pop... Weirdness: 40% Style Influence: 60% Vocal Gender: Female Exclude Styles: Rock, Metal, Country [Screenshot of filled form displayed above] -
Ask for confirmation:
Use AskUserQuestion: - Question: "Submit this song to Suno for generation?" - Options: * "Yes, create the song" (proceed to submit) * "No, cancel" (exit without submitting) - Wait for explicit user response -
Handle response:
- If "Yes": proceed to Step 8
- If "No": inform user and exit gracefully
- Message: "Upload cancelled. The form has been filled but not submitted. You can manually review and submit in the browser if needed."
Why this matters:
- User has final control before spending credits
- Catch any parsing errors before submission
- Visual confirmation builds trust
- Prevents accidental submissions
Tools used:
- computer (screenshot) - Capture form
- AskUserQuestion - Get explicit confirmation
Step 8: Submit & Monitor
Submit the form and monitor for song URLs.
Submission:
-
Find Create button:
- Use find: query="Create song button" or "Create button" - Expected ref like: ref_943 (based on exploration) -
Click Create button:
- Use computer: left_click on Create button ref - Wait 3 seconds for submission processing -
Monitor for response:
- Page may redirect or update with song generation status - Look for success indicators or error messages - Wait up to 10 seconds for initial response
URL Extraction (if generation starts):
-
Check for song URLs:
- Suno typically generates 2 songs per creation - URLs may appear immediately or after processing - Format: https://suno.com/song/[song-id] -
Extract URLs:
- Use read_page to get page content - Look for song URLs in the recent creations area - OR check the workspace/library section -
Display results to user:
✅ Song submitted to Suno! Generation started. Suno is creating your song(s). URLs (check these for your songs): - https://suno.com/song/abc123-def456-... - https://suno.com/song/xyz789-uvw012-... Note: Songs may take 1-2 minutes to generate. Visit the URLs above to listen once ready.
Error Handling:
-
Submit button not found:
- Take screenshot
- Error: "Could not find Create button. Suno UI may have changed."
- Offer to show screenshot to user for manual completion
-
Validation errors from Suno:
- Read error messages from page
- Display to user: "Suno validation error: [error message]"
- Suggest fixes if recognizable (e.g., "Lyrics too short")
-
Network/timeout errors:
- Error: "Submission timed out. Please check Suno manually."
- Provide form status: "Form was filled and Create button clicked, but response not received."
-
Credits exhausted:
- If error message about credits appears
- Inform user: "Suno credits exhausted. Please purchase more credits and try again."
URL Extraction Fallback:
If URLs cannot be automatically extracted:
- Inform user: "Song submitted successfully, but URLs could not be extracted automatically."
- Guidance: "Check your Suno workspace at https://suno.com/me for your newly created songs."
Tools used:
- find - Locate Create button
- computer (left_click) - Submit form
- computer (wait) - Wait for processing
- read_page - Extract URLs and errors
- computer (screenshot) - Debugging
Step 9: Completion
Wrap up the automation and provide final status.
Success case:
✅ Suno Upload Complete!
Song: "Fixer-Upper"
Status: Submitted and generating
URLs:
- [Song URL 1]
- [Song URL 2]
Songs typically generate in 1-2 minutes. Visit the URLs above to listen!
Partial success case:
✅ Suno Upload Submitted!
Song: "Fixer-Upper"
Status: Form submitted, URLs not yet available
Check your Suno workspace for the generated songs:
https://suno.com/me
Failure case:
❌ Suno Upload Failed
Error: [Specific error message]
The form was partially filled. You can:
1. Complete manually in the browser (tab is still open)
2. Try running /suno-upload again
3. Check the error message above for guidance
Error Handling Patterns
File Not Found:
- Clear message about what went wrong
- Guidance on how to fix (navigate to correct directory, create prompt first)
- No stack traces or technical jargon
Parsing Errors:
- Show which field failed to parse
- Show the problematic content if helpful
- Suggest fixing the prompt.md file
- Offer to proceed with defaults if non-critical field
Chrome Automation Failures:
- Take screenshot at failure point
- Show screenshot to user (visual debugging)
- Provide context about what was being attempted
- Offer retry option if transient failure likely
Suno UI Changes:
- If element not found after reasonable attempts
- Error: "Suno UI may have changed. This skill needs updating."
- Recommend manual upload as fallback
- Ask user to report issue
Network Issues:
- Distinguish between local network and Suno server issues
- Suggest checking internet connection
- Offer retry option
- Timeout values should be generous (10+ seconds for submission)
Usage Examples
Example 1: Single prompt file
User: "Upload this to Suno"
Skill:
- Finds single prompt.md in current directory
- Parses: "Fixer-Upper" pop song
- Displays parsed data
- Navigates to Suno, fills form
- Asks confirmation
- User: "Yes"
- Submits and returns URLs
Example 2: Multiple prompt files
User: "/suno-upload"
Skill:
- Finds 5 prompt.md files in subdirectories
- Lists all 5 with titles and projects
- Asks which to upload
- User selects #3
- Proceeds with upload workflow
Example 3: Called from suno-song-creator
User: Creates song with suno-song-creator
Skill (suno-song-creator):
- Generates prompt, saves to prompt.md
- Asks: "Upload to Suno now?"
- User: "Yes"
- Invokes suno-upload skill with file path
- suno-upload proceeds automatically
Tools Reference
Discovery & Parsing:
- Glob - Find prompt.md files
- Read - Read file contents
- AskUserQuestion - File selection, confirmation
Chrome Automation:
- tabs_context_mcp - Get tab state
- tabs_create_mcp - Create new tab
- navigate - Navigate to URLs
- computer (screenshot) - Capture screenshots
- computer (wait) - Stability pauses
- computer (left_click) - Click buttons
- computer (type) - Type text (fallback)
- find - Locate UI elements by description
- form_input - Fill form fields
- read_page - Get page structure
Success Criteria
✅ Finds and parses prompt.md files correctly ✅ Extracts all fields without data loss ✅ Preserves lyrics meta tags and formatting ✅ Navigates to Suno Create interface ✅ Fills all form fields accurately ✅ Handles sliders and special inputs ✅ Shows confirmation before submission ✅ Submits successfully and extracts URLs ✅ Handles errors gracefully with clear messages ✅ Works when called from other skills
Known Limitations
Slider Precision:
- Coordinate-based dragging achieves accuracy within ±1%
- This variance is negligible and acceptable for creative parameters
- Browser rendering and viewport size don't affect the calculation (uses getBoundingClientRect)
URL Extraction:
- Suno's generation is asynchronous
- URLs may not appear immediately
- Fallback: direct user to workspace
UI Changes:
- Suno may update their UI
- Skill may need updates when UI changes
- Reference selectors may break
Credit Requirements:
- Skill does not check credit balance beforehand
- User must have credits for submission to work
- Error appears only at submission time
Maintenance Notes
If Suno UI changes, update these sections:
- Step 5: Navigation paths and button refs
- Step 6: Form field selectors and names
- Step 8: Create button selector
- URL extraction patterns
Test with real prompt.md files regularly to ensure parsing remains accurate.
Version: 2.0.0 - Complete Automation Achieved Last Updated: 2026-01-01 Dependencies: Chrome MCP server, Suno account with credits
Key Improvements in v2.0:
- ✅ Slider automation fully working with coordinate-based dragging
- ✅ Complete end-to-end automation with NO human intervention required
- ✅ Reliable React component interaction through mouse events
- ✅ Validated with successful song generation ("Fixer-Upper" test case)