Parse Canvas
canvas.parseParse an Obsidian canvas file to retrieve its full node and edge structure. Use this for complete graph analysis when neighbor-only queries are insufficient. Read-only.
Instructions
Parse an Obsidian canvas file and return its full structure: every node (text, file, link, group) and every edge. Use this when you need the complete graph; for just the neighbours of a specific node, call canvas.connections instead. Read-only.
Operates on the session-active vault (see vault.current — selectable via vault.select) unless an explicit vaultPath argument is passed, which always wins.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Vault-relative path to an Obsidian `.canvas` file. | |
| vaultPath | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | ||
| nodes | Yes | ||
| edges | Yes |
Implementation Reference
- src/server/tools/canvas.ts:38-50 (registration)Registration of the canvas.parse tool in the tool definitions array, wiring it to parseCanvas domain function.
{ name: "canvas.parse", title: "Parse Canvas", description: "Parse an Obsidian canvas file and return its full structure: every node (text, file, link, group) and every edge. Use this when you need the complete graph; for just the neighbours of a specific node, call `canvas.connections` instead. Read-only.", inputSchema: canvasParseArgsSchema, outputSchema: canvasParseOutputSchema, annotations: READ_ONLY, handler: async (context, rawArgs) => { const args = canvasParseArgsSchema.parse(rawArgs) as CanvasParseArgs; return parseCanvas(context, args); }, }, - src/domain/canvas.ts:47-61 (handler)Core handler that loads a canvas file from disk and returns its full structure (nodes, edges, counts).
export async function parseCanvas( context: DomainContext, args: { filePath: string; vaultPath?: string }, ) { const vaultRoot = requireVaultPath(context, args.vaultPath); const absolutePath = resolveVaultPath(vaultRoot, args.filePath); const canvas = await loadCanvas(absolutePath); return { filePath: args.filePath, nodes: canvas.nodes, edges: canvas.edges, nodeCount: canvas.nodes.length, edgeCount: canvas.edges.length, }; } - src/schema/canvas.ts:21-27 (schema)Input schema for canvas.parse: requires filePath, optional vaultPath.
export const canvasParseArgsSchema = z .object({ filePath: canvasFilePathSchema, vaultPath: z.string().optional(), }) .strict(); export type CanvasParseArgs = z.input<typeof canvasParseArgsSchema>; - src/schema/canvas.ts:83-89 (schema)Output schema for canvas.parse: returns filePath, nodes, and edges arrays with passthrough for extra fields.
export const canvasParseOutputSchema = z .object({ filePath: z.string(), nodes: z.array(z.record(z.string(), z.unknown())), edges: z.array(z.record(z.string(), z.unknown())), }) .passthrough(); - src/domain/canvas.ts:12-23 (helper)Helper function used by parseCanvas to read and parse the canvas JSON file from disk.
async function loadCanvas(filePath: string): Promise<CanvasDocument> { const raw = await readUtf8(filePath); try { const parsed = JSON.parse(raw) as Partial<CanvasDocument>; return { nodes: Array.isArray(parsed.nodes) ? (parsed.nodes as CanvasNode[]) : [], edges: Array.isArray(parsed.edges) ? (parsed.edges as CanvasEdge[]) : [], }; } catch (error) { throw new AppError("invalid_argument", `Invalid canvas JSON: ${filePath}`, { cause: error }); } }