# MCP server SoundCraft speaks the [Model Context Protocol](https://modelcontextprotocol.io) over stdio, so Claude and other agents can make music with it. ```sh soundcraft-cli mcp # headless engine (no window, no audio device) soundcraft-cli mcp --demo # headless, starting from the demo session soundcraft-cli mcp --automation-read-root DIR --automation-write-root DIR # headless, confined to folders soundcraft --control 7801 & # the desktop app… soundcraft-cli mcp --connect 7801 # …driven over MCP: same tools plus screenshots and clicks ``` Claude Code: ```sh claude mcp add soundcraft -- soundcraft-cli mcp --demo ``` ## Confining file access ```sh soundcraft-cli mcp --automation-read-root /work/project --automation-write-root /work/project/out ``` ```json {"mcpServers": {"soundcraft": {"command": "soundcraft-cli", "args": ["mcp", "--automation-read-root", "/work/project", "--automation-write-root", "/work/project/out"]}}} ``` The two flags (VectorCraft and the other Craft apps take the same ones, so one client config works across the suite) keep the agent to the folders you give it: - Every file a command reads must lie inside the **read root**: `open_session`, `session.open`, `import_audio` and `file.import_audio`, `file.import_midi`, `file.import_video`, `file.import_clip_groups`, `file.import_session_data`, `track.load_preset` and `mix.sampler_load`. The media a session file names is read too, so an opened session whose audio paths lead outside the read root loads without that audio and lists it under `missing`. - Every file a command writes must lie inside the **write root**: `save_session`, `session.save`, `session.save_as`, `session.save_copy`, `session.save_template`, `bounce_mix` and `file.bounce_mix`, `file.bounce_stems`, `file.export_clips`, `file.export_midi`, `file.export_session_text`, `file.export_selected_tracks_as_session`, `file.export_sibelius`, `file.send_to_sibelius`, `file.print_score`, `file.export_clip_groups` and `track.save_preset`, together with what a session save writes beside the session file (`Audio Files/`, `Backups/`) and its temporary file. A score command given no `path` writes to the temp folder, which is outside the write root unless you made it the root, so it is refused. - Read and write access are separate. Give the same folder twice for both; a root left out grants none of its access (with only `--automation-read-root`, nothing can be written to disk). Without either flag nothing changes. - A path is made absolute against the server's working directory, then its links are followed: a file (or folder) link that leads out of a root is outside it. For a file that doesn't exist yet, its nearest existing folder's links are followed and the rest must be plain names, so `..` below a folder that doesn't exist is refused, as is a link that leads nowhere (writing through it would create its target). The result is compared with the root by whole folder names: `/work2/x` is not inside `/work`. On Windows case is ignored, UNC paths (`\\server\share\...`) are resolved like drive-letter ones, and device names (`CON`, `NUL`, `COM1`...) are refused. - A refused path is an ordinary tool error the agent can read and correct, for example `automation path rejected: outside the write root /work/project/out: /etc/x.wav` or `automation filesystem access is not granted: write authority is absent: /work/project/out/x.wav`. A refused save path is reported as refused, never as "already exists". - The roots must be existing folders; a missing one stops the server with an error. Each flag is given once (`--flag