# Agent API reference

Everything the editor can do, an agent can do through ArcLight's API: about 130 operations behind 13 MCP tools. This page is for people building their own agents or scripts. To connect Claude Code, start with [Set up AI agents](/content/help/ai-agents/index.html).

**The API describes itself.** Call `describe` with no topic for an overview, `describe {topic: "methods"}` for every operation with its arguments, and `describe {topic: "schema"}` for every field. This page is the map; `describe` is the reference.

## How agents connect

- **Off by default.** ArcLight listens only while is on and the app is open. _Regenerate_ there issues a new token and disconnects everyone using the old one.
- **A local Unix socket,** never the network. It speaks JSON-RPC 2.0, one message per line. The socket file is readable only by you.
- **A token.** ArcLight writes the socket path and token to `~/Library/Group Containers/UW68D9RYJX.com.graizlabs.arclight/agent.json` (mode 0600). The first message on a connection must be `hello` with that token.
- **The `arclight` helper** at `ArcLight.app/Contents/Helpers/arclight` does all of this for you. `arclight mcp` is an MCP server on stdio that forwards tool calls to the socket.

If you talk to the socket directly, open with:

```
{"jsonrpc":"2.0","id":1,"method":"hello","params":{"token":"<token from agent.json>","name":"My agent"}}
```

The `name` is what the host sees in the activity list. After that, every method on this page is a JSON-RPC method with the same name.

## The 13 MCP tools

| Tool | What it does |
| --- | --- |
| `describe` | Reference for the API and every editor catalog. Takes a `topic` and an optional `name`. |
| `list_documents` | Open documents, frontmost first, with id, name, revision, slide count, canvas size and whether it's live. |
| `get` | Reads the document or any part of it by path. `""` is the outline. |
| `set` | Sets one field by path to a JSON value. |
| `patch` | Several path edits (`set`, `insert`, `remove`, `move`) applied together as one undo step. |
| `edit` | Runs an editing operation: `{op, args}`. The same actions as the editor's menus, toolbar and inspectors. |
| `show` | Runs the show: `{op, args}` for play, take, builds, recording, outputs, the virtual camera and the prompter. |
| `render` | Renders a slide to a PNG, optionally after some build clicks and with graphics at given steps. |
| `grab_program` | The current program output frame as a PNG. Only while the show is playing. |
| `select` | Selects a slide and layers in the editor and outlines them, so the host sees what you mean. |
| `activity` | Recent agent changes to a document, newest first, with ids for `revert`. |
| `revert` | Reverts one agent change by activity id. |
| `wait_events` | Long-polls for events after a cursor and returns a new cursor. |

Every tool takes an optional `document` (an id or a name). Leave it out to use the frontmost document. For `edit` and `show`, the operation's parameters go in `args`:

```
edit {op: "add_text", args: {slide: "Intro", name: "Title", string: "Hello", frame: "lower-third"}}
show {op: "take", args: {slide: "#3"}}
```

## Main `edit` operations

