3.7 KiB
GridCraft control protocol
Start the desktop app with a control port:
gridcraft --control 7979 # or GRIDCRAFT_CONTROL_PORT=7979
Then send newline-delimited JSON to 127.0.0.1:7979. Every request line gets one reply line:
{"id": 1, "method": "engine.execute", "params": {"command": "cell.set", "params": {"cell": "B2", "input": "=SUM(A1:A9)"}}}
{"id": 1, "ok": true, "result": {"cell": "B2", "value": "45"}}
Errors come back as {"id": …, "ok": false, "error": "…"}.
Methods
| Method | Params | What it does |
|---|---|---|
engine.execute |
{command, params} |
Runs any engine command (see engine.commands or gridcraft-cli commands) |
engine.commands |
{search?} |
Every command: id, label, ribbon path, shortcut, params doc, enabled; search keeps those whose id, label or ribbon path contains it (case-insensitive) |
engine.journal |
Commands run so far (replayable). Passwords (password, …Password params) are left out, so a replayed Protect Sheet has no password |
|
document.inspect |
Workbook summary: sheets, used ranges, tables, charts, names, selection, undo labels | |
sheet.read |
{range?, sheet?, formulas?, formatted?} |
Values (or formulas / displayed text) of a range |
cell.get |
{cell?} |
One cell: value, formula, displayed text, style, merge, comment, link |
ui.inspect |
UI state: ribbon tab, editor, open dialog, Backstage page, message, grid rect, scroll, perf | |
ui.click / ui.drag / ui.move |
{x, y, toX?, toY?, button?, count?, shift?, cmd?, alt?} |
Real pointer input in window points |
ui.cell.click / ui.cell.drag |
{cell} / {from, to} |
Pointer input at a cell's centre (works in point mode while editing) |
ui.key / ui.text |
{key, shift?, cmd?, alt?, ctrl?} / {text} |
Keyboard input (typing in the grid starts editing) |
ui.edit.begin / ui.edit.text / ui.edit.commit / ui.edit.cancel |
{text?} / {move?: down|right|up|left|none} |
Drive the cell editor |
ui.ribbon |
{tab} |
Switch ribbon tab |
ui.dialog / ui.dialog.set / ui.dialog.confirm / ui.dialog.cancel |
{name} / {field, value} |
Open, fill in and confirm dialogs |
ui.backstage (via engine.execute) |
{page?: home|new|open|info|saveAs|print|export|options|close} |
Open the File tab's Backstage view on a page, or close it (ui.inspect reports the open page as backstage) |
ui.screenshot |
{path?} |
PNG of the window (base64 when no path) |
ui.set |
{dark?, formulaBar?, ribbonCollapsed?} |
UI preferences (formulaBar runs view.formulaBar) |
ui.resize / ui.focus |
{width, height} |
Window control |
app.open / app.save / app.quit |
{path} / {path?} |
Files and lifetime |
Any other method name that is a command id (e.g. home.bold) runs that command.
Use engine.execute with {command: "view.theme", params: {mode: "system"}}
to choose the display theme; mode accepts "system", "light", or "dark".
System follows live OS appearance changes and falls back to Light when the platform supplies no preference.
The saved choice remains System; new users still start in Light. The legacy
view.darkMode command and ui.set {dark} select a fixed Light or Dark theme.
{command: "app.language.set", params: {language: "ja"}} switches the interface language
(code is accepted as an alias for language); app.language.english and
app.language.japanese are shortcuts. Only interface chrome is translated, never command ids or
document text. The choice is saved in ui.json; with nothing saved the desktop app follows the
system language.
For a headless equivalent (no window), use gridcraft-cli mcp or gridcraft-cli run;
see mcp.md and cli.md.