obsidian_periodic_note
Manage periodic notes in Obsidian: read, create, upsert, append, or delete daily, weekly, monthly, quarterly, and yearly notes with custom content and frontmatter.
Instructions
Read/create/upsert/append daily, weekly, monthly, quarterly, or yearly notes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Optional configured vault name. Defaults to the server default vault. | |
| period | No | daily | |
| date | No | ||
| folder | No | ||
| action | No | read | |
| content | No | ||
| frontmatter | No | YAML frontmatter object. | |
| confirmation | No |
Implementation Reference
- src/tools.ts:983-1005 (registration)Registration of 'obsidian_periodic_note' tool with schema definition via the internal 'tool' helper. The tool is registered at line 983 and the handler spans lines 996-1004.
tool( "obsidian_periodic_note", "Read/create/upsert/append daily, weekly, monthly, quarterly, or yearly notes.", { vault: vaultArg, period: z.enum(["daily", "weekly", "monthly", "quarterly", "yearly"]).optional().default("daily"), date: z.string().optional(), folder: z.string().optional(), action: z.enum(["read", "create", "upsert", "append", "delete"]).optional().default("read"), content: z.string().optional().default(""), frontmatter: frontmatterArg, confirmation: z.string().optional(), }, async (args) => { const date = args.date ?? new Date().toISOString().slice(0, 10); const notePath = periodicPath(args.period, date, args.folder); if (args.action === "read") return { path: notePath, content: (await vaults.readText(notePath, args.vault)).text }; if (args.action === "append") return vaults.appendText(notePath, args.content, args.vault, { create: true }); if (args.action === "delete") return vaults.trash(notePath, args.vault, { confirmation: args.confirmation }); const text = args.frontmatter ? stringifyFrontmatter(args.frontmatter, args.content) : args.content; return vaults.writeText(notePath, text, args.vault, { overwrite: args.action === "upsert" }); }, ); - src/tools.ts:996-1004 (handler)Handler function for obsidian_periodic_note that reads/creates/upserts/appends/deletes periodic notes (daily, weekly, monthly, quarterly, yearly). Uses periodicPath() to compute the file path and delegates to vaults.readText, vaults.appendText, vaults.writeText, or vaults.trash.
async (args) => { const date = args.date ?? new Date().toISOString().slice(0, 10); const notePath = periodicPath(args.period, date, args.folder); if (args.action === "read") return { path: notePath, content: (await vaults.readText(notePath, args.vault)).text }; if (args.action === "append") return vaults.appendText(notePath, args.content, args.vault, { create: true }); if (args.action === "delete") return vaults.trash(notePath, args.vault, { confirmation: args.confirmation }); const text = args.frontmatter ? stringifyFrontmatter(args.frontmatter, args.content) : args.content; return vaults.writeText(notePath, text, args.vault, { overwrite: args.action === "upsert" }); }, - src/tools.ts:986-995 (schema)Zod schema for obsidian_periodic_note: vault (optional), period (enum daily/weekly/monthly/quarterly/yearly), date, folder, action (read/create/upsert/append/delete), content, frontmatter, and confirmation.
{ vault: vaultArg, period: z.enum(["daily", "weekly", "monthly", "quarterly", "yearly"]).optional().default("daily"), date: z.string().optional(), folder: z.string().optional(), action: z.enum(["read", "create", "upsert", "append", "delete"]).optional().default("read"), content: z.string().optional().default(""), frontmatter: frontmatterArg, confirmation: z.string().optional(), }, - src/tools.ts:1424-1435 (helper)The periodicPath helper function that computes the file path for a periodic note based on period, date, and folder. Handles daily, weekly (with ISO week), monthly, quarterly, and yearly patterns.
function periodicPath(period: "daily" | "weekly" | "monthly" | "quarterly" | "yearly", date: string, folder?: string): string { const [year, month, day] = date.split("-").map((part) => Number(part)); const d = new Date(Date.UTC(year, (month || 1) - 1, day || 1)); if (period === "daily") return `${folder ?? "00-Inbox"}/${date}.md`; if (period === "monthly") return `${folder ?? "00-Inbox"}/${date.slice(0, 7)}.md`; if (period === "yearly") return `${folder ?? "00-Inbox"}/${String(year).padStart(4, "0")}.md`; if (period === "quarterly") { const quarter = Math.floor(((month || 1) - 1) / 3) + 1; return `${folder ?? "00-Inbox"}/${String(year).padStart(4, "0")}-Q${quarter}.md`; } return `${folder ?? "00-Inbox"}/${String(year).padStart(4, "0")}-W${isoWeek(d)}.md`; } - src/tools.ts:1437-1444 (helper)The isoWeek helper function used by periodicPath to compute the ISO week number for weekly periodic notes.
function isoWeek(date: Date): string { const d = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())); const day = d.getUTCDay() || 7; d.setUTCDate(d.getUTCDate() + 4 - day); const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); const week = Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7); return String(week).padStart(2, "0"); }