get_workbook_metadata
Retrieve detailed metadata about Excel workbooks, including sheet names and optional range details, using the xlwings Excel MCP Server for secure and efficient workbook analysis.
Instructions
Get metadata about workbook including sheets, ranges, etc.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filepath | Yes | ||
| include_ranges | No |
Input Schema (JSON Schema)
{
"properties": {
"filepath": {
"title": "Filepath",
"type": "string"
},
"include_ranges": {
"default": false,
"title": "Include Ranges",
"type": "boolean"
}
},
"required": [
"filepath"
],
"title": "get_workbook_metadataArguments",
"type": "object"
}
Implementation Reference
- src/xlwings_mcp/server.py:914-944 (registration)MCP tool registration and wrapper handler for get_workbook_metadata. Validates session and delegates to xlwings implementation.def get_workbook_metadata( session_id: str, include_ranges: bool = False ) -> str: """ Get metadata about workbook including sheets, ranges, etc. Args: session_id: Session ID from open_workbook (required) include_ranges: Whether to include range information """ try: # Validate session using centralized helper session = get_validated_session(session_id) if isinstance(session, str): # Error message returned return session with session.lock: from xlwings_mcp.xlwings_impl.workbook_xlw import get_workbook_metadata_xlw_with_wb result = get_workbook_metadata_xlw_with_wb(session.workbook, include_ranges=include_ranges) if "error" in result: return f"Error: {result['error']}" import json return json.dumps(result, indent=2, default=str, ensure_ascii=False) except (ValidationError, WorkbookError) as e: return f"Error: {str(e)}" except Exception as e: logger.error(f"Error getting workbook metadata: {e}") raise
- Core handler implementation for extracting workbook metadata using xlwings API on an open workbook object (session mode). Collects sheets, properties, used ranges, protection status, etc.def get_workbook_metadata_xlw_with_wb( wb, include_ranges: bool = False ) -> Dict[str, Any]: """Session-based version using existing workbook object. Args: wb: Workbook object from session include_ranges: 각 시트의 사용 범위 포함 여부 Returns: 워크북 메타데이터 딕셔너리 """ try: # 기본 메타데이터 수집 metadata = { "sheets": [sheet.name for sheet in wb.sheets], "sheet_count": len(wb.sheets) } # 워크북 속성 추가 try: # COM 객체를 통해 추가 속성 접근 (가능한 경우) wb_props = wb.api.BuiltinDocumentProperties # 작성자 정보 try: metadata["author"] = wb_props("Author").Value except Exception: metadata["author"] = "Unknown" # 생성 날짜 try: metadata["created"] = wb_props("Creation Date").Value except Exception: metadata["created"] = None # 마지막 저장자 try: metadata["last_saved_by"] = wb_props("Last Save Time").Value except Exception: metadata["last_saved_by"] = None except Exception as e: logger.debug(f"워크북 속성 읽기 부분적 실패: {e}") # 활성 시트 정보 if wb.sheets: try: # xlwings에서 활성 시트는 첫 번째 시트로 가정 metadata["active_sheet"] = wb.sheets[0].name except Exception: metadata["active_sheet"] = None # 시트별 범위 정보 (요청된 경우) if include_ranges: sheet_info = {} for sheet in wb.sheets: try: # 사용된 범위 확인 used_range = sheet.used_range if used_range: sheet_info[sheet.name] = { "used_range": str(used_range.address), "rows": used_range.rows.count, "columns": used_range.columns.count, "first_cell": used_range.offset(0, 0).resize(1, 1).address, "last_cell": used_range.offset( used_range.rows.count - 1, used_range.columns.count - 1 ).resize(1, 1).address } else: # 빈 시트 sheet_info[sheet.name] = { "used_range": "Empty", "rows": 0, "columns": 0, "first_cell": "A1", "last_cell": "A1" } # 시트 보호 상태 확인 try: sheet_info[sheet.name]["protected"] = sheet.api.ProtectContents except Exception: sheet_info[sheet.name]["protected"] = False except Exception as e: logger.warning(f"시트 '{sheet.name}' 정보 수집 실패: {e}") sheet_info[sheet.name] = {"error": str(e)} metadata["sheet_info"] = sheet_info return metadata except Exception as e: logger.error(f"xlwings 워크북 메타데이터 조회 실패: {e}") return {"error": f"Failed to get workbook metadata: {str(e)}"}
- Helper function for non-session (file path-based) workbook metadata extraction, similar to session version but opens workbook itself.def get_workbook_metadata_xlw( filepath: str, include_ranges: bool = False ) -> Dict[str, Any]: """xlwings를 사용한 워크북 메타데이터 조회 Args: filepath: Excel 파일 경로 include_ranges: 각 시트의 사용 범위 포함 여부 Returns: 워크북 메타데이터 딕셔너리 """ try: # 파일 경로 검증 file_path = validate_file_path(filepath, must_exist=True) # Excel context로 워크북 열기 with excel_context(filepath) as wb: # 기본 메타데이터 수집 metadata = { "filename": file_path.name, "full_path": str(file_path.absolute()), "sheets": [sheet.name for sheet in wb.sheets], "sheet_count": len(wb.sheets), "size": file_path.stat().st_size, "modified": file_path.stat().st_mtime } # 워크북 속성 추가 try: # COM 객체를 통해 추가 속성 접근 (가능한 경우) wb_props = wb.api.BuiltinDocumentProperties # 작성자 정보 try: metadata["author"] = wb_props("Author").Value except Exception: metadata["author"] = "Unknown" # 생성 날짜 try: metadata["created"] = wb_props("Creation Date").Value except Exception: metadata["created"] = None # 마지막 저장자 try: metadata["last_saved_by"] = wb_props("Last Save Time").Value except Exception: metadata["last_saved_by"] = None except Exception as e: logger.debug(f"워크북 속성 읽기 부분적 실패: {e}") # 활성 시트 정보 if wb.sheets: try: # xlwings에서 활성 시트는 첫 번째 시트로 가정 metadata["active_sheet"] = wb.sheets[0].name except Exception: metadata["active_sheet"] = None # 시트별 범위 정보 (요청된 경우) if include_ranges: sheet_info = {} for sheet in wb.sheets: try: # 사용된 범위 확인 used_range = sheet.used_range if used_range: sheet_info[sheet.name] = { "used_range": str(used_range.address), "rows": used_range.rows.count, "columns": used_range.columns.count, "first_cell": used_range.offset(0, 0).resize(1, 1).address, "last_cell": used_range.offset( used_range.rows.count - 1, used_range.columns.count - 1 ).resize(1, 1).address } else: # 빈 시트 sheet_info[sheet.name] = { "used_range": "Empty", "rows": 0, "columns": 0, "first_cell": "A1", "last_cell": "A1" } # 시트 보호 상태 확인 try: sheet_info[sheet.name]["protected"] = sheet.api.ProtectContents except Exception: sheet_info[sheet.name]["protected"] = False except Exception as e: logger.warning(f"시트 '{sheet.name}' 정보 수집 실패: {e}") sheet_info[sheet.name] = {"error": str(e)} metadata["sheet_info"] = sheet_info return metadata except Exception as e: logger.error(f"xlwings 워크북 메타데이터 조회 실패: {e}") return {"error": f"Failed to get workbook metadata: {str(e)}"}
- src/xlwings_mcp/workbook.py:27-32 (helper)Public wrapper in workbook.py that calls the non-session xlwings implementation and raises exceptions on error.def get_workbook_info(filepath: str, include_ranges: bool = False) -> dict[str, Any]: """Get metadata about workbook including sheets, ranges, etc.""" result = get_workbook_metadata_xlw(filepath, include_ranges) if "error" in result: raise WorkbookError(result["error"]) return result