ModalJazz

Use ModalJazz with an agent

ModalJazz has a built-in MCP server, mj-mcp. With it, an AI agent such as Claude Code reads and changes your scores. You ask in plain words, and the agent does the work.

The agent starts mj-mcp and talks to it over standard input and output. There is no network port. With the app closed, the tools change the score files. With the app open, they can change the scores in its windows, and you see each change at once.

Add mj-mcp to your agent

The app has mj-mcp in it, at this path:

/Applications/ModalJazz.app/Contents/MacOS/mj-mcp

The server takes no arguments. If the app is in another folder, change the path.

Claude Code

Run this command once in Terminal:

claude mcp add --scope user modaljazz -- /Applications/ModalJazz.app/Contents/MacOS/mj-mcp

--scope user gives the server to all your projects. Without it, only the current project gets it. claude mcp list shows the server, and /mcp in Claude Code shows its tools.

Claude Desktop

  1. In Claude Desktop, open Settings > Developer, and click Edit Config. This opens claude_desktop_config.json.
  2. Add the server under mcpServers:
    {
      "mcpServers": {
        "modaljazz": {
          "command": "/Applications/ModalJazz.app/Contents/MacOS/mj-mcp"
        }
      }
    }
  3. Quit Claude Desktop and open it again.

Other agents

Any MCP client that starts a local server over standard input and output (the stdio transport) can use mj-mcp. Give the path above as the command, with no arguments.

Work in the open app

Type :set agent on in the app once. The app keeps this setting. Then a tool call on a score that is open in the app changes the score in its window:

  • The agent names the score by its path, its file name (prelude.mj), or its window title (Untitled for a new score).
  • While an agent is connected, the windows show a small "Agent connected" banner.
  • Cmd-Z (or u) removes the changes of one agent request.
  • The save tool saves the score in the app. A new score needs a path.
  • A score that is not open in the app changes in its file.

The app listens on a Unix socket in ~/Library/Application Support/ModalJazz/agent.sock. Only your user can use it. :set agent off closes it.

Ask for changes

Give the path of the score in your request. For example:

  • "Start a new jazz band score in ~/Scores/blues.mj."
  • "Show me measures 1-8 of ~/Scores/prelude.mj."
  • "In ~/Scores/prelude.mj, put measures 5-8 up an octave and save."
  • "Write a C major scale in quarter notes in measures 1-2 of the right hand."
  • "Add a D.C. al Fine at the end of measure 16, and Fine at measure 8."

The changes stay in memory until the agent calls save. Each tool call that changes the score is one undo step.

Example: enter a score from a PDF

This example enters Twinkle, Twinkle, Little Star (a traditional tune) from a PDF with Claude Code. Agents that can read a PDF, or an image of a page, can do this.

  1. You ask:

    > Make a piano score ~/Scores/twinkle.mj from ~/Downloads/twinkle.pdf.
  2. The agent makes the file with new_score, and reads the PDF. Then it calls text_format to learn the score text.

  3. The agent writes the music with write_measures, measures 1-4:

    m1: time=4/4 tempo="Moderato",q=96
    m1 P1.1: C4:q C4:q G4:q G4:q
    m1 P1.2: C3:h E3+G3:h
    m2 P1.1: A4:q A4:q G4:h
    m2 P1.2: F3+A3:h E3+G3:h
    m3 P1.1: F4:q F4:q E4:q E4:q
    m3 P1.2: D3+F3:h C3+E3:h
    m4 P1.1: D4:q D4:q C4:h
    m4 P1.2: G2+G3:h C3:h
  4. The agent runs : commands with run_command: :title Twinkle, Twinkle, Little Star, :4 barline |., and :5-8 bars delete (the new score has eight measures).

  5. The agent calls read_measures and compares the result with the PDF. Then it calls save.

Twinkle, Twinkle, Little Star: four measures for piano

With :set agent on and a new score open in the app, you can ask for the same work in the Untitled window, and see each step.

A long score works best a page or a system at a time: write, read back, and compare. The transcribe-pdf recipe gives the agent all the steps.

The tools

The agent sees these tools and their descriptions. Arguments in bold are required.

Each tool on a score takes file: The path of the score file: .mj, .musicxml, .xml, or .mxl. If the score is open in the ModalJazz app (with :set agent on), the tools change it in its window: there the file name or the window title (Untitled for a new score) also works.

score_summary

Shows the title, the composer, the parts and their staves, the number of measures, the key, the time, and the selection. It also shows each text (title block, copyright, credits, cover) and each page setting as the : command that sets it (| for a new line, {italic} for a style), to change and run with run_command.

