obsidian_recent_notes
Retrieve a list of recently modified notes, sorted newest first. Filter by folder, file extension, and limit results.
Instructions
List recently modified notes or files, sorted newest first.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Optional configured vault name. Defaults to the server default vault. | |
| folder | No | . | |
| extension | No | .md | |
| limit | No | ||
| offset | No |
Implementation Reference
- src/tools.ts:243-259 (registration)Tool registration for 'obsidian_recent_notes' with its Zod schema and handler
tool( "obsidian_recent_notes", "List recently modified notes or files, sorted newest first.", { vault: vaultArg, folder: z.string().optional().default("."), extension: z.string().optional().default(".md"), limit: z.number().int().min(1).max(1000).optional().default(50), offset: z.number().int().min(0).optional().default(0), }, async (args) => { const entries = await vaults.listEntries(args.vault, { folder: args.folder, recursive: true, extension: args.extension, includeDirectories: false }); const sorted = entries.sort((a, b) => b.mtime.localeCompare(a.mtime)); return { total: sorted.length, offset: args.offset, notes: sorted.slice(args.offset, args.offset + args.limit) }; }, { readOnlyHint: true }, ); - src/tools.ts:253-257 (handler)Handler function: lists vault entries, sorts by mtime descending, paginates with limit/offset
async (args) => { const entries = await vaults.listEntries(args.vault, { folder: args.folder, recursive: true, extension: args.extension, includeDirectories: false }); const sorted = entries.sort((a, b) => b.mtime.localeCompare(a.mtime)); return { total: sorted.length, offset: args.offset, notes: sorted.slice(args.offset, args.offset + args.limit) }; }, - src/tools.ts:246-252 (schema)Input schema: vault (optional), folder (default '.'), extension (default '.md'), limit (default 50), offset (default 0)
{ vault: vaultArg, folder: z.string().optional().default("."), extension: z.string().optional().default(".md"), limit: z.number().int().min(1).max(1000).optional().default(50), offset: z.number().int().min(0).optional().default(0), }, - src/vault.ts:209-248 (helper)VaultManager.listEntries: uses fast-glob to list files/folders with filtering by extension, depth, and directory inclusion; returns VaultFileEntry[] sorted by path
async listEntries( vaultName?: string | null, options: { folder?: string; recursive?: boolean; maxDepth?: number; extension?: string; includeDirectories?: boolean } = {}, ): Promise<VaultFileEntry[]> { const vault = this.getVault(vaultName); const folder = normalizeRelativePath(options.folder || "."); const base = this.resolvePath(folder, vault.name); const depth = options.recursive ? options.maxDepth ?? 20 : 1; const pattern = options.recursive ? "**/*" : "*"; const entries = await fg(pattern, { cwd: base.absolute, dot: false, onlyFiles: false, markDirectories: false, ignore: DEFAULT_IGNORES, deep: depth, stats: true, followSymbolicLinks: false, }); const out: VaultFileEntry[] = []; for (const item of entries) { if (typeof item === "string") continue; const rel = toPosix(path.join(base.relative === "." ? "" : base.relative, item.path)); const stats = item.stats; if (!stats) continue; const isDir = stats.isDirectory(); if (isDir && options.includeDirectories === false) continue; const ext = path.posix.extname(rel); if (options.extension && ext.toLowerCase() !== normalizeExtension(options.extension)) continue; out.push({ path: rel, name: path.posix.basename(rel), type: isDir ? "directory" : "file", size: stats.size, mtime: stats.mtime.toISOString(), extension: ext, }); } return out.sort((a, b) => a.path.localeCompare(b.path)); } - src/vault.ts:29-36 (helper)VaultFileEntry type definition: path, name, type, size, mtime (ISO string), extension
export type VaultFileEntry = { path: string; name: string; type: "file" | "directory"; size: number; mtime: string; extension: string; };