Tool tree
gradeNot graded
get_project_stateAnswer
Use this when you need a concise overview of the live Duet project before choosing an edit. Returns tempo, key, mode, chord track, selection and per-track note summaries without flooding context with every note.
View tool JSON
{
"name": "get_project_state",
"kind": "answer",
"impl": "imperative",
"description": "Use this when you need a concise overview of the live Duet project before choosing an edit. Returns tempo, key, mode, chord track, selection and per-track note summaries without flooding context with every note.",
"inputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
}get_selectionAnswer
Use this when you need the exact notes and chord context inside the bars currently selected by the person.
View tool JSON
{
"name": "get_selection",
"kind": "answer",
"impl": "imperative",
"description": "Use this when you need the exact notes and chord context inside the bars currently selected by the person.",
"inputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
}analyze_harmonyAction
Use this when you need deterministic harmonic analysis of a selected or explicit bar range. Duet computes chord functions and scale fit with tonal instead of guessing.
View tool JSON
{
"name": "analyze_harmony",
"kind": "act",
"impl": "imperative",
"description": "Use this when you need deterministic harmonic analysis of a selected or explicit bar range. Duet computes chord functions and scale fit with tonal instead of guessing.",
"inputSchema": {
"type": "object",
"properties": {
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
}
},
"required": [],
"additionalProperties": false
}
}set_selectionAction
Use this when you want to visibly focus the person's editor on a track and bar range before reading or changing it. This changes only the shared cursor, not the music.
View tool JSON
{
"name": "set_selection",
"kind": "act",
"impl": "imperative",
"description": "Use this when you want to visibly focus the person's editor on a track and bar range before reading or changing it. This changes only the shared cursor, not the music.",
"inputSchema": {
"type": "object",
"properties": {
"trackId": {
"type": "string",
"enum": [
"melody",
"bass",
"chords"
]
},
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
}
},
"required": [
"trackId",
"startBar",
"endBar"
],
"additionalProperties": false
}
}set_chord_progressionAction
Use this when the person asks for a chord progression. Replaces consecutive chord slots from startBar, validates every symbol, and creates audible block or arpeggiated chord notes.
View tool JSON
{
"name": "set_chord_progression",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person asks for a chord progression. Replaces consecutive chord slots from startBar, validates every symbol, and creates audible block or arpeggiated chord notes.",
"inputSchema": {
"type": "object",
"properties": {
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"chords": {
"type": "array",
"minItems": 1,
"maxItems": 16,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 16
}
},
"voicing": {
"type": "string",
"enum": [
"block",
"arpeggio"
]
},
"mode": {
"type": "string",
"enum": [
"draft",
"apply"
],
"description": "draft (default): show the result as a ghost preview the person accepts or discards on the page; apply: write immediately because the person explicitly asked for that."
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"startBar",
"chords"
],
"additionalProperties": false
}
}add_notesAction
Use this when you know the exact notes to add to melody, bass, or chords. Note names and beat positions are validated and converted to Duet's internal ticks.
View tool JSON
{
"name": "add_notes",
"kind": "act",
"impl": "imperative",
"description": "Use this when you know the exact notes to add to melody, bass, or chords. Note names and beat positions are validated and converted to Duet's internal ticks.",
"inputSchema": {
"type": "object",
"properties": {
"trackId": {
"type": "string",
"enum": [
"melody",
"bass",
"chords"
]
},
"notes": {
"type": "array",
"minItems": 1,
"maxItems": 128,
"items": {
"type": "object",
"properties": {
"pitchName": {
"type": "string",
"minLength": 2,
"maxLength": 8
},
"startBeat": {
"type": "number",
"minimum": 0,
"maximum": 64
},
"durationBeats": {
"type": "number",
"minimum": 0.0625,
"maximum": 64
},
"velocity": {
"type": "integer",
"minimum": 1,
"maximum": 127
}
},
"required": [
"pitchName",
"startBeat",
"durationBeats"
],
"additionalProperties": false
}
},
"mode": {
"type": "string",
"enum": [
"draft",
"apply"
],
"description": "draft (default): show the result as a ghost preview the person accepts or discards on the page; apply: write immediately because the person explicitly asked for that."
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"trackId",
"notes"
],
"additionalProperties": false
}
}transform_selectionAction
Use this when the person asks to transpose, change mode, quantize, or humanize the currently selected notes. Mode changes preserve melodic contour with deterministic tonal mapping.
View tool JSON
{
"name": "transform_selection",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person asks to transpose, change mode, quantize, or humanize the currently selected notes. Mode changes preserve melodic contour with deterministic tonal mapping.",
"inputSchema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": [
"transpose",
"change_mode",
"quantize",
"humanize"
]
},
"amount": {
"type": "number",
"minimum": -24,
"maximum": 60
},
"targetMode": {
"type": "string",
"enum": [
"major",
"minor",
"dorian",
"phrygian",
"lydian",
"mixolydian",
"locrian"
]
},
"mode": {
"type": "string",
"enum": [
"draft",
"apply"
],
"description": "draft (default): show the result as a ghost preview the person accepts or discards on the page; apply: write immediately because the person explicitly asked for that."
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"operation"
],
"additionalProperties": false
}
}generate_lineAction
Use this when the person asks Duet to write a bass, counter melody, or pad over existing chords. Generation follows deterministic chord-tone and voice-leading rules.
View tool JSON
{
"name": "generate_line",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person asks Duet to write a bass, counter melody, or pad over existing chords. Generation follows deterministic chord-tone and voice-leading rules.",
"inputSchema": {
"type": "object",
"properties": {
"role": {
"type": "string",
"enum": [
"bass",
"counter_melody",
"pad"
]
},
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
},
"style": {
"type": "string",
"enum": [
"simple",
"flowing",
"syncopated"
]
},
"mode": {
"type": "string",
"enum": [
"draft",
"apply"
],
"description": "draft (default): show the result as a ghost preview the person accepts or discards on the page; apply: write immediately because the person explicitly asked for that."
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"role",
"startBar",
"endBar"
],
"additionalProperties": false
}
}set_tempoAction
Use this when the person asks to change playback speed. Duet safely clamps the requested tempo to 40–220 BPM and reports the applied value.
View tool JSON
{
"name": "set_tempo",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person asks to change playback speed. Duet safely clamps the requested tempo to 40–220 BPM and reports the applied value.",
"inputSchema": {
"type": "object",
"properties": {
"bpm": {
"type": "number",
"minimum": -1000,
"maximum": 1000
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"bpm"
],
"additionalProperties": false
}
}playAction
Use this when the person asks to listen to the project or a bar range. Starts Duet's existing browser playback; if sound has not been unlocked, returns a clear user-action request.
View tool JSON
{
"name": "play",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person asks to listen to the project or a bar range. Starts Duet's existing browser playback; if sound has not been unlocked, returns a clear user-action request.",
"inputSchema": {
"type": "object",
"properties": {
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
},
"loop": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}
}get_recent_activityAnswer
Use this at the start of a turn to see what the person did on the page since you last looked: recorded takes, notes added or deleted, chords set, selection moves, undo, drafts they accepted or discarded. Lets you react to their playing instead of asking.
View tool JSON
{
"name": "get_recent_activity",
"kind": "answer",
"impl": "imperative",
"description": "Use this at the start of a turn to see what the person did on the page since you last looked: recorded takes, notes added or deleted, chords set, selection moves, undo, drafts they accepted or discarded. Lets you react to their playing instead of asking.",
"inputSchema": {
"type": "object",
"properties": {
"sinceStateVersion": {
"type": "integer",
"minimum": 0,
"maximum": 1000000
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 40
}
},
"required": [],
"additionalProperties": false
}
}suggest_progressionsAction
Use this when the person describes a feeling (happy, sad, dreamy, tense, epic, jazzy, calm) instead of chord names. Returns chord progressions realized in the project's key with a one-line reason each, so you can offer choices in plain words or install one with set_chord_progression / propose_variations.
View tool JSON
{
"name": "suggest_progressions",
"kind": "act",
"impl": "imperative",
"description": "Use this when the person describes a feeling (happy, sad, dreamy, tense, epic, jazzy, calm) instead of chord names. Returns chord progressions realized in the project's key with a one-line reason each, so you can offer choices in plain words or install one with set_chord_progression / propose_variations.",
"inputSchema": {
"type": "object",
"properties": {
"mood": {
"type": "string",
"enum": [
"happy",
"sad",
"dreamy",
"tense",
"epic",
"jazzy",
"calm"
]
},
"bars": {
"type": "integer",
"minimum": 1,
"maximum": 16
}
},
"required": [
"mood"
],
"additionalProperties": false
}
}propose_variationsAction
Use this to let the person choose by ear. Creates 2–3 alternative drafts for the same bars (chords by mood, or bass / pad / counter melody in different styles, or answers to a phrase). Each appears on the page as a lettered option with Listen / Accept / Discard; nothing is written until one is accepted.
View tool JSON
{
"name": "propose_variations",
"kind": "act",
"impl": "imperative",
"description": "Use this to let the person choose by ear. Creates 2–3 alternative drafts for the same bars (chords by mood, or bass / pad / counter melody in different styles, or answers to a phrase). Each appears on the page as a lettered option with Listen / Accept / Discard; nothing is written until one is accepted.",
"inputSchema": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"chords",
"bass",
"pad",
"counter_melody",
"answer"
]
},
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
},
"count": {
"type": "integer",
"minimum": 2,
"maximum": 3
},
"moods": {
"type": "array",
"minItems": 1,
"maxItems": 3,
"items": {
"type": "string",
"enum": [
"happy",
"sad",
"dreamy",
"tense",
"epic",
"jazzy",
"calm"
]
}
},
"styles": {
"type": "array",
"minItems": 1,
"maxItems": 3,
"items": {
"type": "string",
"maxLength": 16
}
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"kind",
"startBar",
"endBar"
],
"additionalProperties": false
}
}answer_phraseAction
Call and response. Takes the phrase the person just played or selected on the Melody track and writes an answering phrase in the following bars: same rhythm, moved through the key (echo, sequence, invert or contrast), landing on chord tones. Defaults to the last recorded take, then the selection. Returns a draft the person can hear and accept.
View tool JSON
{
"name": "answer_phrase",
"kind": "act",
"impl": "imperative",
"description": "Call and response. Takes the phrase the person just played or selected on the Melody track and writes an answering phrase in the following bars: same rhythm, moved through the key (echo, sequence, invert or contrast), landing on chord tones. Defaults to the last recorded take, then the selection. Returns a draft the person can hear and accept.",
"inputSchema": {
"type": "object",
"properties": {
"sourceStartBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"sourceEndBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
},
"targetStartBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"answerBars": {
"type": "integer",
"minimum": 1,
"maximum": 4
},
"style": {
"type": "string",
"enum": [
"echo",
"sequence",
"invert",
"contrast"
]
},
"mode": {
"type": "string",
"enum": [
"draft",
"apply"
],
"description": "draft (default): show the result as a ghost preview the person accepts or discards on the page; apply: write immediately because the person explicitly asked for that."
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [],
"additionalProperties": false
}
}resolve_draftAction
Accept or discard drafts you proposed. Use after the person tells you which option they like; accepting writes it to the song as a normal undoable change and discards only its rival options (same group), so options for other bars or tracks stay available. Without draftId, acts on the option currently previewed on the page.
View tool JSON
{
"name": "resolve_draft",
"kind": "act",
"impl": "imperative",
"description": "Accept or discard drafts you proposed. Use after the person tells you which option they like; accepting writes it to the song as a normal undoable change and discards only its rival options (same group), so options for other bars or tracks stay available. Without draftId, acts on the option currently previewed on the page.",
"inputSchema": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"accept",
"discard",
"discard_all"
]
},
"draftId": {
"type": "string",
"maxLength": 32
}
},
"required": [
"action"
],
"additionalProperties": false
}
}set_sectionsAction
Label parts of the song (Intro, Verse, Chorus…) on the bar ruler so you and the person can talk about 'the chorus' instead of bar numbers. Replaces all labels; each starts at a bar and runs until the next.
View tool JSON
{
"name": "set_sections",
"kind": "act",
"impl": "imperative",
"description": "Label parts of the song (Intro, Verse, Chorus…) on the bar ruler so you and the person can talk about 'the chorus' instead of bar numbers. Replaces all labels; each starts at a bar and runs until the next.",
"inputSchema": {
"type": "object",
"properties": {
"sections": {
"type": "array",
"minItems": 0,
"maxItems": 8,
"items": {
"type": "object",
"properties": {
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 24
}
},
"required": [
"startBar",
"name"
],
"additionalProperties": false
}
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"sections"
],
"additionalProperties": false
}
}set_instrumentAction
Change the sound of a track: piano, epiano, strings, pad, bass or pluck. Cheap and instantly audible; good when the person says 'softer', 'warmer' or 'like strings'.
View tool JSON
{
"name": "set_instrument",
"kind": "act",
"impl": "imperative",
"description": "Change the sound of a track: piano, epiano, strings, pad, bass or pluck. Cheap and instantly audible; good when the person says 'softer', 'warmer' or 'like strings'.",
"inputSchema": {
"type": "object",
"properties": {
"trackId": {
"type": "string",
"enum": [
"melody",
"bass",
"chords"
]
},
"instrument": {
"type": "string",
"enum": [
"piano",
"epiano",
"strings",
"pad",
"bass",
"pluck"
]
},
"expectedStateVersion": {
"type": "integer",
"minimum": 0,
"description": "Optional stateVersion you last read; the call is rejected if the person changed the page since."
}
},
"required": [
"trackId",
"instrument"
],
"additionalProperties": false
}
}describe_selectionAnswer
Use this when the person says something is missing or asks what could be better but cannot say what. Returns a deterministic plain-language diagnosis of the selected bars (or a given range): empty tracks, missing or static chords, a melody that circles or leaps, notes clashing with their chord or outside the key, each with a suggested tool call. Read it, then offer choices.
View tool JSON
{
"name": "describe_selection",
"kind": "answer",
"impl": "imperative",
"description": "Use this when the person says something is missing or asks what could be better but cannot say what. Returns a deterministic plain-language diagnosis of the selected bars (or a given range): empty tracks, missing or static chords, a melody that circles or leaps, notes clashing with their chord or outside the key, each with a suggested tool call. Read it, then offer choices.",
"inputSchema": {
"type": "object",
"properties": {
"startBar": {
"type": "integer",
"minimum": 0,
"maximum": 15
},
"endBar": {
"type": "integer",
"minimum": 1,
"maximum": 16
}
},
"required": [],
"additionalProperties": false
}
}