Skip to main content
Glama

tree

Generate a visual directory tree with configurable depth and file details to explore and analyze folder structures efficiently.

Instructions

Render a directory tree (bounded recursion). Returns ASCII tree + structured JSON. maxDepth=0 returns only the root node.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathNoBase directory (default: root). Absolute path required if multiple roots.
maxDepthNoDepth (0=root node only, no children). Default: 5
maxEntriesNoMax entries. Default: 1000
includeHiddenNoInclude hidden items (starting with .)
includeIgnoredNoInclude ignored items. Disables .gitignore.
includeSizesNoInclude file sizes in tree entries

Implementation Reference

  • The primary logic handler for the 'tree' tool, calling `treeDirectory` to generate the file structure and formatting the output.
    async function handleTree(
      args: z.infer<typeof TreeInputSchema>,
      signal?: AbortSignal,
      onProgress?: (progress: { current: number }) => void
    ): Promise<ToolResponse<z.infer<typeof TreeOutputSchema>>> {
      const basePath = resolvePathOrRoot(args.path);
      const result = await treeDirectory(basePath, {
        maxDepth: args.maxDepth,
        maxEntries: args.maxEntries,
        includeHidden: args.includeHidden,
        includeIgnored: args.includeIgnored,
        includeSizes: args.includeSizes,
        ...(signal ? { signal } : {}),
        ...(onProgress ? { onProgress } : {}),
      });
    
      const ascii = formatTreeAscii(result.tree);
    
      const structured: z.infer<typeof TreeOutputSchema> = {
        ok: true,
        root: result.root,
        tree: result.tree,
        ascii,
        truncated: result.truncated,
        totalEntries: result.totalEntries,
      };
    
      const text = result.truncated ? `${ascii}\n[truncated]` : ascii;
      return buildToolResponse(text, structured);
    }
  • The registration function that sets up the 'tree' tool on the MCP server, including argument validation and tool wrapping.
    export function registerTreeTool(
      server: McpServer,
      options: ToolRegistrationOptions = {}
    ): void {
      const handler = (
        args: z.infer<typeof TreeInputSchema>,
        extra: ToolExtra
      ): Promise<ToolResult<z.infer<typeof TreeOutputSchema>>> => {
        const targetPath = args.path ?? '.';
        return executeToolWithDiagnostics({
          toolName: 'tree',
          extra,
          outputSchema: TreeOutputSchema,
          timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
          context: { path: targetPath },
          run: async (signal) => {
            const context = args.path ? path.basename(args.path) : '.';
            let progressCursor = 0;
            const knownTotal = args.maxEntries;
    
            notifyProgress(extra, {
              current: 0,
              total: knownTotal,
              message: `≣ tree: ${context}`,
            });
    
            const baseReporter = createProgressReporter(extra);
            const onProgress = (progress: { current: number }): void => {
              const { current } = progress;
              if (current > progressCursor) progressCursor = current;
              baseReporter({
                current,
                total: knownTotal,
                message: `≣ tree: ${context} [${current} entries]`,
              });
            };
    
            try {
              const result = await handleTree(args, signal, onProgress);
              const sc = result.structuredContent;
              const count = sc.totalEntries ?? 0;
              const { truncated } = sc;
    
              let suffix = `${count} ${count === 1 ? 'entry' : 'entries'}`;
              if (truncated) suffix += ' [truncated]';
    
              const finalCurrent = Math.max(count, progressCursor + 1);
              notifyProgress(extra, {
                current: finalCurrent,
                total: finalCurrent,
                message: `≣ tree: ${context} • ${suffix}`,
              });
              return result;
            } catch (error) {
              const finalCurrent = Math.max(progressCursor + 1, 1);
              notifyProgress(extra, {
                current: finalCurrent,
                total: finalCurrent,
                message: `≣ tree: ${context} • failed`,
              });
              throw error;
            }
          },
          onError: (error) =>
            buildToolErrorResponse(error, ErrorCode.E_NOT_DIRECTORY, targetPath),
        });
      };
    
      const wrappedHandler = wrapToolHandler(handler, {
        guard: options.isInitialized,
      });
    
      const validatedHandler = withValidatedArgs(TreeInputSchema, wrappedHandler);
    
      if (
        registerToolTaskIfAvailable(
          server,
          'tree',
          TREE_TOOL,
          validatedHandler,
          options.iconInfo,
          options.isInitialized
        )
      )
        return;
      server.registerTool(
        'tree',
        withDefaultIcons({ ...TREE_TOOL }, options.iconInfo),
        validatedHandler
      );
    }

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/j0hanz/filesystem-mcp'

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