Skip to main content
Glama

read_canvas

Extract and display content from Obsidian canvas files to access visual notes and diagrams stored in your vault.

Instructions

Read and display the contents of an Obsidian canvas file

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path to the .canvas file

Implementation Reference

  • The 'read_canvas' tool handler defined in 'registerCanvasTools'. It accepts a file path, reads the canvas data, and returns a formatted text representation of the nodes and edges.
    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)}`);
        }
      },
    );
  • The 'registerCanvasTools' function where 'read_canvas' is registered to the MCP server.
    export function registerCanvasTools(server: McpServer, vaultPath: string): void {
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden but offers minimal behavioral insight. It mentions 'read and display' but doesn't disclose error handling (e.g., if file is missing), output format, or performance aspects like rate limits. This is inadequate for a tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose ('Read and display the contents') without unnecessary words. Every part earns its place by specifying the resource type, making it appropriately sized for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description is incomplete for a read operation. It doesn't explain what 'display' means in terms of return values (e.g., structured data vs. raw text) or error conditions, leaving significant gaps for the agent to handle this tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the single parameter 'path' well-documented in the schema as a relative path to a .canvas file. The description adds no additional parameter semantics beyond what the schema provides, so it meets the baseline for high coverage without compensating value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read and display') and resource ('contents of an Obsidian canvas file'), making the purpose immediately understandable. However, it doesn't differentiate from sibling tools like 'get_note' or 'list_canvases' beyond specifying the file type, missing an opportunity to clarify its unique role among reading operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. With siblings like 'list_canvases' (for listing) and 'get_note' (for reading notes), the description lacks context on prerequisites (e.g., file must exist) or comparisons, leaving the agent to infer usage based on tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rps321321/obsidian-mcp-pro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server