Skip to content

List dir

list_dir

ListDirTool — directory listing with file metadata.

Registered as list_dir via the axm.tools entry point.

ListDirTool

Directory listing with file metadata for AI agents.

Lists files and directories within a sandboxed root directory. Supports recursive listing via max_depth. Hidden entries and build artefacts (__pycache__, node_modules, etc.) are skipped automatically. Registered as list_dir via axm.tools entry point.

Source code in packages/axm-edit/src/axm_edit/tools/list_dir.py
Python
class ListDirTool:
    """Directory listing with file metadata for AI agents.

    Lists files and directories within a sandboxed root directory.
    Supports recursive listing via *max_depth*. Hidden entries and
    build artefacts (``__pycache__``, ``node_modules``, etc.) are
    skipped automatically.
    Registered as ``list_dir`` via axm.tools entry point.
    """

    agent_hint: str = (
        "List directory tree with file sizes."
        " Use max_depth to limit. Replaces ls/find for project exploration."
    )

    @property
    def name(self) -> str:
        """Tool name used for MCP registration."""
        return "list_dir"

    def execute(
        self,
        *,
        path: str = ".",
        max_depth: int = 1,
        **kwargs: object,
    ) -> ToolResult:
        """List files and directories in a project directory.

        Args:
            path: Root directory to list (default ".").
            max_depth: Recursion depth — 1 for immediate children
                only, >1 for nested listing (default 1).

        Returns:
            ToolResult with entries list (name, path, type,
            size_bytes), count, and truncated flag.
        """
        root_str = path
        depth = max(max_depth, 1)

        root = Path(root_str).resolve()
        if not root.is_dir():
            return ToolResult(
                success=False,
                error=f"Path is not a directory: {root_str}",
            )

        entries: list[dict[str, object]] = []
        truncated = _collect_entries(root, root, depth, 1, entries)

        count = len(entries)
        return ToolResult(
            success=True,
            data={
                "entries": entries,
                "count": count,
                "truncated": truncated,
            },
            text=render_text(
                entries=entries,
                count=count,
                truncated=truncated,
            ),
        )
name property

Tool name used for MCP registration.

execute(*, path='.', max_depth=1, **kwargs)

List files and directories in a project directory.

Parameters:

Name Type Description Default
path str

Root directory to list (default ".").

'.'
max_depth int

Recursion depth — 1 for immediate children only, >1 for nested listing (default 1).

1

Returns:

Type Description
ToolResult

ToolResult with entries list (name, path, type,

ToolResult

size_bytes), count, and truncated flag.

Source code in packages/axm-edit/src/axm_edit/tools/list_dir.py
Python
def execute(
    self,
    *,
    path: str = ".",
    max_depth: int = 1,
    **kwargs: object,
) -> ToolResult:
    """List files and directories in a project directory.

    Args:
        path: Root directory to list (default ".").
        max_depth: Recursion depth — 1 for immediate children
            only, >1 for nested listing (default 1).

    Returns:
        ToolResult with entries list (name, path, type,
        size_bytes), count, and truncated flag.
    """
    root_str = path
    depth = max(max_depth, 1)

    root = Path(root_str).resolve()
    if not root.is_dir():
        return ToolResult(
            success=False,
            error=f"Path is not a directory: {root_str}",
        )

    entries: list[dict[str, object]] = []
    truncated = _collect_entries(root, root, depth, 1, entries)

    count = len(entries)
    return ToolResult(
        success=True,
        data={
            "entries": entries,
            "count": count,
            "truncated": truncated,
        },
        text=render_text(
            entries=entries,
            count=count,
            truncated=truncated,
        ),
    )

render_text(*, entries, count, truncated)

Render a compact, ls-style LLM-facing view of the listing.

One entry per line, using the relative path (which subsumes name and encodes the directory hierarchy when max_depth > 1). Directories get a trailing /; files carry a compact human-readable size. The header carries the total entry count, the dir/file split, and an explicit TRUNCATED flag when the entry cap was reached. Every entry (path, type, size) and the truncation signal are preserved verbatim, so no information is lost relative to data.

Source code in packages/axm-edit/src/axm_edit/tools/list_dir.py
Python
def render_text(
    *,
    entries: list[dict[str, object]],
    count: int,
    truncated: bool,
) -> str:
    """Render a compact, ``ls``-style LLM-facing view of the listing.

    One entry per line, using the relative ``path`` (which subsumes ``name``
    and encodes the directory hierarchy when ``max_depth`` > 1). Directories
    get a trailing ``/``; files carry a compact human-readable size. The
    header carries the total entry count, the dir/file split, and an explicit
    ``TRUNCATED`` flag when the entry cap was reached. Every entry (path,
    type, size) and the truncation signal are preserved verbatim, so no
    information is lost relative to ``data``.
    """
    if not entries:
        return "list_dir | 0 entries"

    n_dirs = sum(1 for e in entries if e["type"] == "dir")
    n_files = count - n_dirs
    plural_d = "s" if n_dirs != 1 else ""
    plural_f = "s" if n_files != 1 else ""
    header = (
        f"list_dir | {count} entries"
        f" · {n_dirs} dir{plural_d} · {n_files} file{plural_f}"
    )
    if truncated:
        header += f" · TRUNCATED at {count}"

    lines = [header]
    lines.extend(_render_entry(entry) for entry in entries)
    return "\n".join(lines)