| Area | Operations |
| --- | --- |
| Slides | `add_slide``duplicate_slide``delete_slides``move_slides``rename_slide``set_background``set_notes``update_slide``insert_template_slides` |
| Adding layers | `add_camera``add_screen``add_window``add_text``add_shape``import_image``add_video``add_preset` (title presets) `add_generator` (Motion backgrounds and particles) `add_graphic` (web graphics) |
| Layer settings | `set_text``style_text``measure_text``style_shape``style_generator``set_camera``set_screen``set_video``set_crop``set_fit``set_mask``set_opacity``set_hidden``rename_layer``update_layer` |
| Arrange | `set_frame``move_layers``transform_layers``align``distribute``center_on_slide``fill_slide``arrange``group``ungroup``set_rotation``set_corners``set_distortion``reset_transform` |
| Layers between slides | `duplicate_layers``delete_layers``copy_layers``cut_layers``paste_layers` |
| Effects | `add_effect``set_effect``move_effect``remove_effect``set_blend_mode` |
| Animate | `set_transition``set_build``set_build_order``set_build_timing` |
| Web graphics | `add_graphic``update_graphic` (change params in place; they merge) `get_graphic``set_graphics_theme` (the show's colors and font for every graphic) |
| Graphics library | `list_library``get_library_graphic``save_library_graphic``delete_library_graphic` |
| Color | `set_grade``reset_grade``auto_balance``apply_look``save_look``rename_look``delete_look``import_lut``remove_lut` |
| Script | `set_script``get_script``import_script``script_from_notes` |
| Media | `list_missing_media``relink``relink_media` |
| Document and settings | `new_document``open_document``save_document``import_slides` (PDF or Keynote) `resize_canvas``set_output``set_prompter``get_settings``set_setting``restore_default_hotkeys` |

## Main `show` operations

| Area | Operations |
| --- | --- |
| Play | `play``stop``toggle_play``take``next``previous``jump``advance_build``edit_while_playing``live_state` |
| Web graphics | `set_graphic_step` (what a `{{Layer: step}}` cue does: on air while playing, in the editor while rehearsing) |
| Recording | `start_recording``stop_recording``toggle_record``last_recording` |
| Outputs | `show_program_output``hide_program_output` |
| Virtual camera | `vcam_status``vcam_install``vcam_uninstall``vcam_refresh` |
| Teleprompter | `prompter` (start, pause, stop, restart, toggle) `prompter_show``prompter_dock``prompter_speed``prompter_seek``prompter_cue` |
| Sources and color | `list_sources``refresh_sources``request_screen_capture``open_color``close_color``get_scopes` |

For the arguments of any operation, call `describe {topic: "methods", name: "set_build"}`.

## Paths and selectors

`get`, `set` and `patch` address any part of the document by path:

```
get {path: ""}                                        // outline
get {path: "slides[\"Intro\"]"}
get {path: "slides[#2].layers[\"Title\"].kind.text"}
set {path: "slides[\"Intro\"].layers[\"Title\"].kind.text.fontSize", value: 96}
get {path: "script"}
get {path: "output"}
```

For the outline, `depth` sets the detail: 0 is slide names only, 1 adds layers (the default), 2 is the full document.

| Selector | Slides | Layers (within a slide) |
| --- | --- | --- |
| "Name" | By name | By name |
| "#3" | Slide number, starting at 1 |  |
| 2 | Index, starting at 0 | Index |
| "live" | The slide on air |  |
| "selected" | The editor's selected slide | The editor's selected layers |
| "last" | The last slide |  |
| An id | Stable across renames | Stable across renames |

Operations that take several layers also accept "all". Names that don't match come back as an error with the closest matches.

## Frames, layouts and colors

- **Coordinates** are canvas points with the origin at the top left. The default canvas is 1920×1080.
- **Frames** are `{x, y, width, height}`, or a named layout: `full`, `center`, `title-safe`, `left-half`, `right-half`, `top-half`, `bottom-half`, `left-two-thirds`, `right-third`, `lower-third`, `pip-top-left`, `pip-top-right`, `pip-bottom-left`, `pip-bottom-right`. Picture-in-picture is 28% of the canvas width, 4% from the corner. `describe {topic: "layouts"}` lists them.
- **Colors** read back as sRGB `{r, g, b, a}` from 0 to 1. Writes also accept `"#RRGGBB"` or `"#RRGGBBAA"`.
- **Layer kinds** read as one key: `kind: {text: {…}}`, `kind: {camera: {…}}`, and so on.

## How changes are applied

- **One call, one undo step.** Every change is a batch, named "Agent: …" in the host's Undo menu and recorded in `activity`.
- **The editor's rules apply.** After a path edit ArcLight repairs what the editor wouldn't allow (build order, groups, value ranges) and lists each fix in `repairs`. Pass `strict: true` to fail instead.
- **Revisions.** Each change returns the new `revision`. Pass `ifRevision` to `set` or `patch` to fail if the document changed since you read it.
- **Reasons.** Pass `reason` to `set` or `patch` and the host sees it in the activity list.
- **Revert.**`revert {id}` undoes one agent change, and refuses with a conflict when the host has edited the same slides since.
- **Errors say how to fix them.** They carry the `path`, the `expected` type, `allowed` values and a `suggestion`.

## Seeing the show

Three calls return PNG images. Over MCP they arrive as image content, alongside a JSON text part.

- `render {slide, width, builds, steps, at}` draws any slide. `builds: 0` shows it as it first appears; the default is every build run. `steps` maps graphic layer names to steps. Cameras and screens appear as labeled cards until you allow agents to see them, so a render never turns on or shows a camera by itself. `startSources: true` asks you first; choose Always Allow and later renders show running cameras (or screens and windows, which are asked about separately) as they are.
- `grab_program {width}` returns the live program frame while the show is playing.
- `show {op: "get_scopes", args: {camera, kind}}` returns a camera's `waveform`, `parade`, `vectorscope` or `histogram`.

## Events

`wait_events` returns events after a cursor as soon as there are any, or an empty list after `timeout` seconds (default 25, at most 60). Pass the returned `cursor` as `since` next time. Leave `since` out to start from now. Filter with `types`, using exact names or prefixes like `"live.*"`.

```
wait_events {since: 118, types: ["live.*", "cue.fired"], timeout: 30}
```

| Event | When |
| --- | --- |
| `document.changed` | A document changed. `data.author` is `"host"` or the agent's name, with the new `revision`. |
| `live.started`, `live.stopped` | The show started or stopped playing. |
| `live.slide` | A slide was taken live (`data.slide` is its name). |
| `build.advanced` | A build click ran on the live slide. |
| `cue.fired` | A teleprompter cue fired: a slide cue (`data.slide`) or a trigger (`data.trigger`). |
| `prompter.state` | The prompter started, paused or stopped. |
| `recording.started`, `recording.stopped` | Recording started or stopped (`data.path` is the movie). |
| `vcam.state` | The virtual camera's install or sending state changed. |
| `performance.level` | The Mac got busier or recovered. |
| `selection.changed` | The host selected a different slide. |

## The graphics library

ArcLight ships ready-made web graphics: bar and line charts, a big number, a quote card, a timeline, a comparison, a source card, and `form-fields`, a reference graphic with one form field of every type. Each has steps, a form (the fields shown in Format ▸ Graphic) and example data. Graphics the person saves sit beside them.

- **Browse.**`describe {topic: "library"}` or `list_library` lists every graphic; `get_library_graphic {name}` returns its README, fields, example and files. MCP clients can also read them as resources, `arclight://library/<name>`.  
- **Add.**`add_graphic {slide, library: "bar-chart", params, steps}`. A library graphic shows only the data you pass; `example: true` uses its sample data, for layout checks, never for air.
- **Change.** Pass `files` with `library` to replace or add files, such as a new stylesheet. `update_graphic {library}` switches a layer to a library graphic and keeps its data.
- **Save.**`save_library_graphic {name, title, summary}` keeps a graphic for later shows: from a layer on a slide (its data becomes the example), from files, or from a library graphic plus changed files. They're stored in `~/Library/Application Support/ArcLight/Graphics`. Built-in names can't be reused, and `delete_library_graphic` removes only your own.

## describe topics

`overview`, `ops`, `methods`, `schema`, `effects`, `filters`, `transitions`, `builds`, `generators`, `titlePresets`, `textStyles`, `templates`, `fonts`, `looks`, `sources`, `blendModes`, `masks`, `shapeForms`, `layouts`, `events`, `graphics` (the web graphic contract and its JavaScript API), `library` (the graphics library) and `producer` (the article-to-show guide, also offered as the MCP prompt `arclight-producer`). Add `name` for one entry, such as `describe {topic: "effects", name: "gaussianBlur"}`.

## Scripts: arclight call

The helper also makes single calls from Terminal or a shell script. It prints the result as JSON, and exits 1 with the error on stderr if the call fails.

```
A="/Applications/ArcLight.app/Contents/Helpers/arclight"
"$A" status
"$A" call list_documents
"$A" call take '{"slide": "#2"}'
"$A" call render '{"slide": "Intro", "width": 640}'
```
