Content Tools

A canvas board is JSON Canvas and a drawing is Excalidraw. The tools here build and change those files from a compact spec. You send a node list or Mermaid source and the server writes the JSON. Every call lands in version history like any other write. The request envelope is the same as every other tool, see Calling Tools.

Terminal
curl -X POST "https://www.monofile.ai/api/tools/checkpoint" \
  -H "Authorization: Bearer $MONOFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "/Projects", "name": "before refactor"}'

Canvas boards

A .canvas file is a spatial board of nodes and edges, described in Canvas Boards.

Both write tools take the same node and edge fields:

Node fieldApplies toDescription
typealltext, file, link or group
refallName this node so later ops can point at it as $name. Letters, digits and underscores, up to 32 characters
x, y, width, heightallPosition and size. Omit them and let auto-layout place the node
colorallNode color
texttextMarkdown content of a note
filefileWorkspace-relative path, for example screens/home.html
contentfileWrite that file with this content in the same call. An HTML file node renders live as an artboard at the node size
subpathfileA #heading inside the file
urllinkThe link target
labelgroupCaption of a group frame
Edge fieldDescription
fromNode, toNodeNode ids, or $n and $ref references to nodes created in the same call
fromSide, toSideWhich side of the node the edge leaves or enters
fromEnd, toEndArrow ends
color, labelAppearance and caption

create_canvas

Creates a board in one call, with its nodes, the edges between them and, if you ask, a layout pass that positions everything.

InputTypeRequiredDescription
pathstringyesPath ending in .canvas
nodesarraynoUp to 200 node specs
edgesarraynoUp to 200 edge specs
layoutstringnoAuto-layout direction: RIGHT, DOWN, LEFT or UP. Recommended whenever you omit x and y
overwritebooleannoReplace an existing file instead of failing with FILE_EXISTS

Scope: files:write. The response carries createdNodeIds, createdEdgeIds and a compact node map you can use for follow-up calls.

POST/api/tools/create_canvas
{
  "path": "/boards/pipeline.canvas",
  "nodes": [
    { "type": "text", "ref": "intake", "text": "## Intake\nForms land here" },
    { "type": "text", "ref": "review", "text": "## Review" },
    { "type": "file", "file": "Projects/spec.md" }
  ],
  "edges": [{ "fromNode": "$intake", "toNode": "$review", "label": "queued" }],
  "layout": "RIGHT"
}

canvas_edit

Applies a batch of operations to a board in order, creating the file if it does not exist. The batch is atomic. If any operation fails, nothing is written.

InputTypeRequiredDescription
pathstringyesPath ending in .canvas
opsarrayyes1 to 200 operations, applied in order
OperationShape
add_nodeThe node fields above
update_node{ "id", "set": { fields to change } }. A null value removes a field
delete_nodes{ "ids": [...] }. Edges touching a deleted node go with it
add_edge or connectThe edge fields above
update_edge{ "id", "set": { ... } }
delete_edges{ "ids": [...] }
layout{ "direction", "nodeIds" }. Omit nodeIds to lay out the whole board

Scope: files:write.

Later operations can refer to earlier ones. $1 is the first creating operation in the batch, $2 the second, and $name is any operation that declared ref: "name". So one call can create a node, connect it to the node it just created, and lay out the result, with no round trip to learn the new id.

POST/api/tools/canvas_edit
{
  "path": "/boards/pipeline.canvas",
  "ops": [
    { "op": "add_node", "ref": "ship", "type": "text", "text": "## Ship" },
    { "op": "connect", "fromNode": "review-node-id", "toNode": "$ship" },
    { "op": "layout", "direction": "RIGHT" }
  ]
}

An error names the index of the operation that failed, with one of INVALID_OP, UNKNOWN_REF, NODE_NOT_FOUND, EDGE_NOT_FOUND, MISSING_FIELD, INVALID_DOCUMENT.

canvas_check

Reports whether a board's file references still point at real files.

InputTypeRequiredDescription
pathstringyesPath to the .canvas file
repairbooleannoRewrite the fixable references in place. Default false

Scope: files:read. repair: true also needs files:write. A read-only key can still inspect a board.

POST/api/tools/canvas_check
{ "path": "/boards/pipeline.canvas" }
Status values
StatusRendersMeaning
okyesId and path both match
path_staleyesThe file moved and the node's portable path did not. Repairable
path_onlyyesNo stable id, so one rename away from breaking. Repairable
unresolved_idnoThe id matches nothing here, for example a board forked in from another workspace
missingnoNothing matches the path
section_missingnoThe file is there, the #heading is not
subpath_ignoredyesA #section on a file that has no sections

repair: true rewrites only path_stale and path_only. It leaves a node that resolves to nothing alone.

Slide decks

A .slides deck is plain markdown, so write and edit work on it. Four tools address slides by number or id so you do not have to count separators. They mirror the canvas tools, and the built-in assistant uses the same ones. The format, the inspector and presenting are on Slide Decks.

create_slides

Creates a deck from a structured spec in one call. Each slide takes content (markdown, or HTML with html: true), optional notes, layout, id, background, src and skip. Slides without an id get one minted. Scope: files:write.

POST/api/tools/create_slides
{
  "path": "/decks/pitch.slides",
  "title": "Monofile pitch",
  "theme": "midnight",
  "slides": [
    { "id": "intro", "layout": "title", "content": "# Monofile\nOne filesystem for people and agents", "notes": "Thirty seconds on who we are." }
  ]
}

The response carries the slide count, the created ids, a compact slide list and a contentHash for the next edit.

slides_edit

