Hyday Whiteboard Skill
First time in this conversation? Run Step 0 from hyday-vault-layout to find the vault root. The whiteboard MCP server below resolves it for you automatically (from ~/Library/Application Support/Hyday/settings.json on macOS or %APPDATA%\Hyday\settings.json on Windows — journalPath field), so as long as the server is configured and the user has opened Hyday once, you're fine. If you ever need to call the server with --data-root, see Step 0 in hyday-vault-layout for the lookup chain.
Hyday's Whiteboard is a 2D canvas where the user pins note cards, sticky notes, and grouping containers, and draws connections between them.
Unlike notes (which are plain .md files), whiteboard state lives in a sidecar JSON at <DATA_ROOT>/.hyday/whiteboards-v2.json. You operate it through the hyday-whiteboard MCP server, which exposes 12 tools.
Installation (one-time)
Before this skill works, the user must configure the MCP server in their agent's MCP config. See mcp-servers/hyday-whiteboard/README.md in this repo for the exact steps. The short version:
npm install inside mcp-servers/hyday-whiteboard/.
- Add an entry to
.mcp.json pointing node at whiteboard-server.cjs.
- The server auto-detects the Hyday vault from
settings.json; override with --data-root if needed.
Once configured, the agent has access to tools named mcphyday-whiteboard* (or similar — the exact prefix depends on the agent).
What's on a whiteboard
A board contains zero or more items and zero or more connections.
Item kinds
| Kind |
What it is |
Created with |
note (card) |
A card linked to an existing .md note. Shows the note's title and a preview. |
addNoteToWhiteboard or buildWhiteboardLayout |
sticky |
A free-form text snippet that lives only on the board — no backing .md file. |
addStickyNote |
group |
A visual container that wraps other items under a labelled header. |
createWhiteboardGroup or buildWhiteboardLayout |
Connections
Edges between two items. The server auto-picks the best handle (top/bottom/left/right) for the shortest path.
Coordinate system
x increases to the right, y increases downward (top-left is 0,0).
- Positions can be negative — the canvas extends infinitely.
- Item position is the top-left corner of the item's bounding box.
Workflow: build a board from scratch (preferred path)
Use buildWhiteboardLayout. It takes groups of note IDs plus optional connections and handles all positioning — column distribution, group sizing, card heights, connection handles. This avoids overlapping cards and bad spacing.
- Make sure every note you want as a card exists as a
.md file in the vault (see hyday-markdown and hyday-vault-layout). Get each note's fileId (filename without .md).
- Group the notes thematically —
[{title, noteIds}].
- Optionally declare connections between notes —
[{fromNoteId, toNoteId, label?}].
- Call
buildWhiteboardLayout once. The server returns a summary of what was created.
Example call shape:
{
"groups": [
{"title": "Foundations", "noteIds": ["systems-thinking-intro", "feedback-loops"]},
{"title": "Case studies", "noteIds": ["case-toyota", "case-netflix", "case-spotify"]},
{"title": "Practice", "noteIds": ["weekly-review-template", "decision-journal"]}
],
"connections": [
{"fromNoteId": "systems-thinking-intro", "toNoteId": "case-toyota", "label": "applies to"}
]
}
The server arranges groups left-to-right, places cards in 1 or 2 columns per group depending on count, sizes each card based on note content length, and draws connections with optimal handle positions.
Workflow: tweak an existing board
For incremental edits, use the per-item tools:
listWhiteboards — find the right boardId (default is 'main').
listWhiteboardItems(boardId) — see what's already there. Note each item's id, x, y, width, height.
- Then any of:
- addNoteToWhiteboard — append one card. Use the returned width×height to pick the next card's Y. - addStickyNote — add a sticky. - createWhiteboardGroup — wrap existing cards in a group (create the group after the cards so you know their bounding box). - createWhiteboardConnection — connect two items by their itemIds. - moveWhiteboardItems — batch reposition / resize. - updateWhiteboardItem — edit text / color / size of a single item. - removeWhiteboardItems — delete items (auto-drops their connections).
Tool reference
All tools take an optional boardId; omit to target the default board ('main').
Read
listWhiteboards() — returns boards with id, name, itemCount.
listWhiteboardItems({boardId?}) — returns items with id, noteId, itemKind, title, x, y, width, height.
Boards
createWhiteboard({name}) — new board.
deleteWhiteboard({boardId}) — soft-delete (recoverable). Cannot delete 'main'.
Items
addNoteToWhiteboard({boardId?, noteId, x, y, width?, height?})
- noteId is the note's filename without .md. - Do not pass height — let the server estimate from content. The response includes the actual width×height; use it to compute the next card's Y. - Default width is 200. Standard card.
addStickyNote({boardId?, content, x, y, color?})
- content is plain text — keep it short (a few words to one sentence). - color: yellow (default), blue, green, pink, purple, orange. - Sticky is 200×150.
createWhiteboardGroup({boardId?, title, x, y, width?, height?})
- title MUST be a meaningful theme name (e.g. "系統思考基礎"). Do not pass generic strings like "Group Name" — the server's description literally calls this out. - Create groups after placing the cards so you know the bounding box. - Positioning rule: x = leftmost-card-x - 30, y = topmost-card-y - 60 (room for title). - Sizing rule: width = card-area-width + 60, height = card-area-height + 90.
Connections
createWhiteboardConnection({boardId?, fromItemId, toItemId, label?}) — by item ID, not note ID. Handles are picked automatically.
Edits
updateWhiteboardItem({boardId?, itemId, content?, color?, width?, height?}) — change at least one field.
moveWhiteboardItems({boardId?, moves: [{itemId, x, y, width?, height?}]}) — batch.
removeWhiteboardItems({boardId?, itemIds}) — also removes connections touching the removed items.
Batch
buildWhiteboardLayout({boardId?, groups, connections?, cardWidth?, columns?}) — see workflow above. Preferred for any layout of >2 cards.
Key constraints and gotchas
noteId ≠ note title. It's the filename without .md. If you only have a title, find the file first (see hyday-vault-layout).
- Cards must not overlap. When placing cards manually, the rule is:
nextY = previousY + previousHeight + 40. With buildWhiteboardLayout this is handled for you.
- Don't pass
height to addNoteToWhiteboard. The auto-estimate is content-aware; an explicit height usually makes the card too tall or too short.
- Groups go behind cards (
zIndex = 0). Create cards first, then groups, otherwise the group title visually sits under cards.
- Connections are by
itemId, not noteId. Item IDs are returned when a card is created (or appear in listWhiteboardItems). Inside buildWhiteboardLayout, you specify connections by noteId because the server maps note → item for you.
Example: building a "Q3 reading review" board
- Ensure these notes exist (use
hyday-markdown skill to create them if needed):
- reading-notes-atomic-habits.md - reading-notes-deep-work.md - reading-notes-thinking-fast-slow.md
- Call:
{
"tool": "buildWhiteboardLayout",
"input": {
"groups": [
{
"title": "Best of Q3",
"noteIds": ["reading-notes-atomic-habits", "reading-notes-deep-work"]
},
{
"title": "Skim again later",
"noteIds": ["reading-notes-thinking-fast-slow"]
}
],
"connections": [
{
"fromNoteId": "reading-notes-atomic-habits",
"toNoteId": "reading-notes-deep-work",
"label": "shared theme: deliberate practice"
}
]
}
}
- Optional follow-up: add a header sticky at the top.
{
"tool": "addStickyNote",
"input": {
"content": "Q3 Reading Review",
"x": 0,
"y": -100,
"color": "yellow"
}
}
- Show the user — Hyday's whiteboard view will reflect changes immediately when they switch to it.
Validation checklist
After any whiteboard operation, verify:
- Every
noteId you used corresponds to a real .md file (otherwise the card shows the noteId as title and no preview).
- Group titles are meaningful, not
"Group Name" or "Untitled".
- If you placed cards manually, no two cards overlap (use the returned
height from each addNoteToWhiteboard to space them).
- Connections reference real
itemIds (per-item flow) or real noteIds (buildWhiteboardLayout flow).
- You used
buildWhiteboardLayout when creating >2 cards at once.
Notes on sync and portability
- The whiteboard sidecar is a regular file (
.hyday/whiteboards-v2.json). If the user's vault folder is inside iCloud, Dropbox, or another file-sync tool, the whiteboard syncs across machines along with the vault.
- The server keeps 3 rotating backups (
.backup.1, .backup.2, .backup.3) next to the sidecar.
- Soft-deleted boards move to
trashedBoards inside the same sidecar — they're not gone.
References
- Server installation and config:
mcp-servers/hyday-whiteboard/README.md
- Creating the notes that become cards: see
hyday-markdown skill
- Where notes live: see
hyday-vault-layout skill