# MCP server `deckcraft-cli mcp` runs a Model Context Protocol server on stdio. By default it drives its own headless engine (no window); with `--connect PORT` it drives a running DeckCraft started with `--control PORT`, so an agent and a person can work on the same deck. `--sample` opens the sample deck. Stdio request frames are limited to 16 MiB including the newline; oversized frames receive a JSON-RPC error and are drained so the next request can still be handled. Invalid UTF-8 frames receive a parse error. Connected mode accepts only newline-terminated replies of at most 16 MiB (including the newline), with the current request's numeric `id`, a boolean `ok`, and either `result` on success or a string `error` on failure. CRLF is accepted. Invalid replies close the connection and report that the command may or may not have run; they never cause a replay. Check the document before retrying a mutation. Before sending another request, unsolicited bytes in the reader's buffer or on the socket cause a fresh connection to be opened. Large image replies must fit this budget; render to a file or use a smaller scale when necessary. Regression coverage for #718 lives in `crates/mcp/src/backend.rs`: synthetic loopback peers test reply correlation, envelopes, framing, the size cap and buffered unsolicited bytes, alongside the lost-reply and reconnect tests. ```json { "mcpServers": { "deckcraft": { "command": "deckcraft-cli", "args": ["mcp", "--connect", "7990"] } } } ``` ## Confining file access ```sh deckcraft-cli mcp --automation-read-root /work/project --automation-write-root /work/project/out ``` ```json {"mcpServers": {"deckcraft": {"command": "deckcraft-cli", "args": ["mcp", "--automation-read-root", "/work/project", "--automation-write-root", "/work/project/out"]}}} ``` The two flags keep the agent to the folders you give it. Repeat either flag to allow access to more folders: - Every file a command reads must lie inside the **read root**: `open_presentation` and `file.open`, and `insert_picture`, `insert.picture`, `picture.change`, `insert.audio` and `insert.video` with a `path`. Pictures, audio and video are copied into the deck when they are inserted, so playing them later reads nothing from disk. - Every file a command writes must lie inside the **write root**: `save_presentation`, `export` (every format, and every slide of an image export), `file.save`, `file.saveAs`, `file.export`, and `render_slide` with a `path`, plus the `.saving` temporary file a save goes through. - 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.pptx` or `automation filesystem access is not granted: write authority is absent: /work/project/out/x.pptx`. - The roots must be existing folders; a missing one stops the server with an error. Repeat either flag to allow access to another folder; both `--flag