Skip to main content
Glama
mixophrygian

Browser History Analysis MCP

by mixophrygian

get_browser_history

Retrieve raw browser history data from multiple browsers within a specified time period for further analysis. Supports Firefox, Chrome, Safari, and auto-detection of browser types.

Instructions

Step 2: Get raw browser history data without analysis. This is the fastest way to retrieve browser history and should be used before any analysis.

Args: time_period_in_days: Number of days of history to retrieve (default: 7) browser_type: Browser type ('firefox', 'chrome', 'safari', or None for auto-detect) all_browsers: If True, get history from all available browsers (default: True) Returns: Either a list of history entries or a dictionary with partial results and browser status

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
all_browsersNo
browser_typeNo
time_period_in_daysNo

Implementation Reference

  • The primary handler function for the 'get_browser_history' tool, registered with @mcp.tool(). It processes inputs and calls the core implementation, serving as the entry point for MCP tool execution.
    @mcp.tool() async def get_browser_history(time_period_in_days: int = 7, browser_type: Optional[str] = None, all_browsers: bool = True) -> Union[List[HistoryEntryDict], Dict[str, Any]]: """Step 2: Get raw browser history data without analysis. This is the fastest way to retrieve browser history and should be used before any analysis. Args: time_period_in_days: Number of days of history to retrieve (default: 7) browser_type: Browser type ('firefox', 'chrome', 'safari', or None for auto-detect) all_browsers: If True, get history from all available browsers (default: True) Returns: Either a list of history entries or a dictionary with partial results and browser status """ return await tool_get_browser_history(time_period_in_days, CACHED_HISTORY, browser_type, all_browsers)
  • Core helper function implementing the full tool logic: detects browsers, queries SQLite history databases (Firefox places.sqlite, Chrome History, Safari History.db), handles timestamps/microseconds conversions, manages locked databases, supports partial success across multiple browsers, and returns formatted history or error details.
    async def tool_get_browser_history(time_period_in_days: int, CACHED_HISTORY: CachedHistory, browser_type: Optional[str] = None, all_browsers: bool = True) -> Union[List[HistoryEntryDict], BrowserHistoryResult]: start_time = time.time() print(f"πŸš€ Starting browser history retrieval for {time_period_in_days} days...") if time_period_in_days <= 0: raise ValueError("time_period_in_days must be a positive integer") # Map browser types to their handler functions browser_handlers = { "firefox": get_firefox_history, "chrome": get_chrome_history, "safari": get_safari_history } if all_browsers: # Step 1: Detect available browsers step_start = time.time() print("πŸ“Š Step 1: Detecting available browsers...") browser_status = tool_detect_available_browsers() detect_time = time.time() - step_start print(f"πŸ“Š Browser detection completed in {detect_time:.3f}s") if browser_status.get("status") == "error": print(f"❌ {browser_status['error_message']}") raise RuntimeError(browser_status['error_message']) elif browser_status.get("status") == "browser_locked": print(f"❌ {browser_status['error_message']}") raise RuntimeError(browser_status['error_message']) available_browsers = browser_status.get('available_browsers', []) if not available_browsers: print("❌ No available browsers found") raise RuntimeError("No browser history databases found. Please ensure Firefox, Chrome, or Safari is installed and try again.") print(f"πŸ“Š Available browsers: {available_browsers}") # Step 2: Get history from each browser all_entries = [] successful_browsers = [] failed_browsers = [] failure_reasons = {} for browser in available_browsers: browser_start = time.time() print(f"πŸ“Š Step 2.{len(successful_browsers) + len(failed_browsers) + 1}: Getting {browser} history...") try: entries = browser_handlers[browser](time_period_in_days) browser_time = time.time() - browser_start print(f"πŸ“Š {browser} history retrieved in {browser_time:.3f}s: {len(entries)} entries") logger.warning(f"Retrieved {len(entries)} {browser} history entries from last {time_period_in_days} days") all_entries.extend([entry.to_dict() for entry in entries]) successful_browsers.append(browser) except Exception as e: browser_time = time.time() - browser_start error_msg = str(e) print(f"❌ {browser} history failed in {browser_time:.3f}s: {error_msg}") logger.warning(f"Failed to get {browser} history: {error_msg}. If the database is locked, please try closing the browser and running the tool again.") failed_browsers.append(browser) failure_reasons[browser] = error_msg continue total_time = time.time() - start_time print(f"πŸ“Š Total browser history retrieval time: {total_time:.3f}s") # If we have any successful browsers, return partial results if successful_browsers: recommendation = "" if failed_browsers: locked_browsers = [browser for browser in failed_browsers if "database is locked" in failure_reasons.get(browser, "").lower()] if locked_browsers: recommendation = f"πŸ”’ BROWSER LOCKED: {', '.join([b.title() for b in locked_browsers])} {'is' if len(locked_browsers) == 1 else 'are'} currently running. Please close {'this browser' if len(locked_browsers) == 1 else 'these browsers'} completely to get complete history analysis. You can restore tabs with Ctrl+Shift+T (Cmd+Shift+T on Mac). " recommendation += f"Successfully retrieved {len(all_entries)} entries from {', '.join([b.title() for b in successful_browsers])}." else: recommendation = f"βœ… Successfully retrieved {len(all_entries)} entries from all browsers: {', '.join([b.title() for b in successful_browsers])}." logger.warning(f"Retrieved total of {len(all_entries)} history entries from {len(successful_browsers)} browsers") return { "history_entries": all_entries, "successful_browsers": successful_browsers, "failed_browsers": failed_browsers, "failure_reasons": failure_reasons, "total_entries": len(all_entries), "status": "partial_success" if failed_browsers else "success", "user_action_required": bool(failed_browsers), "recommendation": recommendation } # If no browsers succeeded, raise error with detailed information locked_browsers = [browser for browser in failed_browsers if "database is locked" in failure_reasons.get(browser, "").lower()] if locked_browsers: error_message = f"πŸ”’ BROWSER LOCKED: All browsers ({', '.join([b.title() for b in locked_browsers])}) are currently running and their databases are locked. Please close ALL browsers completely to analyze history. You can restore tabs with Ctrl+Shift+T (Cmd+Shift+T on Mac)." else: error_details = "; ".join([f"{browser}: {reason}" for browser, reason in failure_reasons.items()]) error_message = f"❌ ERROR: Failed to retrieve history from any browser: {error_details}" raise RuntimeError(error_message) else: # Single browser mode (original behavior) if browser_type is None: browser_status = tool_detect_available_browsers() if browser_status.get("status") == "error": raise RuntimeError(browser_status['error_message']) elif browser_status.get("status") == "browser_locked": raise RuntimeError(browser_status['error_message']) # Get the first available browser from the available_browsers list available_browsers = browser_status.get('available_browsers', []) browser_type = available_browsers[0] if available_browsers else None if browser_type is None: raise RuntimeError("No browser history databases found. Please ensure Firefox, Chrome, or Safari is installed and try again.") logger.warning(f"Auto-detected active browser: {browser_type}") if browser_type not in browser_handlers: raise ValueError(f"Unsupported browser type: {browser_type}. Supported types: {list(browser_handlers.keys())}") try: entries = browser_handlers[browser_type](time_period_in_days) logger.warning(f"Retrieved {len(entries)} {browser_type} history entries from last {time_period_in_days} days") # Ensure we are always working with dictionaries entries_dict = [ensure_history_entry_dict(e) for e in entries] # Cache the history for later use CACHED_HISTORY.add_history(entries_dict, time_period_in_days, browser_type) return entries_dict except sqlite3.Error as e: logger.error(f"Error querying {browser_type} history: {e}") if "database is locked" in str(e).lower(): raise RuntimeError(f"πŸ”’ BROWSER LOCKED: {browser_type.title()} is currently running and its database is locked. Please close {browser_type.title()} completely to analyze its history. You can restore tabs with Ctrl+Shift+T (Cmd+Shift+T on Mac).") else: raise RuntimeError(f"❌ ERROR: Failed to query {browser_type.title()} history: {e}") except Exception as e: logger.error(f"Unexpected error querying {browser_type} history: {e}") raise RuntimeError(f"❌ ERROR: Failed to query {browser_type.title()} history: {e}")
  • Pydantic/TypedDict schema for individual browser history entries returned in the list format.
    class HistoryEntryDict(TypedDict): """Type for individual history entry as dictionary""" url: str title: Optional[str] visit_count: int last_visit_time: str # ISO format datetime string
  • TypedDict schema for the dictionary return type when partial success occurs (some browsers failed).
    class BrowserHistoryResult(TypedDict): """Type for browser history retrieval result with partial success handling""" history_entries: List[HistoryEntryDict] successful_browsers: List[str] failed_browsers: List[str] failure_reasons: Dict[str, str] total_entries: int recommendation: str
  • server/main.py:40-52 (registration)
    The @mcp.tool() decorator registers this function as the MCP tool named 'get_browser_history'.
    @mcp.tool() async def get_browser_history(time_period_in_days: int = 7, browser_type: Optional[str] = None, all_browsers: bool = True) -> Union[List[HistoryEntryDict], Dict[str, Any]]: """Step 2: Get raw browser history data without analysis. This is the fastest way to retrieve browser history and should be used before any analysis. Args: time_period_in_days: Number of days of history to retrieve (default: 7) browser_type: Browser type ('firefox', 'chrome', 'safari', or None for auto-detect) all_browsers: If True, get history from all available browsers (default: True) Returns: Either a list of history entries or a dictionary with partial results and browser status """ return await tool_get_browser_history(time_period_in_days, CACHED_HISTORY, browser_type, all_browsers)

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mixophrygian/browser_history_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server