Automation, AI & MCP
The conductor — one schema-validated action surface for every capability — plus the AI command centre, the MCP bridge that lets an AI client drive the Redline app, and Quantity Link.
The conductor#
Everything the application can do is an action on one dispatch bus, called the conductor. The GUI dispatches actions; batch operations dispatch actions; scripting dispatches actions; the AI dispatches actions. There is no second API and no privileged path.
Three properties follow from that, and they are the whole reason for the design:
Every action is schema-validated. Inputs are defined as schemas, so a malformed dispatch is rejected at the boundary with a reason rather than half- applied.
Every mutation goes through the command bus. Anything an action changes is undoable, whether a human, a batch job or a model initiated it.
Every capability is introspectable. app.listActions returns the surface, so a client can discover what the Redline app can do rather than being told out of band.
The action surface#
Around 117 actions, grouped by domain:
| Domain | Examples |
|---|---|
| Markup | markup.draw, markup.modify, markup.delete, markup.align, markup.distribute, markup.group, markup.mirror, markup.flip, markup.applyFormat |
| Measurement | measure.draw, measure.setScale, measure.setRegionScale, measure.getScale, measure.list |
| Pages | page.list, page.insertBlank, page.insertExternal, page.reorder, page.rotate, page.crop, page.replace, page.setLabels, page.getText |
| Documents | doc.list, doc.getOutline, doc.overlay, doc.register, document.getProperties, document.optimize, document.repair |
| Layers | layer.create, layer.update, layer.assign, layer.delete, layer.list |
| Sets | set.new, set.open, set.addDocument, set.sort, set.combine, set.package, set.print |
| Batch | batch.crop, batch.rotate, batch.split, batch.stamp, batch.overlay, batch.compare, batch.headers, batch.slipSheet |
| Export & print | export.pdf, export.xfdf, export.markupList, export.summaryReport, print.compose, print.job, print.batch |
| Search | search.run, search.text, search.visual, search.results |
| Forms | form.addField, form.setValue, form.listFields, form.signatures |
| Spaces & symbols | space.create, space.markups, symbol.list, symbol.place |
| Version | version.commit, version.list, version.diff, version.checkout, version.tag |
| View & selection | view.navigate, view.get, selection.set, selection.all, tool.setActive |
| AI | ai.ask, ai.runProfile, ai.cancelRun |
The MCP bridge#
The conductor is exposed over MCP (Model Context Protocol), so an AI client can inspect and drive a running editor through exactly the actions the GUI uses.
AI client ──stdio (MCP)──► mcp-server ◄──WebSocket── Amalgative Redline
tools/list ← manifest published by the app
tools/call → dispatched to the app's conductor
The editor's webview cannot host a server, so it connects out to the bridge process as a WebSocket client, publishes its tool manifest, and answers dispatch requests. That process is both a WebSocket server (for the app) and an MCP stdio server (for the AI client).
Running it:
cd mcp-server
npm install
node server.mjs # listens on ws://127.0.0.1:8787 (AMED_MCP_PORT to change)
Then in the Redline app: Settings ▸ AI ▸ MCP bridge → enable, with the URL ws://127.0.0.1:8787. The server logs editor connected — N tools once it is up.
Point an MCP client at it as a stdio server:
{
"mcpServers": {
"amalgative": { "command": "node", "args": ["/abs/path/to/mcp-server/server.mjs"] }
}
}
Tool names are the conductor action ids with dots replaced by underscores — markup_draw, view_navigate, scene_get — and their input schemas come straight from the conductor's own schemas. Because they dispatch through the command bus, everything an AI does is undoable in the app.
The AI command centre#
The AI panel runs a model against the document with the conductor as its tool surface. Three things about how it is wired matter.
Profiles. A run is a named profile — what the model is allowed to do and how much autonomy it has — rather than a single free-form chat mode.
An approval gate. Actions that change the document can be gated behind an explicit confirmation, so an agentic profile proposes and you approve.
Provider choice. The model gateway is an adapter seam. A hosted API and local runtimes such as Ollama or LM Studio are both reachable through it, and the key, where one is needed, is stored on the desktop side rather than in the webview.
The desktop build reaches any provider. The browser build serves only the keyless local runtimes — Ollama and LM Studio — because §H1.6 gate 5 keeps API keys out of the webview and a page has no vault to hold them in. Those runtimes must also be configured to allow the page's origin: LM Studio's CORS toggle, or OLLAMA_ORIGINS. Without that the browser sends a preflight that the runtime rejects, because a JSON content type makes the preflight compulsory. The gateway, adapters and agent loop are tested at their parts and seams.
Quantity Link#
The local query endpoint and the spreadsheet add-in are designed, not built.
Quantity Link exposes live takeoff totals to a spreadsheet. A local endpoint in the desktop application answers queries naming a target document, a measurement type (area, volume, length, count) and optional filters on subject, layer or label; it sums the matching markups and returns the total. A spreadsheet add-in polls or subscribes, so a cell updates when a markup is resized or added.
Action Wizard#
Record a sequence of conductor actions as a named macro, inspect it, and replay it — five actions on the command surface: start and finish recording, recording status, inspect and run.
The Action Wizard records a sequence of conductor actions as a named macro and replays it over a document or a batch of them — the automation surface for people who do not want to write against the API directly.
Plugins#
Redline's plugin story sits on the same seam: a plugin contributes actions to the conductor and receives a sandboxed context rather than raw engine internals, so what a plugin can do is exactly what is expressible as an action — which is also what makes it undoable, scriptable and inspectable for free.