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 mcp__hyday-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
1---2name: hyday-whiteboard3description: Hyday Whiteboard Skill4---56# Hyday Whiteboard Skill78> **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.910Hyday's **Whiteboard** is a 2D canvas where the user pins note cards, sticky notes, and grouping containers, and draws connections between them.1112Unlike 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.1314## Installation (one-time)1516Before 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:17181. `npm install` inside `mcp-servers/hyday-whiteboard/`.192. Add an entry to `.mcp.json` pointing `node` at `whiteboard-server.cjs`.203. The server auto-detects the Hyday vault from `settings.json`; override with `--data-root` if needed.2122Once configured, the agent has access to tools named `mcp__hyday-whiteboard__*` (or similar — the exact prefix depends on the agent).2324## What's on a whiteboard2526A board contains zero or more **items** and zero or more **connections**.2728### Item kinds2930| Kind | What it is | Created with |31|------|-----------|--------------|32| `note` (card) | A card linked to an existing `.md` note. Shows the note's title and a preview. | `addNoteToWhiteboard` or `buildWhiteboardLayout` |33| `sticky` | A free-form text snippet that lives only on the board — no backing `.md` file. | `addStickyNote` |34| `group` | A visual container that wraps other items under a labelled header. | `createWhiteboardGroup` or `buildWhiteboardLayout` |3536### Connections3738Edges between two items. The server auto-picks the best handle (top/bottom/left/right) for the shortest path.3940## Coordinate system4142- `x` increases to the right, `y` increases **downward** (top-left is `0,0`).43- Positions can be negative — the canvas extends infinitely.44- Item position is the **top-left corner** of the item's bounding box.4546## Workflow: build a board from scratch (preferred path)4748**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.49501. 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`).512. Group the notes thematically — `[{title, noteIds}]`.523. Optionally declare connections between notes — `[{fromNoteId, toNoteId, label?}]`.534. Call `buildWhiteboardLayout` once. The server returns a summary of what was created.5455Example call shape:5657```json58{59 "groups": [60 {"title": "Foundations", "noteIds": ["systems-thinking-intro", "feedback-loops"]},61 {"title": "Case studies", "noteIds": ["case-toyota", "case-netflix", "case-spotify"]},62 {"title": "Practice", "noteIds": ["weekly-review-template", "decision-journal"]}63 ],64 "connections": [65 {"fromNoteId": "systems-thinking-intro", "toNoteId": "case-toyota", "label": "applies to"}66 ]67}68```6970The 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.7172## Workflow: tweak an existing board7374For incremental edits, use the per-item tools:75761. `listWhiteboards` — find the right `boardId` (default is `'main'`).772. `listWhiteboardItems(boardId)` — see what's already there. Note each item's `id`, `x`, `y`, `width`, `height`.783. Then any of:79 - `addNoteToWhiteboard` — append one card. Use the returned `width×height` to pick the next card's Y.80 - `addStickyNote` — add a sticky.81 - `createWhiteboardGroup` — wrap existing cards in a group (create the group **after** the cards so you know their bounding box).82 - `createWhiteboardConnection` — connect two items by their `itemId`s.83 - `moveWhiteboardItems` — batch reposition / resize.84 - `updateWhiteboardItem` — edit text / color / size of a single item.85 - `removeWhiteboardItems` — delete items (auto-drops their connections).8687## Tool reference8889All tools take an optional `boardId`; omit to target the default board (`'main'`).9091### Read9293- **`listWhiteboards()`** — returns boards with `id`, `name`, `itemCount`.94- **`listWhiteboardItems({boardId?})`** — returns items with `id`, `noteId`, `itemKind`, `title`, `x`, `y`, `width`, `height`.9596### Boards9798- **`createWhiteboard({name})`** — new board.99- **`deleteWhiteboard({boardId})`** — soft-delete (recoverable). Cannot delete `'main'`.100101### Items102103- **`addNoteToWhiteboard({boardId?, noteId, x, y, width?, height?})`**104 - `noteId` is the note's filename without `.md`.105 - **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.106 - Default `width` is 200. Standard card.107- **`addStickyNote({boardId?, content, x, y, color?})`**108 - `content` is plain text — keep it short (a few words to one sentence).109 - `color`: `yellow` (default), `blue`, `green`, `pink`, `purple`, `orange`.110 - Sticky is `200×150`.111- **`createWhiteboardGroup({boardId?, title, x, y, width?, height?})`**112 - **`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.113 - Create groups **after** placing the cards so you know the bounding box.114 - Positioning rule: `x = leftmost-card-x - 30`, `y = topmost-card-y - 60` (room for title).115 - Sizing rule: `width = card-area-width + 60`, `height = card-area-height + 90`.116117### Connections118119- **`createWhiteboardConnection({boardId?, fromItemId, toItemId, label?})`** — by **item ID**, not note ID. Handles are picked automatically.120121### Edits122123- **`updateWhiteboardItem({boardId?, itemId, content?, color?, width?, height?})`** — change at least one field.124- **`moveWhiteboardItems({boardId?, moves: [{itemId, x, y, width?, height?}]})`** — batch.125- **`removeWhiteboardItems({boardId?, itemIds})`** — also removes connections touching the removed items.126127### Batch128129- **`buildWhiteboardLayout({boardId?, groups, connections?, cardWidth?, columns?})`** — see workflow above. **Preferred** for any layout of >2 cards.130131## Key constraints and gotchas132133- **`noteId` ≠ note title.** It's the filename without `.md`. If you only have a title, find the file first (see `hyday-vault-layout`).134- **Cards must not overlap.** When placing cards manually, the rule is: `nextY = previousY + previousHeight + 40`. With `buildWhiteboardLayout` this is handled for you.135- **Don't pass `height` to `addNoteToWhiteboard`.** The auto-estimate is content-aware; an explicit height usually makes the card too tall or too short.136- **Groups go behind cards** (`zIndex = 0`). Create cards first, then groups, otherwise the group title visually sits under cards.137- **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.138139## Example: building a "Q3 reading review" board1401411. Ensure these notes exist (use `hyday-markdown` skill to create them if needed):142 - `reading-notes-atomic-habits.md`143 - `reading-notes-deep-work.md`144 - `reading-notes-thinking-fast-slow.md`1452. Call:146147```json148{149 "tool": "buildWhiteboardLayout",150 "input": {151 "groups": [152 {153 "title": "Best of Q3",154 "noteIds": ["reading-notes-atomic-habits", "reading-notes-deep-work"]155 },156 {157 "title": "Skim again later",158 "noteIds": ["reading-notes-thinking-fast-slow"]159 }160 ],161 "connections": [162 {163 "fromNoteId": "reading-notes-atomic-habits",164 "toNoteId": "reading-notes-deep-work",165 "label": "shared theme: deliberate practice"166 }167 ]168 }169}170```1711723. Optional follow-up: add a header sticky at the top.173174```json175{176 "tool": "addStickyNote",177 "input": {178 "content": "Q3 Reading Review",179 "x": 0,180 "y": -100,181 "color": "yellow"182 }183}184```1851864. Show the user — Hyday's whiteboard view will reflect changes immediately when they switch to it.187188## Validation checklist189190After any whiteboard operation, verify:1911921. Every `noteId` you used corresponds to a real `.md` file (otherwise the card shows the noteId as title and no preview).1932. Group titles are meaningful, not `"Group Name"` or `"Untitled"`.1943. If you placed cards manually, no two cards overlap (use the returned `height` from each `addNoteToWhiteboard` to space them).1954. Connections reference real `itemId`s (per-item flow) or real `noteId`s (`buildWhiteboardLayout` flow).1965. You used `buildWhiteboardLayout` when creating >2 cards at once.197198## Notes on sync and portability199200- 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.201- The server keeps 3 rotating backups (`.backup.1`, `.backup.2`, `.backup.3`) next to the sidecar.202- Soft-deleted boards move to `trashedBoards` inside the same sidecar — they're not gone.203204## References205206- Server installation and config: `mcp-servers/hyday-whiteboard/README.md`207- Creating the notes that become cards: see `hyday-markdown` skill208- Where notes live: see `hyday-vault-layout` skill