A local bridge for Synthesizer V Studio 2 built with Python + Lua + MCP.
It is also a small experimental toy with a heuristic flavor. Hopefully it can offer some inspiration, experiments, and practical ideas to broader Vocaloid-style creators and AI developers in the future.
Project:
The goal of this project is to let external AI agents, editor plugins, or scripts access the currently opened Synth V project through standard MCP tools, and perform project inspection, note editing, track management, parameter editing, and host interaction.
-
synthv_pipe_client.lua- Runs inside Synth V
- Lives as a
SidePanelSection - Polls a state file and connects to a Python-created named pipe
- Executes the actual official Synth V scripting APIs
-
python_pipe_bridge.py- Local Python bridge process
- Provides a CLI
- Creates a named pipe per request and communicates with Lua
-
python_pipe_mcp_server.py- Built on
FastMCP - Exposes the bridge as MCP tools
- Can be used by VS Code Copilot, Codex, Claude Desktop, and other MCP clients
- Built on
Transport flow:
- Python creates a named pipe
- Python writes pipe metadata to
%TEMP%\\synthv_pipe_bridge_state.json - Lua Side Panel polls the state file and connects to the pipe
- Both sides exchange one JSON request and one JSON response
synthv_pipe_client.lua: Synth V side scriptpython_pipe_bridge.py: local CLI / pipe hostpython_pipe_mcp_server.py: MCP server
-
Copy
synthv_pipe_client.luainto the Synth V scripts folder
In Synth V:Scripts -> Open Scripts Folder -
Reload scripts or restart Synth V
-
Open the
SynthV-MCPside panel and keep it visible -
Install Python dependency
pip install mcpOne-shot calls:
python .\python_pipe_bridge.py ping
python .\python_pipe_bridge.py project
python .\python_pipe_bridge.py notesInteractive mode:
python .\python_pipe_bridge.pyThen enter commands continuously:
ping
project
notes
exit
Start:
python .\python_pipe_mcp_server.pyIt uses stdio as the MCP transport and is usually managed by an MCP client.
Example config:
{
"mcpServers": {
"synthv": {
"command": "python",
"args": ["C:/path/python_pipe_mcp_server.py"]
}
}
}- The Synth V side panel script must be open
- Python and Synth V must run on the same machine
- This is a local bridge, not a remote service
- Multiple host instances are not automatically distinguished yet
- Playback-related APIs are currently not exposed
- The named-pipe transport currently handles one request at a time
RetakeListcan set the active take, but cannot read the current active take- Host dialogs are synchronous and blocking
The tables below list all currently implemented MCP tools.
| Tool | Description |
|---|---|
ping |
Check whether Python and Synth V Lua are connected |
echo |
Echo a message and return a project summary |
| Tool | Description |
|---|---|
get_host_info |
Read Synth V host information |
get_host_clipboard |
Read plain text from the system clipboard |
set_host_clipboard |
Write plain text to the system clipboard |
| Tool | Description |
|---|---|
show_message_box |
Show a blocking message box |
show_input_box |
Show a blocking text input box |
show_ok_cancel_box |
Show an OK / Cancel dialog |
show_yes_no_cancel_box |
Show a Yes / No / Cancel dialog |
show_custom_dialog |
Show a custom form dialog |
show_info |
Convenience wrapper for a simple message box |
prompt_text |
Convenience wrapper for a text prompt |
confirm |
Convenience wrapper for OK / Cancel confirmation |
ask_yes_no_cancel |
Convenience wrapper for a three-choice confirmation dialog |
| Tool | Description |
|---|---|
get_arrangement_selection |
Read the current arrangement-view selection |
get_arrangement_selection_state |
Read arrangement selection summary flags |
clear_arrangement_selection_all |
Clear all arrangement selections |
clear_arrangement_selection_groups |
Clear selected arrangement groups |
select_arrangement_groups |
Select arrangement group references |
unselect_arrangement_groups |
Unselect arrangement group references |
| Tool | Description |
|---|---|
get_project_overview |
Read project overview, current track, current group, and tempo summary |
get_project_duration |
Read total project duration |
list_note_groups_in_library |
List all note groups in the project library |
get_note_group_in_library |
Read one note group from the project library |
add_note_group_to_library |
Create an empty note group in the library |
clone_current_group_to_library |
Clone the current piano-roll group into the library |
remove_note_group_from_library |
Remove a note group from the library |
set_note_group_name_in_library |
Rename a note group in the library |
set_current_group_name |
Rename the current piano-roll group |
| Tool | Description |
|---|---|
list_tracks |
List all tracks |
get_track_info |
Read one track's basic properties |
add_track |
Create a new track |
remove_track |
Remove a track |
set_track_name |
Rename a track |
set_track_color |
Set a track color |
set_track_bounced |
Set a track's bounced state |
get_track_mixer |
Read track mixer parameters |
set_track_mixer |
Update gain, pan, mute, and solo |
get_track_notes |
Read all group references and notes for a track |
get_group_reference |
Read one group reference |
add_group_reference |
Insert a library note group into a track |
set_group_reference |
Update group-reference timing, pitch offset, mute, and related fields |
remove_group_reference |
Remove a group reference |
| Tool | Description |
|---|---|
get_current_group |
Read the current piano-roll group reference |
get_selection |
Read the current piano-roll selection |
get_selection_state |
Read selection summary flags |
clear_selection_all |
Clear all piano-roll selections |
clear_selection_notes |
Clear selected notes |
clear_selection_groups |
Clear selected groups |
clear_selection_pitch_controls |
Clear selected pitch controls |
select_notes |
Select notes by index |
unselect_notes |
Unselect notes by index |
select_groups |
Select group references by index |
unselect_groups |
Unselect group references by index |
get_selected_pitch_controls |
Read selected pitch controls |
get_selected_points |
Read selected automation points |
select_points |
Select automation points |
unselect_points |
Unselect automation points |
| Tool | Description |
|---|---|
list_pitch_controls |
List all pitch controls in the current group |
get_pitch_control |
Read one pitch control |
get_pitch_control_value |
Read a pitch curve value at a given time |
add_pitch_control_point |
Add one pitch point |
add_pitch_control_curve |
Add one pitch curve |
update_pitch_control_point |
Update one pitch point |
update_pitch_control_curve |
Update one pitch curve |
delete_pitch_control |
Delete one pitch control |
delete_pitch_controls |
Delete multiple pitch controls |
clear_pitch_controls |
Clear all pitch controls in the current group |
| Tool | Description |
|---|---|
list_notes |
List all notes in the current group |
get_note |
Read one note |
get_note_attributes |
Read advanced note attributes |
set_note_attributes |
Update advanced note attributes |
get_note_retakes |
Read retake count metadata for a note |
generate_note_retake |
Generate one retake |
delete_note_retake |
Delete one retake |
set_note_active_retake |
Set the active retake |
get_notes_in_range |
List notes overlapping a given time range |
| Tool | Description |
|---|---|
clear_notes |
Delete all notes in the current group |
delete_notes_in_range |
Delete notes overlapping a given time range |
add_note |
Add one note |
add_notes |
Add multiple notes |
update_note |
Update one note |
update_notes |
Update multiple notes |
delete_note |
Delete one note |
delete_notes |
Delete multiple notes |
| Tool | Description |
|---|---|
transpose_selected_notes |
Transpose currently selected notes |
set_selected_lyrics |
Replace lyrics of selected notes |
set_selected_phonemes |
Replace phonemes of selected notes |
set_selected_language_override |
Set language override for selected notes |
move_selected_notes |
Move selected notes by offset |
duplicate_selected_notes |
Duplicate selected notes |
transpose_notes_by_indices |
Transpose notes by explicit indices |
set_notes_lyrics |
Replace lyrics by explicit note indices |
set_notes_phonemes |
Replace phonemes by explicit note indices |
set_notes_language_override |
Replace language override by explicit note indices |
| Tool | Description |
|---|---|
list_tempo_marks |
List all tempo marks |
get_tempo_at |
Read the tempo at a given position |
set_tempo_mark |
Add or update a tempo mark |
remove_tempo_mark |
Remove a tempo mark |
seconds_to_blick |
Convert seconds to blick |
blick_to_seconds |
Convert blick to seconds |
quarter_to_blick |
Convert quarter units to blick |
blick_to_quarter |
Convert blick to quarter units |
| Tool | Description |
|---|---|
pitch_to_freq |
Convert pitch to frequency |
freq_to_pitch |
Convert frequency to pitch |
black_key |
Check whether a pitch is a black key |
| Tool | Description |
|---|---|
get_group_parameter |
Read an automation parameter object from the current group |
get_parameter_points |
Read automation points |
get_parameter_value |
Read an automation value at a position |
add_parameter_point |
Add an automation point |
remove_parameter_point |
Remove one point or a point range |
clear_parameter_points |
Clear all points for a parameter |
simplify_parameter_points |
Simplify automation points |
| Tool | Description |
|---|---|
get_current_group_voice |
Read current group-reference voice parameters |
set_current_group_voice |
Update current group-reference voice parameters |
set_current_group_voice currently supports:
paramLoudnessparamTensionparamBreathinessparamGenderparamToneShiftvocalModeParams
Notes:
- Lua already supports
vocalModeParams - Python / MCP does not yet provide a dedicated high-level wrapper for
vocalModeParams
| Tool | Description |
|---|---|
get_script_data |
Read script-private metadata |
set_script_data |
Write script-private metadata |
has_script_data |
Check whether script-private metadata exists |
get_script_data_keys |
List script-private metadata keys |
remove_script_data |
Remove one metadata key |
clear_script_data |
Clear all script-private metadata on a target |
Current supported targets:
projecttracktrackMixergroupgroupRefnotetimeAxis
python .\python_pipe_bridge.py projectpython .\python_pipe_bridge.py note-add --onset 0 --duration 705600000 --pitch 60 --lyrics lapython .\python_pipe_bridge.py voice-getpython .\python_pipe_bridge.py mixer-set --track-index 1 --gain-decibel -3python .\python_pipe_bridge.py confirm --message "Continue?"Major areas still not covered:
- PlaybackControl
- TimeAxis measure marks / time signatures
- Navigation / CoordinateSystem
- Computed pitch / computed attributes / phoneme analysis
- Async dialogs
This project is licensed under the MIT License.
Copyright (c) 2026 MetaMiku
Main references used during development:
-
Synthesizer V Studio 2 scripting overview
https://resource.dreamtonics.com/scripting/ -
Dreamtonics official example scripts
https://github.com/Dreamtonics/svstudio-scripts