Applies a batch of operations in order, atomically: insert_slide, update_slide, delete_slides, move_slide and set_deck. Address slides by 1-based number, by #id, or by $n for a slide inserted earlier in the same batch. Pass the previous contentHash as ifHash to refuse the write if the deck changed in between. Scope: files:write.

POST/api/tools/slides_edit
{
  "path": "/decks/pitch.slides",
  "ops": [
    { "op": "insert_slide", "after": "#intro", "slide": { "id": "next", "content": "## Next steps\n- Ship the desktop beta" } }
  ],
  "ifHash": "1a2b3c4d-k9"
}

Inserting a slide whose id already exists is a no-op with a warning, so a retry does not duplicate the slide. If any operation fails, nothing is written.

slides_check

Reports missing or moved references, empty slides, duplicate ids, slides without notes and slides over their word budget. repair: true rewrites moved references in place. Scope: files:read, plus files:write for a repair.

POST/api/tools/slides_check
{ "path": "/decks/pitch.slides", "repair": true }

slides_export

Writes the deck to the workspace as standalone HTML or an editable PowerPoint file. format is html or pptx; output defaults to the deck's path with the new extension; overwrite replaces an existing output instead of failing with FILE_EXISTS. A .pptx lands as an attachment file (a download card). Scope: files:write.

POST/api/tools/slides_export
{ "path": "/decks/pitch.slides", "format": "pptx", "overwrite": true }

Diagrams

create_diagram

Turns Mermaid source into an editable Excalidraw drawing and saves it as a .draw file. Send standard Mermaid and the server converts it. Do not write Excalidraw JSON by hand.

InputTypeRequiredDescription
mermaidstringyesMermaid source, up to 50 KB
pathstringyesPath ending in .draw

Scope: files:write. Five diagram types convert: flowchart (graph TD and graph LR, including subgraphs and classDef styling), sequenceDiagram, classDiagram, erDiagram and stateDiagram-v2. Anything else comes back as UNSUPPORTED_TYPE.

POST/api/tools/create_diagram
{
  "path": "/diagrams/login.draw",
  "mermaid": "graph TD\n  A[Start] --> B{Valid?}\n  B -->|Yes| C[Process]\n  B -->|No| D[Error]"
}

A syntax error returns PARSE_ERROR with the line number, so fix that line and retry. The saved file keeps the Mermaid source alongside the drawing, so you can read it back and regenerate later. See Diagrams and Drawings.

Versions and history

Monofile captures every write as a version and groups the writes of one call into a changeset. These six tools read and undo that history. The concepts are in How Versioning Works and Changesets.

list_versions

A file's version history, newest first, metadata only.

InputTypeRequiredDescription
pathstringyesFull path to the file
limitnumberno1 to 50, out-of-range values are clamped. Default 20

Scope: files:read. Each entry carries a source (agent for an automatic before-image, user for a human edit, checkpoint, revert), an operation, and the changeset it belongs to. Start here to get the versionId the next two tools need.

POST/api/tools/list_versions
{ "path": "/Projects/report.md", "limit": 10 }

read_version

The content of one previous version. Use it to compare an old version against the current content.

InputTypeRequiredDescription
pathstringyesFull path to the file
versionIdstringyesFrom list_versions

Scope: files:read.

POST/api/tools/read_version
{ "path": "/Projects/report.md", "versionId": "<versionId from list_versions>" }

revert_file

Restores a file to a previous version. It saves the current content as a new version first, so you can undo the revert.

InputTypeRequiredDescription
pathstringyesFull path to the file
versionIdstringyesThe version to restore

Scope: files:write. For undoing a whole multi-file run, use revert_changeset instead.

POST/api/tools/revert_file
{ "path": "/Projects/report.md", "versionId": "<versionId from list_versions>" }

checkpoint

A named snapshot of the current content of a file, or of every file under a folder. Monofile does not prune checkpoints automatically, so take one before a large or risky change.

InputTypeRequiredDescription
pathstringyesFile or folder path
namestringyes1 to 60 characters, for example before refactor

Scope: files:write. Caps: 10 checkpoints per file, and 200 files per folder checkpoint. See Checkpoints.

POST/api/tools/checkpoint
{ "path": "/Projects", "name": "before refactor" }

list_changesets

Recent changesets, newest first, each with the files it touched and a summary.

InputTypeRequiredDescription
limitnumberno1 to 50, clamped. Default 10
pathstringnoOnly changesets that touched this file

Scope: files:read. This is how you find the changesetId when someone asks you to undo a previous run.

POST/api/tools/list_changesets
{ "limit": 10, "path": "/Projects/report.md" }

revert_changeset

Undoes an entire changeset. Each file goes back to its content before the run, and files the run created are deleted.

InputTypeRequiredDescription
changesetIdstringyesFrom list_changesets
forcebooleannoRevert even if files moved on since. Default false

Scope: files:write and files:delete. If anyone wrote to a file after the changeset, the call fails with CONFLICT and lists what changed. Confirm with whoever owns the work, then retry with force: true. Either way the tool captures the pre-revert state first, so you can revert the revert. Reverting Safely covers when to force.

POST/api/tools/revert_changeset
{ "changesetId": "<changesetId from list_changesets>" }

Next steps

  • Calling ToolsThe one-endpoint pattern, the MCP-shaped envelope, and the index of every tool.

  • File and Shell ToolsReading, writing and editing files, plus the two shell tiers.

  • ChangesetsRuns grouped into one reviewable, revertable unit.

  • Canvas BoardsSpatial boards of live file nodes, notes, links, groups and labelled edges.

1723 words