一键导入
obsidian-canvas
Create and manipulate Obsidian Canvas (.canvas) files using the JSON Canvas spec
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create and manipulate Obsidian Canvas (.canvas) files using the JSON Canvas spec
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Run the self-improvement pipeline to analyze usage, plan, and apply Claude Code configuration improvements
Create, schedule, and manage autonomous AI-agent tasks with systemd timers
Create a git commit with proper conventional commit message
Code generation, exploration, and image analysis via Codex CLI
Query Gemini CLI for quick lookups, deep research, and approach comparison
Populate styled ODT/OTT templates with content while preserving formatting
| name | obsidian-canvas |
| description | Create and manipulate Obsidian Canvas (.canvas) files using the JSON Canvas spec |
| argument-hint | <vault-name> [canvas description or path] |
| model | sonnet |
Create and edit .canvas files (JSON Canvas v1.0) for spatial thinking, flowcharts, mind maps, and knowledge graphs.
Vaults root: ~/Apps/Obsidian/
The first argument ($ARGUMENTS) identifies the vault. Extract the vault name from the first word/token — it is a subdirectory of the vaults root. The remaining arguments describe what to create or which canvas to modify.
~/Apps/Obsidian/<vault-name>/ls ~/Apps/Obsidian/ if the user's vault name doesn't match.canvas files when editing."Notes/topic.md" not absolute paths).{
"nodes": [],
"edges": []
}
Both arrays are optional. An empty {} is valid. Nodes are ordered by ascending z-index (first = bottom, last = top).
| Property | Type | Required | Description |
|---|---|---|---|
id | string | yes | Unique identifier (16-char hex) |
type | string | yes | "text", "file", "link", "group" |
x | integer | yes | X position in pixels |
y | integer | yes | Y position in pixels |
width | integer | yes | Width in pixels |
height | integer | yes | Height in pixels |
color | string | no | Preset "1"-"6" or hex "#RRGGBB" |
{
"id": "a1b2c3d4e5f6a7b8",
"type": "text",
"x": 0, "y": 0, "width": 400, "height": 200,
"text": "# Heading\n\nMarkdown content with **bold** and *italic*."
}
Additional: text (string, required) — Markdown-formatted content.
{
"id": "b2c3d4e5f6a7b8c9",
"type": "file",
"x": 500, "y": 0, "width": 400, "height": 300,
"file": "Notes/my-note.md",
"subpath": "#Section Name"
}
Additional: file (string, required) — vault-relative path. subpath (string, optional) — heading/block link, starts with #.
{
"id": "c3d4e5f6a7b8c9d0",
"type": "link",
"x": 0, "y": 300, "width": 400, "height": 200,
"url": "https://example.com"
}
Additional: url (string, required) — external URL.
{
"id": "d4e5f6a7b8c9d0e1",
"type": "group",
"x": -50, "y": -50, "width": 1000, "height": 600,
"label": "Phase 1",
"background": "assets/texture.png",
"backgroundStyle": "cover"
}
Additional: label (string, optional), background (string, optional — image path), backgroundStyle (string, optional — "cover", "ratio", or "repeat").
Group membership is implicit via spatial containment — no parent/children properties. Place groups before their contained nodes in the array (lower z-index).
| Property | Type | Required | Description |
|---|---|---|---|
id | string | yes | Unique identifier (16-char hex) |
fromNode | string | yes | Source node ID |
fromSide | string | no | "top", "right", "bottom", "left" |
fromEnd | string | no | "none" (default) or "arrow" |
toNode | string | yes | Target node ID |
toSide | string | no | "top", "right", "bottom", "left" |
toEnd | string | no | "arrow" (default) or "none" |
color | string | no | Same color format as nodes |
label | string | no | Text displayed along the edge |
Default: one-way arrow (fromEnd=none, toEnd=arrow). Set both to "arrow" for bidirectional, both to "none" for plain line.
{
"id": "e5f6a7b8c9d0e1f2",
"fromNode": "a1b2c3d4e5f6a7b8",
"fromSide": "right",
"toNode": "b2c3d4e5f6a7b8c9",
"toSide": "left",
"label": "relates to"
}
| Value | Color |
|---|---|
"1" | Red |
"2" | Orange |
"3" | Yellow |
"4" | Green |
"5" | Cyan |
"6" | Purple |
Or use hex: "#FF6B6B". Omit color for the default/neutral color.
Use 16-character random lowercase hex strings: "a1b2c3d4e5f6a7b8". Each ID must be unique within the canvas. Generate fresh IDs for every node and edge.
| Content Type | Width | Height |
|---|---|---|
| Short text card | 250 | 120 |
| Standard text node | 400 | 200 |
| Detailed text node | 500 | 300 |
| File embed | 400 | 300 |
| Link preview | 350 | 200 |
| Small group | 600 | 400 |
| Large group | 1200 | 800 |
Horizontal flow (left to right):
x: 0 x: 520 x: 1040
y: 0 y: 0 y: 0
[Node A] --> [Node B] --> [Node C]
Vertical flow (top to bottom):
x: 0, y: 0 [Node A]
x: 0, y: 320 [Node B]
x: 0, y: 640 [Node C]
Grid (rows and columns):
(0,0) (520,0) (1040,0)
(0,320) (520,320) (1040,320)
Radial (center + surrounding): Place the central node at (0, 0), then arrange related nodes in a circle at radius ~400px.
Horizontal or vertical sequence of text nodes connected by edges. Use fromSide/toSide to control routing. Color-code by status or category.
Central topic node with radiating branches. Use group nodes to cluster related branches. Edges from center outward, no fromSide/toSide needed (auto-routed).
Mix of file nodes (existing notes) and text nodes (annotations) with labeled edges describing relationships. Use color to distinguish node roles.
Columns as group nodes side by side. Task cards as text nodes inside each group. Move cards between groups by updating x/y coordinates.
{
"nodes": [
{"id": "g1", "type": "group", "x": 0, "y": 0, "width": 300, "height": 600, "label": "To Do", "color": "1"},
{"id": "g2", "type": "group", "x": 380, "y": 0, "width": 300, "height": 600, "label": "In Progress", "color": "3"},
{"id": "g3", "type": "group", "x": 760, "y": 0, "width": 300, "height": 600, "label": "Done", "color": "4"},
{"id": "t1", "type": "text", "x": 25, "y": 50, "width": 250, "height": 100, "text": "Task one"},
{"id": "t2", "type": "text", "x": 405, "y": 50, "width": 250, "height": 100, "text": "Task two"}
],
"edges": []
}
{
"nodes": [
{
"id": "d4e5f6a7b8c9d0e1",
"type": "group",
"x": -50,
"y": -50,
"width": 1100,
"height": 500,
"label": "Research",
"color": "5"
},
{
"id": "a1b2c3d4e5f6a7b8",
"type": "text",
"x": 0,
"y": 0,
"width": 400,
"height": 200,
"color": "4",
"text": "# Overview\n\nStarting point for the research project."
},
{
"id": "b2c3d4e5f6a7b8c9",
"type": "file",
"x": 520,
"y": 0,
"width": 400,
"height": 300,
"file": "Notes/literature-review.md",
"subpath": "#Key Findings"
},
{
"id": "c3d4e5f6a7b8c9d0",
"type": "link",
"x": 0,
"y": 300,
"width": 350,
"height": 200,
"url": "https://arxiv.org/abs/example"
}
],
"edges": [
{
"id": "e5f6a7b8c9d0e1f2",
"fromNode": "a1b2c3d4e5f6a7b8",
"fromSide": "right",
"toNode": "b2c3d4e5f6a7b8c9",
"toSide": "left",
"label": "see also"
},
{
"id": "f6a7b8c9d0e1f2a3",
"fromNode": "a1b2c3d4e5f6a7b8",
"fromSide": "bottom",
"toNode": "c3d4e5f6a7b8c9d0",
"toSide": "top",
"fromEnd": "arrow",
"toEnd": "arrow"
}
]
}
fromSide/toSide on edges to let Obsidian auto-route them