suno-mcp
Skill5 starsChanged 33 days agoMITView on GitHub
Generate AI music with Suno via MCP. Use when creating songs with custom lyrics, instrumental tracks, or specific genres/moods. Triggers on "generate a song", "create music", "make a track", "Suno", "AI music", or any music generation request.
In this repository5 other files it gives its agents.
- comfyuiSkill
- drama-videoSkill
- music-videoSkill
- storyboardSkill
- youtube-uploadSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 53
Use an absolute script path and an explicit output directory for each task.
- Very specific: line 59
Do NOT write a per-invocation wrapper python file.
- Distinctive: line 96
Use a 400-second timeout — the pipeline is 3–5 minutes (Suno generation plus parallel download of both variants).
- Very specific: line 130
If the user gives you a Suno share URL (https://suno.com/s/<share_id>) instead of asking you to generate a new song, you don't need the MCP …
- Very specific: line 149
After the pull, hand song.mp3 to the music-video skill at step 5 (STT → align scene timings) and skip steps 1-4 of that skill.
- Distinctive: line 223
Keep lines to a natural spoken length — Suno matches syllables to melody
- Distinctive: line 224
Avoid punctuation mid-line.
- Very specific: line 227
Use [Instrumental] for breathing room between sections
- Very specific: line 316
Connection refused / DNS error: verify SUNO_MCP_URL resolves to http://suno-mcp.tail.ait4x.org and that the client has the intended …
- Very specific: line 319
Wrong parameter name: Use lyrics, not prompt (deprecated).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Suno MCP Skill
Direct Suno MCP server access for AI music generation. The scripts talk to the
MCP server over plain JSON-RPC / HTTP (no mcporter, no npx) and download
both song variants to a local directory.
Server URL configuration
The Suno server is on Headscale at http://suno-mcp.tail.ait4x.org.
The scripts use SUNO_MCP_URL (defaulting to that URL), with /mcp for
JSON-RPC and /audio/<file>.mp3 for downloads. SUNO_OUTPUT_DIR defaults to
./outputs/suno. CLI flags --url and --output-dir override these values.
On an ordinary Headscale-connected client, use the URL directly. The current OpenClaw gateway also resolves this hostname through its Headscale sidecar. The old media relay and Tailscale-SaaS Suno endpoint are retired.
Thor's native execution node uses a userspace Headscale client alongside the separate host Tailscale failsafe. For Suno commands on that node, explicitly set this command's proxy environment; do not set a global system proxy:
/usr/bin/env SUNO_MCP_URL=http://suno-mcp.tail.ait4x.org \
http_proxy=http://127.0.0.1:1055 https_proxy=http://127.0.0.1:1055 \
no_proxy= NO_PROXY= \
python3 /home/venetanji/dev/creative-skills/suno-mcp/scripts/generate_song.py \
--input-json /absolute/path/to/song-spec.jsonPort 1055 is a loopback-only outbound proxy provided by tailscale-hs, the
Headscale client, not the host's Tailscale-SaaS daemon. Browser login is at the
same Suno base URL. Music generation is not part of connectivity verification.
Script paths
Canonical source on Thor is /home/venetanji/dev/creative-skills/suno-mcp.
The gateway's installed copy is
/home/venetanji/.openclaw/skills/suno-mcp inside the gateway, backed by
/home/venetanji/.openclaw-gateway/skills/suno-mcp on Thor.
Use an absolute script path and an explicit output directory for each task.
Historical lordship and media-relay paths are not current execution routes.
Quick Start
Two-step pattern: write tool for the spec, exec tool for the script.
Do NOT write a per-invocation wrapper python file. Do NOT shell-quote
multiline lyrics into --lyrics='...'. Both are workarounds for
shell-quoting that the --input-json flag eliminates entirely.
Step 1 — write the song spec via the write tool
The write tool doesn't go through shell parsing, so lyrics with
quotes, backslashes, multiline [Verse] / [Chorus] blocks, or any
UTF-8 are safe as-is. Target file: anywhere writable, e.g.
/workspace/.suno/<title-slug>.json.
{
"title": "Neon Highways",
"lyrics": "[Verse 1]\nDriving through the rain...\n[Chorus]\n...",
"tags": "synthwave, 1980s production, gated reverb on snare, ...",
"negative_prompt": "",
// Optional:
// "instrumental": true,
"output_dir": "/absolute/path/to/output"
}Step 2 — call generate_song.py via the exec tool
Single argument, no shell quoting of user content, passes preflight cleanly. On Thor, keep the Headscale proxy settings scoped to this command; another Headscale-connected client can omit those proxy assignments:
/usr/bin/env SUNO_MCP_URL=http://suno-mcp.tail.ait4x.org \
http_proxy=http://127.0.0.1:1055 https_proxy=http://127.0.0.1:1055 \
no_proxy= NO_PROXY= \
python3 /home/venetanji/dev/creative-skills/suno-mcp/scripts/generate_song.py \
--input-json /workspace/.suno/neon-highways.jsonUse a 400-second timeout — the pipeline is 3–5 minutes (Suno generation plus parallel download of both variants).
Step 3 — send BOTH variants
The script's stdout is JSON with at least:
{
"local_files": ["<path>/suno_<id1>.mp3", "<path>/suno_<id2>.mp3"],
"all_ids": ["<id1>", "<id2>"],
"local_file": "<local_files[0]>" // legacy alias
}Suno always returns two takes from a single request. Send both to the
user with the message tool (one call per file) and let them choose —
agents that send only the first systematically lose half the value of
every generation.
CLI flag overrides
CLI flags still work and override JSON values for ad-hoc tweaks (no need to rewrite the JSON for a small change):
python3 generate_song.py --input-json /workspace/.suno/song.json --title "Take 2"For instrumental tracks, set "instrumental": true in the JSON (or
pass --instrumental on the CLI).
Importing an existing Suno song
If the user gives you a Suno share URL (https://suno.com/s/<share_id>)
instead of asking you to generate a new song, you don't need the MCP
generate path at all. Resolve to the canonical share URL in a browser
to read the song UUID, then pull the mp3 directly from Suno's CDN:
# Share URL → canonical URL → uuid (the canonical URL contains it):
# https://suno.com/s/34nlQuwqbiaJXzo1
# → https://suno.com/song/<uuid>?sh=<share_id>
# The same `og:image` meta on the share page contains the uuid; you can
# also use playwright-cli to grab `<meta property="og:image">` directly.
UUID=5717194f-048e-4e92-8f4c-505a44ca3138
curl -sS -o song.mp3 "https://cdn1.suno.ai/${UUID}.mp3"
# Cover image (1200×630 og:image) is also public:
curl -sS -o cover.jpeg "https://cdn2.suno.ai/image_large_${UUID}.jpeg"After the pull, hand song.mp3 to the music-video skill at step 5
(STT → align scene timings) and skip steps 1-4 of that skill.
Writing Lyrics
Suno uses section tags in square brackets to structure songs. Place them on their own line before each section.
Section tags
| Tag | Purpose |
[Verse] | Main storytelling section |
[Chorus] | Repeated hook, usually the emotional peak |
[Pre-Chorus] | Build-up before the chorus |
[Bridge] | Contrasting section, usually once near the end |
[Outro] | Closing section |
[Intro] | Opening section (lyrical or descriptive) |
[Hook] | Short repeated phrase |
[Refrain] | Shorter repeated line within a verse |
[Instrumental] | Tells Suno to play an instrumental break here — no vocals |
[Solo] | Instrumental solo (guitar, sax, etc.) |
[Break] | Rhythmic or percussive break |
[Interlude] | Transitional passage |
[Spoken] | Spoken word delivery (not sung) |
[Whispered] | Whispered vocal delivery |
[Ad lib] | Free improvised vocal fills |
[Fade out] | Signals the song to fade at the end |
Vocal direction tags
You can add delivery hints inside the lyrics themselves:
(soft),(loud),(whispering),(screaming)— volume/intensity(harmonies),(echo),(choir)— texture(spoken),(rapped),(chanted)— delivery style(male vocal),(female vocal),(duet)— voice
Example lyrics
[Intro]
(soft guitar, ambient)
[Verse]
Salt in the air and rust on the crane,
the fishermen leave before the morning train.
Old radios hum through the fog and the grey,
singing the names of the ones who stayed.
[Chorus]
Glass harbour, glass harbour,
where the cold light bends,
where the sea keeps all the secrets
that the shore pretends.
[Instrumental]
[Verse 2]
A lighthouse blinks its one-eyed prayer,
a child draws boats on the kitchen stair.
[Bridge]
(whispered)
Everything returns to the water.
Everything returns.
[Outro]
(fade out)Tips for better vocals
- Keep lines to a natural spoken length — Suno matches syllables to melody
- Avoid punctuation mid-line; use line breaks instead
- Rhyme schemes don't have to be strict — half-rhymes work well
[Chorus]repeating the exact same text across the song makes it stick- Use
[Instrumental]for breathing room between sections
Writing Style Prompts (tags)
The tags field is a text-to-music prompt, not a keyword list. Write it like a producer brief: genres, instruments, tempo, production style, atmosphere, and a short narrative description of the track.
Structure
- Genre and sub-genre — be specific: "trip-hop" not just "hip hop"; "folk noir" not just "folk"
- BPM — e.g.
92 BPM,slow 68 BPM,uptempo 128 BPM - Instruments — list the key ones:
detuned Rhodes chords,bowed upright bass,slap bass - Production texture —
vinyl crackle intro,tape delay throws,sidechain pumping,analog tape saturation - Vocal style —
breathy lead vocal,half-spoken delivery,harmonized chorus,world-weary baritone - Atmosphere / mood —
nocturnal cityscape,minor key melancholy,rain-soaked streets - Narrative sentence — a short description of how the track unfolds
Example style prompts
Folk noir:
trip-hop, folk noir, coastal Americana, 74 BPM, fingerpicked acoustic guitar, bowed upright bass, sparse brushed snare, foghorn field recording, salt wind ambience, weathered male vocal, world-weary baritone, close-mic room reverb, minor pentatonic melody, mournful tone, open tuning resonance, subtle string swell on chorus, fading tape hiss outro. A sparse track built around fingerpicked guitar and bowed bass. The vocal sits close and unadorned over brushed percussion and field recordings of harbour wind. A restrained string swell lifts the chorus before the arrangement dissolves back into silence and tape hiss.
Synthwave:
cinematic synthwave, 80s retrowave, 110 BPM, analog polysynth arpeggios, driving gated snare, pulsing Moog bass, detuned pad layer, gated reverb on snare, vocoder harmonies, neon-lit melancholy, nocturnal highway atmosphere. A driving retrowave track that opens on a slow synth pad swell before the gated snare kicks in and the arpeggiator climbs. Vocoder harmonies glide over the chorus as the bass locks into a four-on-the-floor pulse.
Trip-hop / downtempo:
trip-hop, deep house, 92 BPM, sampled ferris wheel ambience, vinyl crackle intro, detuned Rhodes chords, wobbling sub-bass lead, broken kick pattern, shuffled rim clicks, breathy lead vocal, half-spoken delivery, harmonized chorus, tape delay throws, stereo spring reverb, sidechain pumping, analog tape saturation, minor key melancholy. Opens with crumbling drum machine grooves and detuned Rhodes over a pulsing sub-bass. Shuffled rim clicks and vinyl texture build into the chorus with harmonized vocals and tape delay. The bridge dissolves into a half-spoken reverie before returning to the hypnotic groove.
Tip: The narrative sentence at the end helps Suno understand the shape of the track — how energy builds and falls — not just the sound palette.
Parameters
| Parameter | Description |
lyrics | Full song text with section tags (see above) |
tags | Style prompt — genres, instruments, production, atmosphere, narrative sentence |
title | Song title |
make_instrumental | true to skip vocals entirely |
negative_prompt | Styles to avoid, e.g. "heavy metal, screaming" |
Output
Suno always generates two song variants from a single request. Both are equally valid. The helper script downloads both — local_files is the canonical list, local_file is a legacy alias for the first variant. Default behaviour for any agent: send both with their Suno preview URLs so the user can pick (see Quick Start step 3).
CLI Reference
generate_song.py — primary entry point
| Flag | Description |
--lyrics, -l | Full song text with section tags |
--tags, -t (required) | Style prompt (producer brief; see above) |
--title, -T (required) | Song title |
--instrumental, -i | Instrumental track (no vocals) |
--negative-prompt, -n | Styles to avoid, e.g. "heavy metal, screaming" |
--url | Override SUNO_MCP_URL env var |
--output-dir | Override SUNO_OUTPUT_DIR env var |
--timeout | Total timeout in seconds (default 400) |
--dry-run | Print constructed MCP request body, no API call |
download_from_mcp.py — re-download an existing song by ID
| Flag | Description |
song_id (positional) | Suno song UUID |
--url | Override SUNO_MCP_URL env var |
--output-dir, -o | Override SUNO_OUTPUT_DIR env var |
--max-wait, -w | Max seconds to wait for file availability (default 120) |
Dry-run (no API call, no Suno credits)
Pass --dry-run to print the constructed MCP request body and target endpoint
without contacting the server. Use during development to verify quoting /
argument shape:
python3 generate_song.py --dry-run \
--title 'Test Song' \
--tags 'trip-hop, 92 BPM' \
--lyrics '[Verse]\nHello world'Troubleshooting
- Connection refused / DNS error: verify
SUNO_MCP_URLresolves tohttp://suno-mcp.tail.ait4x.organd that the client has the intended Headscale route. On Thor's native execution node, use the command-scoped proxy settings shown above. HTTP 400 Bad Request: Missing session ID: the script's MCP client forgot to sendmcp-session-idafterinitialize. This shouldn't happen in the bundled client — if you see it, the script is stale, re-import.- Login required: the Suno MCP server needs a one-time Google login via the
suno_loginMCP tool. Connect to the server's noVNC URL and complete the OAuth dance; the session persists in the saved Chrome profile. - Wrong parameter name: Use
lyrics, notprompt(deprecated). - Timeout: The full pipeline takes 3–5 minutes; always set exec timeout ≥ 400 seconds.
- "No song IDs in response": the server returned a non-standard payload. Re-run; if it persists, call the
debug_browserMCP tool to inspect page state. - Only one variant in
local_files: bug. Both should always be present. Re-run. - 403 on direct CDN URL: harmless — the script falls back to the MCP-proxied
<base>/audio/<file>.mp3URL (and vice-versa).
Audio URL pattern
The audio URL is ${SUNO_MCP_URL}/audio/<short>.mp3. The script rebuilds it
from the configured server URL after every download_song call, ignoring any
host embedded in the server response that may be an internal bind address.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

