Get directory file structure Args: directory: Directory path, relative to workspace max_depth: 最大遍历深度 Returns: JSON string of file structure
(directory: str = ".", max_depth: int = 5)
| 1279 | |
| 1280 | @mcp.tool() |
| 1281 | async def get_file_structure(directory: str = ".", max_depth: int = 5) -> str: |
| 1282 | """ |
| 1283 | Get directory file structure |
| 1284 | |
| 1285 | Args: |
| 1286 | directory: Directory path, relative to workspace |
| 1287 | max_depth: 最大遍历深度 |
| 1288 | |
| 1289 | Returns: |
| 1290 | JSON string of file structure |
| 1291 | """ |
| 1292 | try: |
| 1293 | ensure_workspace_exists() |
| 1294 | |
| 1295 | if directory == ".": |
| 1296 | target_dir = WORKSPACE_DIR |
| 1297 | else: |
| 1298 | target_dir = validate_path(directory) |
| 1299 | |
| 1300 | if not target_dir.exists(): |
| 1301 | result = { |
| 1302 | "status": "error", |
| 1303 | "message": f"Directory does not exist: {directory}", |
| 1304 | } |
| 1305 | return json.dumps(result, ensure_ascii=False, indent=2) |
| 1306 | |
| 1307 | def scan_directory(path: Path, current_depth: int = 0) -> Dict[str, Any]: |
| 1308 | """Recursively scan directory""" |
| 1309 | if current_depth >= max_depth: |
| 1310 | return {"type": "directory", "name": path.name, "truncated": True} |
| 1311 | |
| 1312 | items = [] |
| 1313 | try: |
| 1314 | for item in sorted(path.iterdir()): |
| 1315 | relative_path = os.path.relpath(item, WORKSPACE_DIR) |
| 1316 | |
| 1317 | if item.is_file(): |
| 1318 | file_info = { |
| 1319 | "type": "file", |
| 1320 | "name": item.name, |
| 1321 | "path": relative_path, |
| 1322 | "size_bytes": item.stat().st_size, |
| 1323 | "extension": item.suffix, |
| 1324 | } |
| 1325 | items.append(file_info) |
| 1326 | elif item.is_dir() and not item.name.startswith("."): |
| 1327 | dir_info = scan_directory(item, current_depth + 1) |
| 1328 | dir_info["path"] = relative_path |
| 1329 | items.append(dir_info) |
| 1330 | except PermissionError: |
| 1331 | pass |
| 1332 | |
| 1333 | return { |
| 1334 | "type": "directory", |
| 1335 | "name": path.name, |
| 1336 | "items": items, |
| 1337 | "item_count": len(items), |
| 1338 | } |
nothing calls this directly
no test coverage detected