MIDI Music Composer

Use when the user asks to write, compose, make, or generate a song as an actual MIDI/instrumental artifact rather than lyrics or a Suno prompt. Creates original MIDI songs, melodies, chord progressions, website music, game music, ambient loops, and short title-based compositions.

Audits

Pass

Install

openclaw skills install midi-music-composer

Music Composer

Overview

Create a short original MIDI composition from a title. The skill turns the title into a stable musical world: genre, tempo, time signature, key, chord progression, instruments, sectional form, and one main melody owner.

Use the bundled generator for candidate artifacts, select the best-scoring candidate, then revise only within the same musical world unless the user asks for a different direction. When the user wants to improve taste, compare versions, or help the critic learn, use blind audition mode.

This skill is for producing a .mid file and manifest, not for writing lyrics or prompts for external music generators.

When to Use

  • The user asks Hermes to compose, generate, make, or write a song and appears to want an actual generated music file.
  • The user wants MIDI music, website music, game music, short instrumental cues, ambient loops, or title-based compositions.
  • The user provides a title and expects the agent to choose chords, meter, genre, and instruments.
  • The user says "write me a song" and then clarifies they want a MIDI/instrumental composition rather than lyrics.

Do not use this skill for full audio model generation, lyric writing, playlist curation, or music theory explanation unless the user also wants a generated MIDI composition.

If the user only says "write me a song" and does not specify lyrics vs MIDI, ask one short clarification: "Do you want lyrics, or should I generate a MIDI instrumental?" If this skill was explicitly invoked with /music-composer, assume MIDI and proceed.

Core Protocol

When making a song from scratch:

  1. Ask the user for a title if they did not provide one.
    • If they gave only a broad theme such as "love", make a simple title from it, such as "Love, Lightly Held", and continue unless they asked to choose the title themselves.
  2. Derive one stable musical world from the title:
    • chord progression
    • time signature
    • genre
    • tempo
    • key or mode
  3. Choose instruments that fit the title, chords, and genre.
  4. Keep the song close to 1 minute unless the user asks otherwise.
  5. End on a resolving tonic chord.
  6. Assign the main melody to exactly one instrument.
  7. Let other instruments provide harmony, bass, rhythm, texture, or supporting responses. They may intertwine with the lead, but they must not double the main melody at the same time.
  8. Prefer a miniature form: intro, A theme, B variation, A return, coda, resolution.
  9. After delivering the song, ask the user for a short opinion and record it as preference memory.

Default Workflow

  1. Convert the title into 3-5 mood words.
  2. Pick the genre and meter from those mood words.
  3. Pick a chord progression and harmonic strategy before writing any melody.
    • Candidate generation should explore different harmonic strategies: template color, borrowed chords, secondary dominant, pedal motion, passing diminished, and modal mixture.
  4. Choose one lead instrument for the main melody.
  5. Shape a motif through repetition, contrast, and return.
  6. Add accompaniment in this order: harmony, bass, rhythm, texture.
  7. Generate multiple candidates, a MIDI file, a composition JSON, and a manifest using scripts/generate_song.py.
  8. Run the critic on the manifest using scripts/critique_song.py.
  9. Check the manifest and critic output:
    • duration is roughly 60 seconds
    • form includes intro, A theme, B variation, A return, coda, and resolution
    • harmonic strategy creates color without losing tonic resolution
    • the coda avoids repeating the same phrase for the final four bars
    • final chord resolves to tonic
    • only one instrument owns main_melody
    • supporting instruments do not duplicate the main melody
  10. Deliver the MIDI path, manifest path, selected candidate, critic score, and a compact musical summary.
    • Include the selected harmonic strategy and chord progression.
    • Mention why the candidate was selected, for example: stronger harmony, cleaner coda, or better motif.
  11. Ask exactly one feedback question:
What did you think: 1-5? And should the next one be stranger, simpler, more emotional, or more rhythmic?
  1. When the user replies with feedback, record it with scripts/record_preference.py using the manifest path from the most recent generated song.
  2. Revise if the result feels cluttered, unresolved, too repetitive, or too generic.

Blind Audition Workflow

Use blind audition mode when the user wants to compare versions, rate candidates, calibrate the critic, or make the skill learn their taste.

  1. Generate 4 blind candidates:
python3 "${HERMES_SKILL_DIR}/scripts/generate_audition.py" "Title Goes Here" --out ./out --candidates 4 --preferences ~/.hermes/music-composer-preferences.json --render-audio
  1. Show only the label and playable files. Do not reveal score, genre, harmony, or critic metadata before the user rates them.
I made 4 blind versions of <title>. Listen in any order and rate each 1-5.

A: <midi path or audio path>
B: <midi path or audio path>
C: <midi path or audio path>
D: <midi path or audio path>

Send ratings like: A=4, B=2, C=5, D=3
  1. When the user responds, record the audition:
python3 "${HERMES_SKILL_DIR}/scripts/record_audition.py" "<audition_json_path>" --ratings "A=4,B=2,C=5,D=3" --opinion "<optional user notes>"
  1. Tell the user the winner, whether the critic agreed, and one thing the skill learned. Future generations should include the preference memory.

Tool Use

