read_canvas
Extract and display content from Obsidian canvas files to access visual notes and diagrams within your vault.
Instructions
Read and display the contents of an Obsidian canvas file
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the .canvas file |
Implementation Reference
- src/tools/canvas.ts:37-103 (handler)The handler for "read_canvas", which reads a canvas file using readCanvasFile and formats it for output.
server.registerTool( "read_canvas", { description: "Read and display the contents of an Obsidian canvas file", inputSchema: { path: z.string().min(1).describe("Relative path to the .canvas file"), }, }, async ({ path: canvasPath }) => { try { const data = await readCanvasFile(vaultPath, canvasPath); const lines: string[] = []; lines.push(`Canvas: ${canvasPath}`); lines.push(`Nodes: ${data.nodes.length} | Edges: ${data.edges.length}`); lines.push(""); if (data.nodes.length > 0) { lines.push("--- Nodes ---"); for (const node of data.nodes) { const pos = `(${node.x}, ${node.y})`; const size = `${node.width}x${node.height}`; let preview = ""; if (node.type === "text" && node.text) { preview = node.text.length > 100 ? node.text.slice(0, 100) + "..." : node.text; } else if (node.type === "file" && node.file) { preview = node.file; } else if (node.type === "link" && node.url) { preview = node.url; } else if (node.type === "group" && node.label) { preview = `Group: ${node.label}`; } lines.push(` [${node.id}] type=${node.type} pos=${pos} size=${size}`); if (preview) { lines.push(` content: ${preview}`); } if (node.color) { lines.push(` color: ${node.color}`); } } lines.push(""); } if (data.edges.length > 0) { lines.push("--- Edges ---"); for (const edge of data.edges) { const label = edge.label ? ` [${edge.label}]` : ""; const sides = [ edge.fromSide ? `from-side=${edge.fromSide}` : "", edge.toSide ? `to-side=${edge.toSide}` : "", ].filter(Boolean).join(" "); const sideInfo = sides ? ` (${sides})` : ""; lines.push(` ${edge.fromNode} -> ${edge.toNode}${label}${sideInfo}`); } } return { content: [{ type: "text" as const, text: lines.join("\n") }] }; } catch (err) { console.error("Failed to read canvas:", err); return errorResult(`Error reading canvas: ${err instanceof Error ? err.message : String(err)}`); } }, ); - src/tools/canvas.ts:11-37 (registration)Tool registration for canvas related tools including "read_canvas".
export function registerCanvasTools(server: McpServer, vaultPath: string): void { server.registerTool( "list_canvases", { description: "List all canvas files in the vault", inputSchema: {}, }, async () => { try { const files = await listCanvasFiles(vaultPath); if (files.length === 0) { return { content: [{ type: "text" as const, text: "No canvas files found in the vault." }] }; } const formatted = files.map((f, i) => `${i + 1}. ${f}`).join("\n"); return { content: [{ type: "text" as const, text: `Found ${files.length} canvas file(s):\n\n${formatted}` }], }; } catch (err) { console.error("Failed to list canvas files:", err); return errorResult(`Error listing canvas files: ${err instanceof Error ? err.message : String(err)}`); } }, ); server.registerTool(