Skip to main content
Glama
sureshsankaran

Obsidian Tools MCP Server

insert_at_heading

Insert content under a specific heading in an Obsidian note to organize information within sections.

Instructions

Insert content under a specific heading in a note

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the note
headingYesThe heading text to insert content under
contentYesContent to insert
positionNoInsert at start or end of the heading section. Default: endend

Implementation Reference

  • The core handler function that executes the tool: reads the note, finds the specified heading using regex, determines the section end by next higher/same level heading, inserts content at start or end of the section, and writes back the file.
    async function handleInsertAtHeading(args: {
      path: string;
      heading: string;
      content: string;
      position?: "start" | "end";
    }): Promise<string> {
      const fullPath = resolvePath(args.path);
      const position = args.position ?? "end";
    
      if (!(await fileExists(fullPath))) {
        throw new Error(`Note not found at ${args.path}`);
      }
    
      const fileContent = await fs.readFile(fullPath, "utf-8");
      const lines = fileContent.split("\n");
    
      // Find the heading
      const headingPattern = new RegExp(`^#+\\s+${args.heading}\\s*$`);
      let headingIndex = -1;
    
      for (let i = 0; i < lines.length; i++) {
        if (headingPattern.test(lines[i])) {
          headingIndex = i;
          break;
        }
      }
    
      if (headingIndex === -1) {
        throw new Error(`Heading "${args.heading}" not found in ${args.path}`);
      }
    
      // Find the end of this section (next heading of same or higher level)
      const headingLevel = (lines[headingIndex].match(/^#+/) || [""])[0].length;
      let sectionEnd = lines.length;
    
      for (let i = headingIndex + 1; i < lines.length; i++) {
        const lineHeadingMatch = lines[i].match(/^#+/);
        if (lineHeadingMatch && lineHeadingMatch[0].length <= headingLevel) {
          sectionEnd = i;
          break;
        }
      }
    
      // Insert content
      if (position === "start") {
        lines.splice(headingIndex + 1, 0, "", args.content);
      } else {
        lines.splice(sectionEnd, 0, args.content, "");
      }
    
      await fs.writeFile(fullPath, lines.join("\n"), "utf-8");
      return `Successfully inserted content under heading "${args.heading}" in ${args.path}`;
    }
  • The input schema definition for the insert_at_heading tool, specifying parameters like path, heading, content, and optional position.
    {
      name: "insert_at_heading",
      description: "Insert content under a specific heading in a note",
      inputSchema: {
        type: "object",
        properties: {
          path: {
            type: "string",
            description: "Path to the note",
          },
          heading: {
            type: "string",
            description: "The heading text to insert content under",
          },
          content: {
            type: "string",
            description: "Content to insert",
          },
          position: {
            type: "string",
            enum: ["start", "end"],
            description:
              "Insert at start or end of the heading section. Default: end",
            default: "end",
          },
        },
        required: ["path", "heading", "content"],
      },
    },
  • src/index.ts:920-928 (registration)
    The switch case in the CallToolRequest handler that routes calls to 'insert_at_heading' to the handleInsertAtHeading function.
    case "insert_at_heading":
      result = await handleInsertAtHeading(
        args as {
          path: string;
          heading: string;
          content: string;
          position?: "start" | "end";
        }
      );

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/sureshsankaran/obsidian-tools-mcp'

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