{"ok":true,"site":{"host":"tonic.stranica.workers.dev","url":"https://tonic.stranica.workers.dev/","type":"live","desc":"Learn piano fundamentals on your computer keyboard or a MIDI piano, with your own AI agent as the tutor. Built on WebMCP. Nothing you play leaves your browser.","tools":[{"name":"get_started","kind":"answer","impl":"imperative","description":"Call this first when teaching. Returns a small session brief with the teaching rules and exactly one recommended next tool call, including ready-to-use input.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_teaching_guide","kind":"answer","impl":"imperative","description":"How to teach with this page: nine short rules on order, pacing by score, wording for beginners, songs, free play and saving. Read once per session.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_app_state","kind":"answer","impl":"imperative","description":"Current UI state: mode, running exercise and progress, latest result, tempo, input instrument and highlighted keys. Use get_started for the first call; use this whenever the page state is unclear.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_keyboard_layout","kind":"answer","impl":"imperative","description":"Which computer keys play which notes. The student plays the piano on their typing keyboard: home row A S D F G H J K L ; ' are the white keys, W E T Y U O P the black keys, Z and X shift the octave. Use this to give instructions like \"press A for C4\".","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_input_status","kind":"answer","impl":"imperative","description":"Which instrument the student is playing on: computer keyboard or a connected MIDI keyboard / digital piano, with playable range and polyphony. Adapt exercises to it: keep computer-keyboard drills within the range and to triads; a MIDI piano can do two hands and wide arpeggios.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_practice_log","kind":"answer","impl":"imperative","description":"Past practice sessions and recent attempts with scores, newest first. Use it to pick up where the student left off and to notice trends.","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"limit":{"type":"integer","description":"Sessions to return, default 10."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_attempt_results","kind":"answer","impl":"imperative","description":"Full results of an attempt: notes hit and missed, timing offsets in milliseconds with early/late tendency, and per-prompt answers for find_note and ear_training. Defaults to the latest attempt. Call it after the student says they have finished an exercise.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"attempt_id":{"type":"string","description":"Omit for the latest attempt."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"show_on_keyboard","kind":"act","impl":"imperative","description":"Light up keys on the on-screen piano with a caption, and optionally sound them. Give notes, a chord symbol, or a scale. Good for \"this is C major\", \"here is a G7 chord\", or pointing out a single key.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"notes":{"type":"array","items":{"type":"string"},"description":"Note names like [\"C4\",\"E4\",\"G4\"]."},"chord":{"type":"string","description":"Chord symbol like \"Cmaj7\", \"Am\", \"G7\", \"C/E\"."},"scale_root":{"type":"string","description":"Scale root like \"D4\" (use with scale_mode)."},"scale_mode":{"type":"string","description":"major, minor, blues, ..."},"caption":{"type":"string","description":"Short label shown above the keyboard."},"play":{"type":"boolean","description":"Also sound the notes (chords together, scales in sequence)."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"clear_keyboard","kind":"act","impl":"imperative","description":"Remove highlights and captions from the on-screen piano and stop any reference playback.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"play_reference","kind":"act","impl":"imperative","description":"Play something for the student to hear, lighting up keys as it plays: a scale, a chord progression, a melody or a rhythm. Same parameters as start_exercise. Returns right away; playback runs for `duration_seconds`.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"kind":{"type":"string","enum":["scale","chords","melody","rhythm","find_note","ear_training","song"],"description":"scale, chords, melody and rhythm are timed with a metronome. find_note and ear_training are prompt-by-prompt."},"name":{"type":"string","description":"Short title shown to the student."},"bpm":{"type":"number","description":"Tempo 30–240. Beginners: 50–70."},"root":{"type":"string","description":"scale: root like \"C4\" or \"F#3\". ear_training: reference note (default C4)."},"mode":{"type":"string","description":"scale: major, minor, harmonic_minor, melodic_minor, major_pentatonic, minor_pentatonic, blues, dorian, mixolydian, lydian, phrygian, chromatic."},"octaves":{"type":"integer","minimum":1,"maximum":3,"description":"scale: default 1."},"direction":{"type":"string","enum":["up","down","up_down"],"description":"scale: default up_down."},"note_value":{"type":"string","enum":["quarter","eighth","half"],"description":"scale: beats per note, default quarter."},"progression":{"type":"array","items":{"type":"string"},"description":"chords: chord symbols (C, Am, G7, Fmaj7, C/E) or roman numerals (I, ii, V7, vii°). Numerals need `key`."},"key":{"type":"string","description":"chords: key for roman numerals, e.g. \"G\" or \"A minor\"."},"beats_per_chord":{"type":"number","description":"chords: default 4."},"notes":{"type":"array","items":{"type":"string"},"description":"melody: note names in order. rhythm: the single note to tap (default C4). find_note: exact notes to ask for."},"rhythm":{"type":"array","items":{"type":"number"},"description":"melody / rhythm: beats per note, e.g. [1, 1, 0.5, 0.5, 2]."},"melody":{"type":"string","description":"melody: built-in tune id: ode_to_joy, twinkle, mary."},"count":{"type":"integer","description":"find_note / ear_training: number of prompts, default 5."},"show_hints":{"type":"boolean","description":"find_note: light up the answer key."},"intervals":{"type":"array","items":{"type":"string"},"description":"ear_training: intervals to draw from: m2 M2 m3 M3 P4 TT P5 m6 M6 m7 M7 P8."},"low":{"type":"string","description":"find_note: lowest note to ask for (default C4)."},"high":{"type":"string","description":"find_note: highest note to ask for (default B4)."},"include_black_keys":{"type":"boolean","description":"find_note: also ask for sharps and flats. Default false (white keys only)."},"song_id":{"type":"string","description":"song: id from search_songs, e.g. \"fur_elise\"."},"section":{"type":"string","description":"song: section id from get_song, or \"all\" for the whole piece. Default: first section."},"hands":{"type":"string","enum":["right","left","both"],"description":"song: default right. \"both\" only where get_song shows a left-hand part."},"tempo_percent":{"type":"number","minimum":30,"maximum":150,"description":"song: percent of the song tempo. Start learners at 60–70."},"path_step":{"type":"string","description":"Learning-path step id from get_learning_paths. Pass path exercises unchanged so progress is tracked."}},"required":["kind"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"set_metronome","kind":"act","impl":"imperative","description":"Set the practice tempo and switch the free-running metronome on or off. Exercises use their own bpm and count in one bar automatically.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"bpm":{"type":"number","description":"30–240"},"on":{"type":"boolean"}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"update_settings","kind":"act","impl":"imperative","description":"Toggle the app's sound, the key-letter labels on the on-screen piano, or shift which octave the computer keyboard plays (-2 to 2; 0 means A = C4).","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"sound":{"type":"boolean"},"show_key_labels":{"type":"boolean"},"octave_shift":{"type":"integer","minimum":-2,"maximum":2}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"start_exercise","kind":"act","impl":"imperative","description":"Start an exercise on screen for the student to play on their computer keyboard or MIDI keyboard. Timed kinds (scale, chords, melody, rhythm) count in one bar with clicks, light up each target key in time, and end on their own. Untimed kinds (find_note, ear_training) go prompt by prompt. Returns immediately. When the student says they are done, call get_attempt_results. Keep beginners at 50–70 bpm and within the playable range from get_input_status. For a song from the library use kind \"song\" with song_id, a section id (or \"all\"), hands and tempo_percent.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"kind":{"type":"string","enum":["scale","chords","melody","rhythm","find_note","ear_training","song"],"description":"scale, chords, melody and rhythm are timed with a metronome. find_note and ear_training are prompt-by-prompt."},"name":{"type":"string","description":"Short title shown to the student."},"bpm":{"type":"number","description":"Tempo 30–240. Beginners: 50–70."},"root":{"type":"string","description":"scale: root like \"C4\" or \"F#3\". ear_training: reference note (default C4)."},"mode":{"type":"string","description":"scale: major, minor, harmonic_minor, melodic_minor, major_pentatonic, minor_pentatonic, blues, dorian, mixolydian, lydian, phrygian, chromatic."},"octaves":{"type":"integer","minimum":1,"maximum":3,"description":"scale: default 1."},"direction":{"type":"string","enum":["up","down","up_down"],"description":"scale: default up_down."},"note_value":{"type":"string","enum":["quarter","eighth","half"],"description":"scale: beats per note, default quarter."},"progression":{"type":"array","items":{"type":"string"},"description":"chords: chord symbols (C, Am, G7, Fmaj7, C/E) or roman numerals (I, ii, V7, vii°). Numerals need `key`."},"key":{"type":"string","description":"chords: key for roman numerals, e.g. \"G\" or \"A minor\"."},"beats_per_chord":{"type":"number","description":"chords: default 4."},"notes":{"type":"array","items":{"type":"string"},"description":"melody: note names in order. rhythm: the single note to tap (default C4). find_note: exact notes to ask for."},"rhythm":{"type":"array","items":{"type":"number"},"description":"melody / rhythm: beats per note, e.g. [1, 1, 0.5, 0.5, 2]."},"melody":{"type":"string","description":"melody: built-in tune id: ode_to_joy, twinkle, mary."},"count":{"type":"integer","description":"find_note / ear_training: number of prompts, default 5."},"show_hints":{"type":"boolean","description":"find_note: light up the answer key."},"intervals":{"type":"array","items":{"type":"string"},"description":"ear_training: intervals to draw from: m2 M2 m3 M3 P4 TT P5 m6 M6 m7 M7 P8."},"low":{"type":"string","description":"find_note: lowest note to ask for (default C4)."},"high":{"type":"string","description":"find_note: highest note to ask for (default B4)."},"include_black_keys":{"type":"boolean","description":"find_note: also ask for sharps and flats. Default false (white keys only)."},"song_id":{"type":"string","description":"song: id from search_songs, e.g. \"fur_elise\"."},"section":{"type":"string","description":"song: section id from get_song, or \"all\" for the whole piece. Default: first section."},"hands":{"type":"string","enum":["right","left","both"],"description":"song: default right. \"both\" only where get_song shows a left-hand part."},"tempo_percent":{"type":"number","minimum":30,"maximum":150,"description":"song: percent of the song tempo. Start learners at 60–70."},"path_step":{"type":"string","description":"Learning-path step id from get_learning_paths. Pass path exercises unchanged so progress is tracked."}},"required":["kind"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"set_practice_plan","kind":"act","impl":"imperative","description":"Replace the student's practice plan shown in the app. Each item can carry an exercise spec so the student can start it with one click. Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"title":{"type":"string","description":"e.g. \"This week: C major and first chords\""},"items":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"detail":{"type":"string","description":"Why, or what to focus on."},"exercise":{"type":"object","properties":{"kind":{"type":"string","enum":["scale","chords","melody","rhythm","find_note","ear_training","song"],"description":"scale, chords, melody and rhythm are timed with a metronome. find_note and ear_training are prompt-by-prompt."},"name":{"type":"string","description":"Short title shown to the student."},"bpm":{"type":"number","description":"Tempo 30–240. Beginners: 50–70."},"root":{"type":"string","description":"scale: root like \"C4\" or \"F#3\". ear_training: reference note (default C4)."},"mode":{"type":"string","description":"scale: major, minor, harmonic_minor, melodic_minor, major_pentatonic, minor_pentatonic, blues, dorian, mixolydian, lydian, phrygian, chromatic."},"octaves":{"type":"integer","minimum":1,"maximum":3,"description":"scale: default 1."},"direction":{"type":"string","enum":["up","down","up_down"],"description":"scale: default up_down."},"note_value":{"type":"string","enum":["quarter","eighth","half"],"description":"scale: beats per note, default quarter."},"progression":{"type":"array","items":{"type":"string"},"description":"chords: chord symbols (C, Am, G7, Fmaj7, C/E) or roman numerals (I, ii, V7, vii°). Numerals need `key`."},"key":{"type":"string","description":"chords: key for roman numerals, e.g. \"G\" or \"A minor\"."},"beats_per_chord":{"type":"number","description":"chords: default 4."},"notes":{"type":"array","items":{"type":"string"},"description":"melody: note names in order. rhythm: the single note to tap (default C4). find_note: exact notes to ask for."},"rhythm":{"type":"array","items":{"type":"number"},"description":"melody / rhythm: beats per note, e.g. [1, 1, 0.5, 0.5, 2]."},"melody":{"type":"string","description":"melody: built-in tune id: ode_to_joy, twinkle, mary."},"count":{"type":"integer","description":"find_note / ear_training: number of prompts, default 5."},"show_hints":{"type":"boolean","description":"find_note: light up the answer key."},"intervals":{"type":"array","items":{"type":"string"},"description":"ear_training: intervals to draw from: m2 M2 m3 M3 P4 TT P5 m6 M6 m7 M7 P8."},"low":{"type":"string","description":"find_note: lowest note to ask for (default C4)."},"high":{"type":"string","description":"find_note: highest note to ask for (default B4)."},"include_black_keys":{"type":"boolean","description":"find_note: also ask for sharps and flats. Default false (white keys only)."},"song_id":{"type":"string","description":"song: id from search_songs, e.g. \"fur_elise\"."},"section":{"type":"string","description":"song: section id from get_song, or \"all\" for the whole piece. Default: first section."},"hands":{"type":"string","enum":["right","left","both"],"description":"song: default right. \"both\" only where get_song shows a left-hand part."},"tempo_percent":{"type":"number","minimum":30,"maximum":150,"description":"song: percent of the song tempo. Start learners at 60–70."},"path_step":{"type":"string","description":"Learning-path step id from get_learning_paths. Pass path exercises unchanged so progress is tracked."}},"required":["kind"],"additionalProperties":false}},"required":["title"],"additionalProperties":false}}},"required":["title","items"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"complete_plan_item","kind":"act","impl":"imperative","description":"Mark a practice-plan item done (or not done) by its id or exact title.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"item_id":{"type":"string"},"title":{"type":"string"},"done":{"type":"boolean","description":"Default true."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"log_practice_session","kind":"act","impl":"imperative","description":"Save a practice session to the student's log with a short summary and optional tutor notes. Attaches recent attempts (default: everything since the last logged session). Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"summary":{"type":"string","description":"One or two sentences: what was practiced and how it went."},"notes":{"type":"string","description":"What to work on next time."},"attempt_ids":{"type":"array","items":{"type":"string"},"description":"Specific attempts to attach. Omit to attach everything since the last session."}},"required":["summary"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"say","kind":"act","impl":"imperative","description":"Speak one or two short sentences out loud through the page, in the browser voice. Use it for coaching while the student has both hands on the keys and eyes on the keyboard, e.g. \"Good. Now a little slower.\" Keep it under 25 words; the student can also read your chat.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"text":{"type":"string"}},"required":["text"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"wait_for_result","kind":"act","impl":"imperative","description":"Waits until the running exercise finishes, then returns its full results with coaching, so you never need to poll or ask the student to say \"done\". Call it right after start_exercise. The cap defaults to the time the drill still needs (max 45 s); if they are still playing when it runs out, it returns their progress and you call it again. With nothing running it returns the latest result.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"timeout_seconds":{"type":"number","description":"Default 20, max 45."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"wait_for_notes","kind":"act","impl":"imperative","description":"Listens for the next thing the student plays outside a drill (a note, a chord, or a short burst) and returns it named, e.g. \"C major\" or \"a perfect 5th\". Use it for \"play me a C chord\" checks and \"what is this?\" moments. Returns after timeout_seconds (default 15, max 45) with nothing if they did not play.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"timeout_seconds":{"type":"number","description":"Default 15, max 45."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_recent_notes","kind":"answer","impl":"imperative","description":"What the student has been playing freely, outside a drill: the notes held right now and what chord or interval they make, the last notes with timing, and the phrase since the last pause. Use it for \"what chord is this?\", \"was that right?\", or to react to improvising. Timing is in milliseconds.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"seconds":{"type":"number","description":"How far back to look, default 20, max 90."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"save_recording_as_song","kind":"act","impl":"imperative","description":"Turn what the student just played freely into a song in their library. Takes the phrase since the last pause (or the last N seconds), snaps it to a beat grid, writes it in Tonic notation and shows a confirmation card. Returns the notation so you can read it back or fix it with add_song. Give bpm if you know the tempo they meant; otherwise it is estimated.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"title":{"type":"string"},"bpm":{"type":"number","description":"Tempo the student was playing at. Estimated if omitted."},"beats_per_bar":{"type":"integer","description":"Default 4."},"grid":{"type":"string","enum":["quarter","eighth","sixteenth"],"description":"Smallest note to snap to, default eighth."},"seconds":{"type":"number","description":"Use the last N seconds instead of the phrase since the last pause."},"key":{"type":"string"},"genre":{"type":"string","enum":["kids","folk","holiday","hymn","classical"]},"moods":{"type":"array","items":{"type":"string","enum":["calm","joyful","playful","festive","melancholic","solemn","majestic"]}}},"required":["title"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"add_song","kind":"act","impl":"imperative","description":"Add a song to the student's library so it gets Listen, Practice, sections and progress like any other song. Write the melody in Tonic notation: note names with octave (C4, F#4, Bb3) and beats after a colon (E4:0.5, G4:2; default 1), \"-\" for a rest (\"-:2\"), [C3 E3 G3] for a chord, \"|\" bar lines optional. Every section must be whole bars; an optional left hand (lh) must be the same length as the right hand (rh). Keep right-hand notes within C4–F5 so they fit the computer keyboard. The page validates and shows a confirmation card before saving. Prefer public-domain tunes or the student's own material. Example: {\"title\":\"Ode to Joy\",\"key\":\"C major\",\"bpm\":80,\"sections\":[{\"name\":\"Theme\",\"rh\":\"E4 E4 F4 G4 | G4 F4 E4 D4 | C4 C4 D4 E4 | E4:1.5 D4:0.5 D4:2\"}]}","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"title":{"type":"string"},"origin":{"type":"string","description":"Composer or tradition and year, e.g. \"Traditional Irish\"."},"genre":{"type":"string","enum":["kids","folk","holiday","hymn","classical"]},"moods":{"type":"array","items":{"type":"string","enum":["calm","joyful","playful","festive","melancholic","solemn","majestic"]}},"difficulty":{"type":"integer","minimum":1,"maximum":5},"key":{"type":"string","description":"e.g. \"F major\" or \"A minor\". Flat keys spell notes with flats."},"bpm":{"type":"number","description":"30–240, default 80."},"beats_per_bar":{"type":"integer","description":"Default 4. Use 3 for waltzes; count 6/8 in eighths with 6."},"blurb":{"type":"string","description":"One line for the student."},"techniques":{"type":"array","items":{"type":"string"}},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Short id like \"a\", \"verse\". Default a, b, c…"},"name":{"type":"string","description":"Shown to the student, e.g. \"Verse\"."},"rh":{"type":"string","description":"Right-hand melody in Tonic notation."},"lh":{"type":"string","description":"Optional left hand, same length as rh."}},"required":["rh"],"additionalProperties":false}},"form":{"type":"array","items":{"type":"string"},"description":"Section order for the whole song, e.g. [\"a\",\"b\",\"a\"]. Default: sections in order."}},"required":["title","sections"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"remove_song","kind":"act","impl":"imperative","description":"Remove a song the agent or the student added earlier. Built-in songs cannot be removed. Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"song_id":{"type":"string"}},"required":["song_id"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"show_screen","kind":"act","impl":"imperative","description":"Move the page to a screen: home (the learning paths), a learning path by id, songs (optionally with a song expanded), or practice (plan and log). Closes a finished result if it is showing. Use this instead of clicking links or menus.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"screen":{"type":"string","enum":["home","path","songs","practice"]},"path_id":{"type":"string","enum":["keys","chords","scales","ear"],"description":"For screen \"path\"."},"song_id":{"type":"string","description":"For screen \"songs\": expand this song."}},"required":["screen"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"close_result","kind":"act","impl":"imperative","description":"Close the result or \"listen\" card that is showing and return to the page underneath. Same as the student pressing Done.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_practice_plan","kind":"answer","impl":"imperative","description":"The practice plan shown on the Practice screen: each item with its id, whether it is done, and its exercise spec, which you can pass to start_exercise unchanged.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"replay_prompt","kind":"act","impl":"imperative","description":"In an ear-training drill, play the prompt again for the student. Same as the \"Play it again\" button.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"play_back_attempt","kind":"act","impl":"imperative","description":"Play back what the student played in an attempt, at the timing they played it, keys lighting up. Same as the \"Hear yours\" button. Defaults to the latest attempt.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"attempt_id":{"type":"string"}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"connect_midi","kind":"act","impl":"imperative","description":"Try to connect a MIDI keyboard or digital piano. Browsers only grant MIDI access from a real click, so this may fail; if it does, ask the student to press \"Connect a MIDI keyboard\" under the piano.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"export_progress","kind":"act","impl":"imperative","description":"Everything stored in this browser (attempts, plan, log, settings, added songs) as JSON, the same as the Export button. Use it to move progress to another browser with import_progress.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"import_progress","kind":"act","impl":"imperative","description":"Replace what is stored in this browser with a JSON export from export_progress or the Export button. Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"json":{"type":"object","description":"The exported object."}},"required":["json"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"reset_progress","kind":"act","impl":"imperative","description":"Erase the plan, log, attempts, added songs and settings from this browser. Same as the Reset link. Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"load_sample_progress","kind":"act","impl":"imperative","description":"Fill the app with a sample plan and practice log, for trying things out. Same as the \"Load sample\" link. Shows a confirmation card first.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_learning_paths","kind":"answer","impl":"imperative","description":"The five learning paths the app is organised around (find your way around the keys, learn chords, scales and rhythm, train your ear, play a song) with their steps, which are done, and the next step's ready-to-use exercise. To start a step, pass its exercise to start_exercise unchanged; it carries path_step so the app ticks it off. For songs use search_songs.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"search_songs","kind":"answer","impl":"imperative","description":"Browse the song library: 20 public-domain pieces (kids, folk, holiday, hymn, classical) rated 1–5. Filter by text, genre, mood, difficulty, hands, and whether it fits the computer keyboard. Set for_student true to rank by the student's level, interests, instrument and progress, with a reason per song. Then call get_song, or start_exercise with kind \"song\".","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Free text matched against title, composer, genre, moods and techniques."},"genre":{"type":"string","enum":["kids","folk","holiday","hymn","classical"]},"mood":{"type":"string","enum":["calm","joyful","playful","festive","melancholic","solemn","majestic"]},"max_difficulty":{"type":"integer","minimum":1,"maximum":5},"min_difficulty":{"type":"integer","minimum":1,"maximum":5},"hands":{"type":"string","enum":["right","both"],"description":"\"both\" returns only songs with a left-hand part."},"fits_computer_keyboard":{"type":"boolean","description":"Only songs with at least one section playable on the computer keyboard."},"for_student":{"type":"boolean","description":"Rank by the student profile, interests, instrument and progress."},"limit":{"type":"integer","description":"Default 10."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_song","kind":"answer","impl":"imperative","description":"Everything about one song: each section with length, note range, whether it fits the computer keyboard (and the octave shift it needs), the student's best score, its distinct notes and computer keys, plus ready-made warm-up drills and a suggested first exercise. Call this before starting a song.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"song_id":{"type":"string"}},"required":["song_id"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]},{"name":"get_song_progress","kind":"answer","impl":"imperative","description":"Best score per section and overall mastery for one song, or for every song the student has tried. A song counts as learned when every section scores 80 or more.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"song_id":{"type":"string","description":"Omit for all songs with progress."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/","pages":["/","/learn/songs","/practice","/learn/keys","/learn/chords","/learn/scales"]}],"category":"Health & Education","favicon":"/favicons/tonic.stranica.workers.dev.svg","apiSurface":"spec","toolCount":37}}