aps_get_folder_tree
Retrieve a recursive folder tree for any project folder, displaying subfolder hierarchy and file counts per folder to quickly understand project organization while avoiding rate limits by controlling depth.
Instructions
Build a recursive folder‑tree structure showing subfolder hierarchy and file counts per folder. Useful for understanding a project's organisation at a glance. ⚠️ Each level makes an API call, so keep max_depth low (default 3) to avoid rate limits.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | Project ID – starts with 'b.'. | |
| folder_id | Yes | Root folder URN – starts with 'urn:'. | |
| max_depth | No | Maximum recursion depth (1‑5). Default 3. |
Implementation Reference
- src/index.ts:335-360 (registration)Tool registration (schema + name) for 'aps_get_folder_tree' in the TOOLS array. Defines inputSchema with project_id, folder_id, max_depth.
// 8 ── aps_get_folder_tree { name: "aps_get_folder_tree", description: "Build a recursive folder‑tree structure showing subfolder hierarchy and file counts per folder. " + "Useful for understanding a project's organisation at a glance. " + "⚠️ Each level makes an API call, so keep max_depth low (default 3) to avoid rate limits.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – starts with 'b.'.", }, folder_id: { type: "string", description: "Root folder URN – starts with 'urn:'.", }, max_depth: { type: "number", description: "Maximum recursion depth (1‑5). Default 3.", }, }, required: ["project_id", "folder_id"], }, }, - src/index.ts:1153-1166 (handler)Handler for 'aps_get_folder_tree' in handleTool(). Validates project_id and folder_id, calls buildFolderTree(), and returns JSON.
// ── aps_get_folder_tree ────────────────────────────────────── if (name === "aps_get_folder_tree") { const projectId = args.project_id as string; const folderId = args.folder_id as string; const e1 = validateProjectId(projectId); if (e1) return fail(e1); const e2 = validateFolderId(folderId); if (e2) return fail(e2); const maxDepth = Math.min(Math.max(Number(args.max_depth) || 3, 1), 5); const t = await token(); const tree = await buildFolderTree(projectId, folderId, t, maxDepth); return json(tree); } - src/aps-dm-helpers.ts:315-382 (helper)Core recursive folder tree builder (buildFolderTree). Fetches folder contents, recurses into subfolders up to max_depth, returns FolderTreeNode structure.
export async function buildFolderTree( projectId: string, folderId: string, token: string, maxDepth: number = 3, _currentDepth: number = 0, ): Promise<FolderTreeNode> { const path = `data/v1/projects/${projectId}/folders/${encodeURIComponent(folderId)}/contents`; const raw = (await apsDmRequest("GET", path, token, { query: { "page[limit]": "200" }, })) as Record<string, unknown>; const data = Array.isArray(raw.data) ? (raw.data as Record<string, unknown>[]) : []; const childFolders: FolderTreeNode[] = []; let fileCount = 0; for (const item of data) { const attrs = item.attributes as Record<string, unknown> | undefined; if (item.type === "folders") { if (_currentDepth < maxDepth - 1) { const child = await buildFolderTree( projectId, item.id as string, token, maxDepth, _currentDepth + 1, ); child.name = (attrs?.displayName as string) ?? "(unknown)"; childFolders.push(child); } else { childFolders.push({ name: (attrs?.displayName as string) ?? "(unknown)", id: item.id as string, type: "folder", // max depth reached – children not fetched }); } } else { fileCount++; } } // Resolve folder name at the root level of the call let folderName = folderId; if (_currentDepth === 0) { try { const folderRaw = (await apsDmRequest( "GET", `data/v1/projects/${projectId}/folders/${encodeURIComponent(folderId)}`, token, )) as Record<string, unknown>; const fAttrs = (folderRaw.data as Record<string, unknown>)?.attributes as | Record<string, unknown> | undefined; folderName = (fAttrs?.displayName as string) ?? folderId; } catch { // keep folderId as name } } return { name: folderName, id: folderId, type: "folder", children: childFolders.length > 0 ? childFolders : undefined, file_count: fileCount, }; } - src/aps-dm-helpers.ts:61-67 (schema)FolderTreeNode interface used as the return type for buildFolderTree. Contains name, id, type, children, and file_count.
export interface FolderTreeNode { name: string; id: string; type: "folder"; children?: FolderTreeNode[]; file_count?: number; }