file
The score. See file.

read_measures

Shows measures as compact score text: one line for each measure and staff, for example m5 P1.1: C5:q D5:q E5:h. Call text_format for the form of the text.

file
The score. See file.
measures optional
5 or 5-8, counted from 1. The default is all measures.
staves optional
Staff labels with commas: P1,P2.1. P2 is part 2; P1.2 is staff 2 of part 1. score_summary shows the parts.

write_measures

Writes compact score text over measures, as one undo step. Each line of the text must be in the measures. A staff with no line in the text does not change. Call text_format for the form of the text. The selection ends.

file
The score. See file.
measures
5 or 5-8, counted from 1.
text
The compact score text.

run_command

Runs one : command, as one undo step. A measure range can come first: :5-8 transpose +P8. A staff label of score_summary can come before it, for a command on that part or staff (:instrument acts on one part): :P5 instrument brace off, :P1.2 4 clef bass. With no label, the command acts on the staff of the cursor (P1 at the start). With no range, the command acts on the selection (see select), or on the measure of the cursor (measure 1 at the start; :5 moves it to measure 5). The commands: time, pickup, key, clef, bars, barline, repeat, volta, segno, coda, tocoda, fine, dc, ds, rehearsal, section, break, pagebreak, numbers, hide, show, transpose, tempo, title, subtitle, composer, lyricist, arranger, copyright, credits, cover, new, instrument, set, notation, notehead, slur, artic, bow, ornament, tuplet, cue, tremolo, hairpin, text. :set takes the settings of the score (firstpage, font, staffsize, staffdistance, systemdistance, hairpin, fingering, names, chords, keynaturals, copyright, paper, mmrest, octavecourtesy, brackets, hideempty, repeatwings, concert). Commands only for the app window (run_command refuses them): w, e, q, wq, x, export, part, score, speed, solo, mute, unmute, loop, chords, lyrics, tutor, map, keys. Call list_commands for what each command and setting does.

file
The score. See file.
command
The command, for example :key Eb.

select

Selects measures. The commands of run_command with no measure range then act on the selection. With staves, the selection is a time range on those staves (and the staves between them); with no staves, it is whole measures on all staves.

file
The score. See file.
measures
5 or 5-8, counted from 1, or none to end the selection.
staves optional
Staff labels with commas: P1,P2.1. P2 is part 2; P1.2 is staff 2 of part 1. score_summary shows the parts.

check_collisions

Lists the marks that overlap notes or other marks on the pages, one line for each: the page, the measure, and the two objects with their staves, for example p1 m2: dynamic p (P4) / tempo mark (P5.1). The layout moves staves apart and breaks hairpins to keep marks clear, so the list shows what is left. Call it after the music and the marks are in, and fix what it lists with run_command or write_measures (for example another side or time for a mark).

file
The score. See file.

layout

Lists the systems of each page, one line for each page: the measures of each system, with (break) or (page break) after a break set with :break or :pagebreak, for example p3: m37-40 (break), m41-44. The other system ends come from the layout. A measure line of read_measures shows a set break as break or pagebreak, and write_measures sets and clears them.

file
The score. See file.

undo

Undoes the last change: one tool call that changed the score.

file
The score. See file.

save

Writes the score to its file. The changes of the other tools stay in memory until a save. With to, it writes a copy in the format of the extension (.mj, .musicxml, .xml, .mxl, .svg, or .pdf) and does not change the file of the score: a later save with no to still writes file. A score in the app with no file yet saves to a .mj path in to.

file
The score. See file.
to optional
A path for a copy. The default is file.

new_score

Writes a new score from a template to a new file, with eight empty measures. The file must not exist yet. The extension gives the format. The other tools can then change the score. The templates: piano, string-orchestra, full-orchestra, concert-band, jazz-band, choir, choir-piano, woodwind-quintet.

file
The score. See file.
template optional
The template. The default is piano.

list_commands

Lists the : commands of run_command, with what each one does.

text_format

Describes the compact score text of read_measures and write_measures.

guide

Gives the recipes for jobs with more than one step, for example the copy of a PDF score. With no name, it lists the recipes. With a name, it gives the steps of that recipe, and tells which programs of the recipe are installed.

name optional
The name of a recipe, for example transcribe-pdf.

Limits

  • The tools take no key commands. They use : commands and the score text.
  • The : commands that need the app (files, windows, playback, and entry modes) do not work in mj-mcp. The list_commands tool shows the commands that work.
  • A file with no unsaved changes in the app opens again when it changes on disk, for example after mj write.