Skip to main content
Glama

insert_at_heading

Insert content under a specific heading in an Obsidian note. Add text at the start or end of a heading section to organize notes effectively.

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 implements the tool logic: reads the note file, locates the specified heading, finds the end of the heading's section, inserts the provided content at the start or end of the section, and saves the updated 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 tool's metadata and input schema definition in the tools array, used for tool listing and validation.
    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-929 (registration)
    The switch case in the main tool call handler that routes calls to 'insert_at_heading' to the specific handler function.
    case "insert_at_heading": result = await handleInsertAtHeading( args as { path: string; heading: string; content: string; position?: "start" | "end"; } ); break;

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