Generate and select the best of three candidates:

python3 "${HERMES_SKILL_DIR}/scripts/generate_song.py" "Title Goes Here" --out ./out --candidates 3

If ${HERMES_SKILL_DIR} is unavailable, first locate this skill directory under ~/.hermes/skills/music-composer.

The script writes:

  • a .mid file
  • a .json manifest describing title, genre, time signature, key, form, chords, instruments, duration, and melody ownership
  • a .composition.json intermediate composition plan
  • candidate score metadata, harmonic strategies, and chord progressions when --candidates is greater than 1

Critique the result:

python3 "${HERMES_SKILL_DIR}/scripts/critique_song.py" ./out/title-goes-here.json

Try to render WAV audio if local tools are installed:

python3 "${HERMES_SKILL_DIR}/scripts/render_audio.py" ./out/title-goes-here.mid

Record user feedback as preference memory:

python3 "${HERMES_SKILL_DIR}/scripts/record_preference.py" ./out/title-goes-here.json --opinion "4/5, liked the coda but the chords felt flat"

Generate a blind audition set:

python3 "${HERMES_SKILL_DIR}/scripts/generate_audition.py" "Title Goes Here" --out ./out --candidates 4 --preferences ~/.hermes/music-composer-preferences.json --render-audio

Record blind audition ratings:

python3 "${HERMES_SKILL_DIR}/scripts/record_audition.py" ./out/title-goes-here-audition-*/audition.json --ratings "A=4,B=2,C=5,D=3" --opinion "C had the best ending and stranger chords"

Use preference memory in future generation:

python3 "${HERMES_SKILL_DIR}/scripts/generate_song.py" "New Title" --out ./out --candidates 5 --preferences ~/.hermes/music-composer-preferences.json

For deeper composing guidance, read references/composer-protocol.md. For compact examples of good title-to-genre mappings, read references/song-recipes.json.

Research Mode

Use the repo-level research harness when the user asks to improve, optimize, evaluate, benchmark, or experiment with the music-composer skill itself.

Run a fixed evaluation:

python3 research/run_experiment.py --candidates 6 --label "experiment-name"

Create or refresh the current baseline:

python3 research/run_experiment.py --candidates 6 --label "baseline" --write-baseline

The harness writes:

  • research/runs/<run-id>/report.json
  • research/experiments.jsonl
  • optional research/baselines/current.json

When using research mode, make one focused change at a time, run the harness, compare against baseline, and keep changes only if the aggregate score improves without validation failures. Read research/program.md before making research-driven edits.

Common Pitfalls

  1. Do not let multiple instruments double the main melody. The manifest must have exactly one main_melody_owner.
  2. Do not end on a dominant, suspended, or unresolved chord. The final chord should be tonic.
  3. Do not switch genre or chord language midway through the piece.
  4. Do not treat the generator output as only prose. Return the generated .mid path and manifest summary.
  5. Do not ignore the critic if it flags repetitive pre-resolution bars.
  6. Do not make the user run preference commands manually. Ask for their opinion and record it yourself.
  7. Do not pick only safe diatonic harmony when the user asks for stranger or less flat chords.
  8. Do not change generator behavior without running the research harness when the task is explicitly about optimization or quality improvement.
  9. In blind audition mode, do not reveal candidate scores or musical metadata until after the user rates the versions.

Feedback Loop

After every delivered song, keep track of the manifest path in the conversation. Ask the user for a brief opinion:

What did you think: 1-5? And should the next one be stranger, simpler, more emotional, or more rhythmic?

When the user responds, call:

python3 "${HERMES_SKILL_DIR}/scripts/record_preference.py" "<last_manifest_path>" --opinion "<user feedback>"

Then acknowledge what was learned in one sentence. Future generations should include:

--preferences ~/.hermes/music-composer-preferences.json

For blind auditions, keep track of the audition.json path. After the user gives ratings, call record_audition.py. If the critic disagreed with the user's winner, say so plainly and treat that as calibration data rather than an error.

Response Style

When delivering a generated song, use this compact shape:

Made it: <title>

MIDI: <path>
Manifest: <path>
Composition plan: <path>

Selected candidate <n>/<count>: <genre>, <time signature>, <key>, <tempo> BPM
Harmony: <harmonic_strategy> using <chords>
Lead: <main_melody_owner>
Why this one: <one short reason from score/critic/candidate table>

What did you think: 1-5? And should the next one be stranger, simpler, more emotional, or more rhythmic?

Do not dump the full manifest unless the user asks. Do not ask multiple follow-up questions after delivery; keep feedback collection easy.

Verification Checklist

  • The song has a title.
  • The generated duration is roughly 55-65 seconds.
  • The manifest includes a clear miniature form.
  • The selected candidate includes harmonic color, unless the user asked for simple harmony.
  • The coda provides a distinct lead-in to the resolution.
  • The critic score is high, or any findings are explained.
  • If multiple candidates were generated, the selected candidate and score table are included.
  • The user was asked for an opinion after delivery.
  • The final chord is tonic.
  • Exactly one instrument owns the main melody.
  • Supporting instruments play harmony, bass, rhythm, texture, or responses rather than the lead melody.