testmo_get_folders_recursive
Retrieve a folder and all descendant subfolders as a nested tree with a single API call, eliminating the need for multiple requests.
Instructions
Get a folder and all descendant subfolders as a nested tree in a single call.
Args: project_id: The project ID. folder_id: The root folder ID to start recursion from.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | ||
| folder_id | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- testmo/tools/composite.py:157-174 (handler)The main handler function for the testmo_get_folders_recursive tool. It fetches all folders via _get_all_folders helper, builds a folder map, collects the subtree IDs for the given root folder, builds a nested tree structure, and returns the total folder count and tree.
@mcp.tool() async def testmo_get_folders_recursive( project_id: int, folder_id: int, ) -> dict[str, Any]: """Get a folder and all descendant subfolders as a nested tree in a single call. Args: project_id: The project ID. folder_id: The root folder ID to start recursion from. """ all_folders = await _get_all_folders(project_id) folder_map = _build_folder_map(all_folders) if folder_id not in folder_map: return {"error": f"Folder {folder_id} not found in project {project_id}"} subtree_ids = _collect_subtree(all_folders, folder_id) tree = _build_folder_tree(all_folders, subtree_ids, folder_id, folder_map) return {"total_folders": len(subtree_ids), "tree": tree} - testmo/tools/composite.py:157-158 (registration)The tool is registered via the @mcp.tool() decorator on line 157, which registers it with the FastMCP server instance from testmo/server.py.
@mcp.tool() async def testmo_get_folders_recursive( - testmo/tools/composite.py:11-23 (helper)Helper function _collect_subtree: given all folders and a root_id, returns a set of all folder IDs in the subtree (inclusive) by traversing parent-child relationships.
def _collect_subtree(all_folders: list[dict[str, Any]], root_id: int) -> set[int]: """Return set of folder IDs in the subtree rooted at root_id (inclusive).""" children_map: dict[int, list[int]] = defaultdict(list) for f in all_folders: children_map[f.get("parent_id") or 0].append(f["id"]) result = {root_id} stack = [root_id] while stack: current = stack.pop() for child_id in children_map.get(current, []): result.add(child_id) stack.append(child_id) return result - testmo/tools/composite.py:26-27 (helper)Helper function _build_folder_map: builds a dict mapping folder_id to folder object for quick lookups.
def _build_folder_map(all_folders: list[dict[str, Any]]) -> dict[int, dict[str, Any]]: return {f["id"]: f for f in all_folders} - testmo/tools/composite.py:43-65 (helper)Helper function _build_folder_tree: given all folders, a set of subtree IDs, a root_id, and a folder map, builds a nested dict tree with full_path and children.
def _build_folder_tree( all_folders: list[dict[str, Any]], subtree_ids: set[int], root_id: int, folder_map: dict[int, dict[str, Any]], ) -> dict[str, Any] | None: children_map: dict[int, list[dict[str, Any]]] = defaultdict(list) for f in all_folders: if f["id"] not in subtree_ids: continue children_map[f.get("parent_id") or 0].append(f) def build_node(folder: dict[str, Any]) -> dict[str, Any]: node = {**folder} node["full_path"] = _get_folder_path(folder["id"], folder_map) node["children"] = [ build_node(child) for child in children_map.get(folder["id"], []) ] return node if root_id not in folder_map: return None return build_node(folder_map[root_id])