Skip to main content
Glama

list_directory

List directory contents with file metadata, respecting configured path and depth restrictions to enforce policy compliance.

Instructions

List directory entries with metadata, honoring path and depth policy.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
ctxNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The actual implementation of the list_directory tool handler. Lists directory entries with metadata (name, kind, size, modified time), enforces path policy (check_path_policy) and depth policy (max_directory_depth), and logs results via append_log_entry.
    def list_directory(path: str, ctx: Context | None = None) -> str:
        """List directory entries with metadata, honoring path and depth policy."""
        context_tokens = activate_runtime_context(ctx)
        path = str(pathlib.Path(WORKSPACE_ROOT) / path) if not os.path.isabs(path) else path
    
        try:
            refresh_policy_if_changed()
            path_check = check_path_policy(path, tool="list_directory")
            if path_check:
                result = PolicyResult(allowed=False, reason=path_check[0], decision_tier="blocked", matched_rule=path_check[1])
            else:
                result = PolicyResult(allowed=True, reason="allowed", decision_tier="allowed", matched_rule=None)
    
            if result.allowed:
                if not os.path.exists(path):
                    append_log_entry(build_log_entry("list_directory", result, path=path, error="path not found"))
                    return f"Error: path not found: {path}"
    
                if not os.path.isdir(path):
                    append_log_entry(build_log_entry("list_directory", result, path=path, error="not a directory"))
                    return f"Error: '{path}' is a file, not a directory"
    
                depth = relative_depth(path)
                max_depth = POLICY.get("allowed", {}).get("max_directory_depth", 5)
                if depth > max_depth:
                    result = PolicyResult(
                        allowed=False,
                        reason=f"Directory depth {depth} exceeds the policy limit of {max_depth} (allowed.max_directory_depth): '{path}'",
                        decision_tier="blocked",
                        matched_rule="allowed.max_directory_depth",
                    )
    
            append_log_entry(build_log_entry("list_directory", result, path=path))
            if not result.allowed:
                return f"[POLICY BLOCK] {result.reason}"
    
            lines = [f"Contents of {path}:"]
            try:
                entries = sorted(os.scandir(path), key=lambda e: (e.is_file(), e.name))
            except OSError as e:
                return f"Error reading directory: {e}"
    
            for entry in entries:
                try:
                    stat = entry.stat(follow_symlinks=False)
                    mtime = datetime.datetime.fromtimestamp(stat.st_mtime, datetime.UTC).isoformat().replace("+00:00", "Z")
                    kind = "file" if entry.is_file(follow_symlinks=False) else "directory"
                    size = f"{stat.st_size} bytes" if kind == "file" else "-"
                    lines.append(f"  {entry.name}  [{kind}]  size={size}  modified={mtime}")
                except OSError:
                    lines.append(f"  {entry.name}  [unreadable]")
    
            if len(lines) == 1:
                lines.append("  (empty)")
    
            return "\n".join(lines)
        finally:
            reset_runtime_context(context_tokens)
  • src/server.py:21-31 (registration)
    Registers list_directory as an MCP tool on the FastMCP server via mcp.tool()(list_directory) at line 29.
    for tool in [
        server_info,
        restore_backup,
        execute_command,
        read_file,
        write_file,
        edit_file,
        delete_file,
        list_directory,
    ]:
        mcp.tool()(tool)
  • Re-exports list_directory from tools.file_tools and includes it in __all__.
    from .file_tools import delete_file, edit_file, list_directory, read_file, write_file
    from .restore_tools import restore_backup
    
    __all__ = [
        "server_info",
        "execute_command",
        "read_file",
        "write_file",
        "edit_file",
        "delete_file",
        "list_directory",
        "restore_backup",
    ]
  • Lists 'list_directory' as one of the configured MCP tools in AIRG_MCP_TOOLS for config management.
    AIRG_MCP_TOOLS = [
        "server_info",
        "restore_backup",
        "execute_command",
        "read_file",
        "write_file",
        "edit_file",
        "delete_file",
        "list_directory",
    ]
  • Test that exercises list_directory to verify it returns directory contents (e.g., 'demo.txt').
    def test_file_tools_read_write_list_delete_flow(self):
        (self.workspace / "nested").mkdir(parents=True, exist_ok=True)
        write_result = write_file("nested/demo.txt", "hello world")
        self.assertIn("Successfully wrote", write_result)
    
        read_result = read_file("nested/demo.txt")
        self.assertEqual(read_result, "hello world")
    
        listing = list_directory("nested")
        self.assertIn("demo.txt", listing)
    
        delete_result = delete_file("nested/demo.txt")
        self.assertIn("Successfully deleted", delete_result)
    
    def test_edit_file_flow(self):
        self._write("nested/edit.txt", "alpha beta gamma")
Behavior3/5

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

The description mentions 'honoring path and depth policy,' hinting at behavioral constraints, but does not elaborate on what happens with invalid paths, policy violations, or the readonly nature. Since no annotations are provided, the description carries the full burden but only offers partial insight.

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 sentence of 10 words, front-loaded with the core purpose. No wasted words, though it could benefit from expansion.

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

Completeness2/5

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

Despite having an output schema, the description does not clarify return values, error behavior, or the depth policy. For a tool with 2 parameters and no annotations, it lacks sufficient detail for an agent to use correctly.

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

Parameters1/5

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

With 0% schema description coverage, the description must explain parameters but fails to do so. The 'path' parameter is implicit, but 'ctx' is entirely unexplained. No additional meaning is added beyond the raw schema.

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

Purpose5/5

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

The description clearly states the action ('List directory entries') and the resource ('directory entries with metadata'). The verb 'list' distinguishes it from sibling tools like read_file or write_file, which operate on file content rather than directory structure.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives, nor does it indicate when not to use it. Siblings include other file operations, but the description does not mention contexts where list_directory is appropriate or inappropriate.

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/runtimeguard/ai-runtime-guard'

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