get_transaction_history
Retrieve recent package transaction history from pacman log on Arch Linux, showing installed, upgraded, and removed packages with filtering options.
Instructions
[HISTORY] Get recent package transactions from pacman log. Shows installed, upgraded, and removed packages. Only works on Arch Linux.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of transactions to return (default 50) | |
| transaction_type | No | Filter by type: install/remove/upgrade/all (default all) | all |
Implementation Reference
- src/arch_ops_server/logs.py:67-134 (handler)The core async handler function that implements the get_transaction_history tool. It parses the pacman.log file, filters transactions by type and limit, and returns structured history data. Includes error handling for non-Arch systems and missing log files.async def get_transaction_history( limit: int = 50, transaction_type: str = "all" ) -> Dict[str, Any]: """ Get recent package transactions from pacman log. Args: limit: Maximum number of transactions to return (default 50) transaction_type: Filter by type - install/remove/upgrade/all (default all) Returns: Dict with transaction history """ if not IS_ARCH: return create_error_response( "NotSupported", "This feature is only available on Arch Linux" ) logger.info(f"Getting transaction history (limit={limit}, type={transaction_type})") try: pacman_log = Path(PACMAN_LOG) if not pacman_log.exists(): return create_error_response( "NotFound", f"Pacman log file not found at {PACMAN_LOG}" ) transactions = [] valid_actions = { "all": ["installed", "upgraded", "removed", "downgraded", "reinstalled"], "install": ["installed"], "remove": ["removed"], "upgrade": ["upgraded", "downgraded", "reinstalled"] } actions_to_match = valid_actions.get(transaction_type, valid_actions["all"]) # Read log file from end (most recent first) with open(pacman_log, 'r') as f: lines = f.readlines() # Process in reverse order for most recent first for line in reversed(lines): if len(transactions) >= limit: break parsed = parse_log_line(line) if parsed and parsed["action"].lower() in actions_to_match: transactions.append(parsed) logger.info(f"Found {len(transactions)} transactions") return { "count": len(transactions), "transaction_type": transaction_type, "transactions": transactions } except Exception as e: logger.error(f"Failed to parse transaction history: {e}") return create_error_response( "LogParseError", f"Failed to parse transaction history: {str(e)}" )
- src/arch_ops_server/server.py:996-1015 (registration)MCP tool registration in @server.list_tools(). Defines the tool name, description, and input schema for parameters limit and transaction_type. This makes the tool discoverable to MCP clients.name="get_transaction_history", description="[HISTORY] Get recent package transactions from pacman log. Shows installed, upgraded, and removed packages. Only works on Arch Linux.", inputSchema={ "type": "object", "properties": { "limit": { "type": "integer", "description": "Maximum number of transactions to return (default 50)", "default": 50 }, "transaction_type": { "type": "string", "description": "Filter by type: install/remove/upgrade/all (default all)", "enum": ["all", "install", "remove", "upgrade"], "default": "all" } }, "required": [] } ),
- Tool execution dispatcher in @server.call_tool(). Handles input parameter extraction, Arch Linux check, invokes the handler function, and formats the JSON response as TextContent for MCP protocol.elif name == "get_transaction_history": if not IS_ARCH: return [TextContent(type="text", text="Error: get_transaction_history only available on Arch Linux systems")] limit = arguments.get("limit", 50) transaction_type = arguments.get("transaction_type", "all") result = await get_transaction_history(limit=limit, transaction_type=transaction_type) return [TextContent(type="text", text=json.dumps(result, indent=2))]
- src/arch_ops_server/logs.py:24-64 (helper)Supporting helper function parse_log_line that extracts structured data (timestamp, action, package, version) from individual pacman log lines using regex patterns.def parse_log_line(line: str) -> Optional[Dict[str, Any]]: """ Parse a single line from pacman log. Args: line: Log line to parse Returns: Dict with parsed data or None if not a transaction line """ # Format: [YYYY-MM-DD HH:MM] [ACTION] package (version) match = re.match( r'\[(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2})\]\s+\[(\w+)\]\s+(.+)', line ) if not match: return None date_str, time_str, action, details = match.groups() timestamp = f"{date_str}T{time_str}:00" # Parse package details # Format: "package_name (version)" or "package_name (old -> new)" pkg_match = re.match(r'(\S+)\s+\((.+)\)', details) if pkg_match: package = pkg_match.group(1) version_info = pkg_match.group(2) else: # Some log lines don't have version info package = details version_info = "" return { "timestamp": timestamp, "action": action, "package": package, "version_info": version_info, "raw_line": line.strip() }