Skip to main content
Glama
takuya0206

Obsidian MCP

by takuya0206

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
NameRequiredDescriptionDefault
pathNoOptional folder path to list notes from

Implementation Reference

  • 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}`);
        }
      };
    }
  • 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)
    );
  • 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;
    }

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

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