search_drive_files
Search files and folders in Google Drive or shared drives using specific queries and parameters. Retrieve detailed results including ID, name, type, size, modified time, and link.
Instructions
Searches for files and folders within a user's Google Drive, including shared drives.
Args:
user_google_email (str): The user's Google email address. Required.
query (str): The search query string. Supports Google Drive search operators.
page_size (int): The maximum number of files to return. Defaults to 10.
drive_id (Optional[str]): ID of the shared drive to search. If None, behavior depends on `corpora` and `include_items_from_all_drives`.
include_items_from_all_drives (bool): Whether shared drive items should be included in results. Defaults to True. This is effective when not specifying a `drive_id`.
corpora (Optional[str]): Bodies of items to query (e.g., 'user', 'domain', 'drive', 'allDrives').
If 'drive_id' is specified and 'corpora' is None, it defaults to 'drive'.
Otherwise, Drive API default behavior applies. Prefer 'user' or 'drive' over 'allDrives' for efficiency.
Returns:
str: A formatted list of found files/folders with their details (ID, name, type, size, modified time, link).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| corpora | No | ||
| drive_id | No | ||
| include_items_from_all_drives | No | ||
| page_size | No | ||
| query | Yes | ||
| service | Yes | ||
| user_google_email | Yes |
Implementation Reference
- gdrive/drive_tools.py:35-100 (handler)Primary handler function for the 'search_drive_files' tool. Decorated for registration, error handling, and auth. Parses query (structured or free-text), builds API params via helper, executes Drive files.list(), formats results as readable text list.@server.tool() @handle_http_errors("search_drive_files", is_read_only=True, service_type="drive") @require_google_service("drive", "drive_read") async def search_drive_files( service, user_google_email: str, query: str, page_size: int = 10, drive_id: Optional[str] = None, include_items_from_all_drives: bool = True, corpora: Optional[str] = None, ) -> str: """ Searches for files and folders within a user's Google Drive, including shared drives. Args: user_google_email (str): The user's Google email address. Required. query (str): The search query string. Supports Google Drive search operators. page_size (int): The maximum number of files to return. Defaults to 10. drive_id (Optional[str]): ID of the shared drive to search. If None, behavior depends on `corpora` and `include_items_from_all_drives`. include_items_from_all_drives (bool): Whether shared drive items should be included in results. Defaults to True. This is effective when not specifying a `drive_id`. corpora (Optional[str]): Bodies of items to query (e.g., 'user', 'domain', 'drive', 'allDrives'). If 'drive_id' is specified and 'corpora' is None, it defaults to 'drive'. Otherwise, Drive API default behavior applies. Prefer 'user' or 'drive' over 'allDrives' for efficiency. Returns: str: A formatted list of found files/folders with their details (ID, name, type, size, modified time, link). """ logger.info(f"[search_drive_files] Invoked. Email: '{user_google_email}', Query: '{query}'") # Check if the query looks like a structured Drive query or free text # Look for Drive API operators and structured query patterns is_structured_query = any(pattern.search(query) for pattern in DRIVE_QUERY_PATTERNS) if is_structured_query: final_query = query logger.info(f"[search_drive_files] Using structured query as-is: '{final_query}'") else: # For free text queries, wrap in fullText contains escaped_query = query.replace("'", "\\'") final_query = f"fullText contains '{escaped_query}'" logger.info(f"[search_drive_files] Reformatting free text query '{query}' to '{final_query}'") list_params = build_drive_list_params( query=final_query, page_size=page_size, drive_id=drive_id, include_items_from_all_drives=include_items_from_all_drives, corpora=corpora, ) results = await asyncio.to_thread( service.files().list(**list_params).execute ) files = results.get('files', []) if not files: return f"No files found for '{query}'." formatted_files_text_parts = [f"Found {len(files)} files for {user_google_email} matching '{query}':"] for item in files: size_str = f", Size: {item.get('size', 'N/A')}" if 'size' in item else "" formatted_files_text_parts.append( f"- Name: \"{item['name']}\" (ID: {item['id']}, Type: {item['mimeType']}{size_str}, Modified: {item.get('modifiedTime', 'N/A')}) Link: {item.get('webViewLink', '#')}" ) text_output = "\n".join(formatted_files_text_parts) return text_output
- gdrive/drive_tools.py:47-62 (schema)Docstring defining input parameters, types, defaults, and return format, serving as the tool schema for MCP.""" Searches for files and folders within a user's Google Drive, including shared drives. Args: user_google_email (str): The user's Google email address. Required. query (str): The search query string. Supports Google Drive search operators. page_size (int): The maximum number of files to return. Defaults to 10. drive_id (Optional[str]): ID of the shared drive to search. If None, behavior depends on `corpora` and `include_items_from_all_drives`. include_items_from_all_drives (bool): Whether shared drive items should be included in results. Defaults to True. This is effective when not specifying a `drive_id`. corpora (Optional[str]): Bodies of items to query (e.g., 'user', 'domain', 'drive', 'allDrives'). If 'drive_id' is specified and 'corpora' is None, it defaults to 'drive'. Otherwise, Drive API default behavior applies. Prefer 'user' or 'drive' over 'allDrives' for efficiency. Returns: str: A formatted list of found files/folders with their details (ID, name, type, size, modified time, link). """
- gdrive/drive_tools.py:35-37 (registration)Tool registration via @server.tool() decorator, plus error handler and auth requirement decorators specific to this tool.@server.tool() @handle_http_errors("search_drive_files", is_read_only=True, service_type="drive") @require_google_service("drive", "drive_read")
- gdrive/drive_helpers.py:74-112 (helper)Helper constructs standardized parameters for Drive files.list() API calls, handling shared drives (driveId/corpora) and common fields.def build_drive_list_params( query: str, page_size: int, drive_id: Optional[str] = None, include_items_from_all_drives: bool = True, corpora: Optional[str] = None, ) -> Dict[str, Any]: """ Helper function to build common list parameters for Drive API calls. Args: query: The search query string page_size: Maximum number of items to return drive_id: Optional shared drive ID include_items_from_all_drives: Whether to include items from all drives corpora: Optional corpus specification Returns: Dictionary of parameters for Drive API list calls """ list_params = { "q": query, "pageSize": page_size, "fields": "nextPageToken, files(id, name, mimeType, webViewLink, iconLink, modifiedTime, size)", "supportsAllDrives": True, "includeItemsFromAllDrives": include_items_from_all_drives, } if drive_id: list_params["driveId"] = drive_id if corpora: list_params["corpora"] = corpora else: list_params["corpora"] = "drive" elif corpora: list_params["corpora"] = corpora return list_params
- gdrive/drive_helpers.py:59-71 (helper)Regex patterns used to identify structured Drive search queries vs free-text, triggering query reformatting in handler.DRIVE_QUERY_PATTERNS = [ re.compile(r'\b\w+\s*(=|!=|>|<)\s*[\'"].*?[\'"]', re.IGNORECASE), # field = 'value' re.compile(r'\b\w+\s*(=|!=|>|<)\s*\d+', re.IGNORECASE), # field = number re.compile(r'\bcontains\b', re.IGNORECASE), # contains operator re.compile(r'\bin\s+parents\b', re.IGNORECASE), # in parents re.compile(r'\bhas\s*\{', re.IGNORECASE), # has {properties} re.compile(r'\btrashed\s*=\s*(true|false)\b', re.IGNORECASE), # trashed=true/false re.compile(r'\bstarred\s*=\s*(true|false)\b', re.IGNORECASE), # starred=true/false re.compile(r'[\'"][^\'"]+[\'"]\s+in\s+parents', re.IGNORECASE), # 'parentId' in parents re.compile(r'\bfullText\s+contains\b', re.IGNORECASE), # fullText contains re.compile(r'\bname\s*(=|contains)\b', re.IGNORECASE), # name = or name contains re.compile(r'\bmimeType\s*(=|!=)\b', re.IGNORECASE), # mimeType operators ]