list_directory
Display files and directories within a workspace. Specify a path to view contents, enable recursive listing to see nested items, and control depth and entry limits for organized browsing.
Instructions
List files and directories. Paths are relative to the configured root (/app/workspace). Set recursive=true to list all nested files.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Directory path relative to the configured root | . |
| recursive | No | Whether to list files recursively | |
| max_depth | No | Maximum directory depth for recursive listing (default: 3, max: 10) | |
| max_entries | No | Maximum total entries to return (default: 10000) |
Implementation Reference
- src/tools/file-reader.ts:125-192 (handler)The core handler function for 'list_directory' which reads a directory and formats the output into a list of file entries.
export async function listDirectory( input: ListDirectoryInput ): Promise<ToolResult<ListDirectoryResult>> { const userPath = input.path ?? "."; const result = safePath(userPath); if ("error" in result) { return { ok: false, error: result.error, code: "PATH_TRAVERSAL" }; } const { resolved } = result; // M2: Apply depth/entry caps with defaults from schema const maxDepth = input.max_depth ?? 3; const maxEntries = input.max_entries ?? 10000; logger.debug("Listing directory", { path: resolved, recursive: input.recursive, maxDepth, maxEntries, }); const counter = { count: 0, truncated: false }; let entries: FileEntry[]; try { entries = await collectEntries( resolved, userPath, input.recursive ?? false, 0, maxDepth, maxEntries, counter ); } catch (err) { const code = (err as NodeJS.ErrnoException).code; if (code === "ENOENT") { return { ok: false, error: `Directory not found: ${userPath}`, code: "NOT_FOUND", }; } if (code === "ENOTDIR") { return { ok: false, error: `Path is not a directory: ${userPath}`, code: "NOT_A_DIRECTORY", }; } return { ok: false, error: `Failed to list directory: ${(err as Error).message}`, code: "LIST_ERROR", }; } return { ok: true, data: { path: userPath, entries, total: entries.length, ...(counter.truncated ? { truncated: true } : {}), } as ListDirectoryResult, }; } - src/types.ts:90-116 (schema)The Zod schema definition for 'list_directory' input parameters and result structures.
export const ListDirectorySchema = z.object({ path: z .string() .optional() .default(".") .describe("Directory path relative to the configured root"), recursive: z .boolean() .optional() .default(false) .describe("Whether to list files recursively"), max_depth: z .number() .int() .min(1) .max(10) .optional() .default(3) .describe("Maximum directory depth for recursive listing (default: 3, max: 10)"), max_entries: z .number() .int() .min(1) .optional() .default(10000) .describe("Maximum total entries to return (default: 10000)"), }); - src/index.ts:94-100 (registration)Registration of the 'list_directory' tool with the MCP server using the handler and schema.
server.tool( "list_directory", `List files and directories. Paths are relative to the configured root (${config.fileReaderRoot}). ` + "Set recursive=true to list all nested files.", ListDirectorySchema.shape, async (args) => { const result = await listDirectory(args);