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;
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses key behavioral traits: recursive listing, scope (entire Vault or specific folder), and output format (tree-format string). However, it lacks details on permissions, rate limits, pagination, or error handling. For a read-only listing tool, this is adequate but not comprehensive, as it misses operational constraints that could affect agent decisions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that efficiently conveys the tool's action, scope, and output. It is front-loaded with the core functionality and avoids unnecessary details. Every part of the sentence adds value, making it highly concise and easy to parse for an AI agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (recursive listing with one optional parameter), no annotations, and no output schema, the description is partially complete. It covers the basic operation and output format but omits details like return structure examples, error cases, or performance implications. For a tool without structured output documentation, more context on what the 'tree-format string' entails would improve completeness, but it meets minimum viability.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with the 'path' parameter documented as 'Optional folder path to list notes from.' The description adds marginal value by clarifying that listing can be 'under a specified folder,' reinforcing the parameter's purpose. Since schema coverage is high, the baseline is 3, and the description does not significantly enhance parameter understanding beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Recursively lists files and folders' with the resource being 'the entire Vault or under a specified folder.' It uses specific verbs ('lists,' 'returns') and identifies the output format ('tree-format string'). However, it does not explicitly differentiate from sibling tools like 'searchWithJsonLogic,' which might also involve listing but with filtering, so it misses full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by mentioning it can list 'the entire Vault or under a specified folder,' suggesting when to use the optional 'path' parameter. However, it does not provide explicit guidance on when to use this tool versus alternatives like 'searchWithJsonLogic' for filtered searches or 'readNote' for individual file access. No exclusions or prerequisites are stated, leaving usage context partially inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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