Skip to content

Commit 50ebf73

Browse files
authored
Merge pull request #19 from GitHubSecurityLab/limit_list_file
allow list files to exit gracefully when there are too many files and add a non recursive version to limit return files
2 parents 1a2eda2 + 716b7e0 commit 50ebf73

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/seclab_taskflows/mcp_servers/local_file_viewer.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
LINE_LIMIT_FOR_FETCHING_FILE_CONTENT = int(os.getenv('LINE_LIMIT_FOR_FETCHING_FILE_CONTENT', default=1000))
2828

29+
FILE_LIMIT_FOR_LIST_FILES = int(os.getenv('FILE_LIMIT_FOR_LIST_FILES', default=100))
30+
2931
def is_subdirectory(directory, potential_subdirectory):
3032
directory_path = Path(directory)
3133
potential_subdirectory_path = Path(potential_subdirectory)
@@ -69,16 +71,22 @@ def search_zipfile(database_path, term, search_dir = None):
6971
results[filename].append(i+1)
7072
return results
7173

72-
def _list_files(database_path, root_dir = None):
74+
def _list_files(database_path, root_dir = None, recursive=True):
7375
results = []
7476
root_dir = strip_leading_dash(root_dir)
7577
with zipfile.ZipFile(database_path) as z:
7678
for entry in z.infolist():
7779
if entry.is_dir():
80+
if not recursive:
81+
dirname = remove_root_dir(entry.filename)
82+
if Path(dirname).parent == Path(root_dir):
83+
results.append(dirname + '/')
7884
continue
7985
filename = remove_root_dir(entry.filename)
8086
if root_dir and not is_subdirectory(root_dir, filename):
8187
continue
88+
if not recursive and Path(filename).parent != Path(root_dir):
89+
continue
8290
results.append(filename)
8391
return results
8492

@@ -152,8 +160,27 @@ async def list_files(
152160
if not source_path or not source_path.exists():
153161
return f"Invalid {owner} and {repo}. Check that the input is correct or try to fetch the repo from gh first."
154162
content = _list_files(source_path, path)
163+
if len(content) > FILE_LIMIT_FOR_LIST_FILES:
164+
return f"Too many files to display in {owner}/{repo} at path {path} ({len(content)} files). Try using `list_files_non_recursive` instead."
155165
return json.dumps(content, indent=2)
156166

167+
@mcp.tool()
168+
async def list_files_non_recursive(
169+
owner: str = Field(description="The owner of the repository"),
170+
repo: str = Field(description="The name of the repository"),
171+
path: str = Field(description="The path to the directory in the repository")) -> str:
172+
"""
173+
List the files of a directory from a local GitHub repository non-recursively.
174+
Subdirectories will be listed and indicated with a trailing slash.
175+
"""
176+
source_path = Path(f"{LOCAL_GH_DIR}/{owner}/{repo}.zip")
177+
source_path = sanitize_file_path(source_path, [LOCAL_GH_DIR])
178+
if not source_path or not source_path.exists():
179+
return f"Invalid {owner} and {repo}. Check that the input is correct or try to fetch the repo from gh first."
180+
content = _list_files(source_path, path, recursive=False)
181+
return json.dumps(content, indent=2)
182+
183+
157184
@mcp.tool()
158185
async def search_repo(
159186
owner: str = Field(description="The owner of the repository"),

src/seclab_taskflows/toolboxes/local_file_viewer.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ server_params:
1212
env:
1313
LOCAL_GH_DIR: "{{ env DATA_DIR }}"
1414
LINE_LIMIT_FOR_FETCHING_FILE_CONTENT: "{{ env LINE_LIMIT_FOR_FETCHING_FILE_CONTENT }}"
15+
FILE_LIMIT_FOR_LIST_FILES: "{{ env FILE_LIMIT_FOR_LIST_FILES }}"

0 commit comments

Comments
 (0)