listNotes
Recursively list files and folders in your Obsidian vault or a specific folder, returning results in a tree format for easy navigation.
Instructions
Recursively lists files and folders in the entire Vault or under a specified folder and returns the result as a tree-format string
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Optional folder path to list notes from |
Implementation Reference
- src/tools/list-notes.ts:25-34 (handler)The tool handler factory that creates the executor for the listNotes tool. It takes optional path parameter, calls api.listAllItemsAsTree, and formats success/error response.export function createListNotesTool(api: ObsidianAPI): ToolHandler { return async (params: { path?: string }): Promise<ToolResponse> => { try { const result = await api.listAllItemsAsTree(params.path); return formatSuccessResponse(result); } catch (error) { return formatErrorResponse(`Error listing notes: ${(error as Error).message}`); } }; }
- src/tools/list-notes.ts:7-9 (schema)Input schema definition for the listNotes tool using Zod, defining optional 'path' parameter.export const ListNotesSchema = { path: z.string().optional().describe("Optional folder path to list notes from") };
- src/server.ts:63-68 (registration)Registration of the listNotes tool with the MCP server, providing name, description, schema, and handler.this.server.tool( listNotesDefinition.name, listNotesDefinition.description, listNotesDefinition.schema, createListNotesTool(this.api) );
- src/api/obsidian-api.ts:101-149 (helper)Core helper method in ObsidianAPI that recursively fetches and formats the vault/folder structure as a tree string, invoked by the listNotes handler.async listAllItemsAsTree(folderName = ""): Promise<string> { // ルートフォルダ(vault直下)を指定するときは空文字列を渡す // インデント用文字列は初回呼び出し時は空にしておく return await this.listAllItemsRecursive(folderName, ""); } // 再帰的にアイテムを走査し、階層構造を文字列で返す内部メソッド private async listAllItemsRecursive( folderName: string, indent: string ): Promise<string> { let cleanedFolder = folderName.replace(/\/$/, ""); // folderName が空であれば "/vault/"、そうでなければ "/vault/[folderName]/" const urlPath = cleanedFolder ? `/vault/${encodeURIComponent(cleanedFolder)}/` : `/vault/`; // フォルダ配下の要素を取得 const response = await this.client.get(urlPath); const items: string[] = response.data.files ?? []; let treeStr = ""; const totalCount = items.length; for (let i = 0; i < totalCount; i++) { const item = items[i]; const isLast = i === totalCount - 1; // "├──" または "└──" const branch = isLast ? "└── " : "├── "; // サブ階層で使うインデント; "│ " または " " const newIndent = indent + (isLast ? " " : "│ "); if (item.endsWith("/")) { // フォルダの場合 treeStr += `${indent}${branch}${item}\n`; // 末尾スラッシュを除去しつつ再帰的に取得 const childFolder = item.replace(/\/$/, ""); const nextFolderName = cleanedFolder ? `${cleanedFolder}/${childFolder}` : childFolder; treeStr += await this.listAllItemsRecursive(nextFolderName, newIndent); } else { // ファイルの場合 treeStr += `${indent}${branch}${item}\n`; } } return treeStr; }