Skip to main content
Glama
mixophrygian

Browser History Analysis MCP

by mixophrygian

check_browser_status

Check browser availability and lock status to determine if browsers need closing before analyzing history.

Instructions

Step 1: Check which browsers are available and which are locked. This is the first step in the workflow - run this to see if you need to close any browsers.

Returns a dictionary with:
- status: "ready", "browser_locked", or "error"
- error_message: Clear error message if there's an issue
- user_action_required: True if user needs to close browsers
- recommended_action: Specific instructions for the user
- available_browsers: List of detected browsers
- active_browsers: List of browsers that are currently running

IMPORTANT: If status is "browser_locked", you MUST tell the user to close the specified browser(s).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The handler function for the 'check_browser_status' tool, decorated with @mcp.tool() for automatic registration. It calls the helper tool_detect_available_browsers() from browser_utils and adds a Claude-specific instruction if user action is required.
    @mcp.tool()
    def check_browser_status() -> Dict[str, Any]:
        """Step 1: Check which browsers are available and which are locked.
        This is the first step in the workflow - run this to see if you need to close any browsers.
        
        Returns a dictionary with:
        - status: "ready", "browser_locked", or "error"
        - error_message: Clear error message if there's an issue
        - user_action_required: True if user needs to close browsers
        - recommended_action: Specific instructions for the user
        - available_browsers: List of detected browsers
        - active_browsers: List of browsers that are currently running
        
        IMPORTANT: If status is "browser_locked", you MUST tell the user to close the specified browser(s).
    
        """
        result = tool_detect_available_browsers()
        
        # If there's a user action required, make it very clear
        if result.get("user_action_required", False):
            result["claude_instruction"] = "IMPORTANT: Tell the user they need to close their browser(s) as specified in the recommended_action field."
        
        return result
  • Core helper function implementing the browser detection and status checking logic. Detects paths to Firefox, Chrome, and Safari history databases, attempts read-only connections to check for locks (indicating running browsers), and returns detailed status information used by the main handler.
    def tool_detect_available_browsers() -> Dict[str, Any]:
        browsers_to_check = []
        
        # Check Firefox
        if PATH_TO_FIREFOX_HISTORY:
            browsers_to_check.append(('firefox', PATH_TO_FIREFOX_HISTORY))
        
        # Check Chrome
        if PATH_TO_CHROME_HISTORY:
            browsers_to_check.append(('chrome', PATH_TO_CHROME_HISTORY))
        
        # Check Safari
        if PATH_TO_SAFARI_HISTORY:
            browsers_to_check.append(('safari', PATH_TO_SAFARI_HISTORY))
        
        if not browsers_to_check:
            logger.warning("No browser history databases found")
            return {
                "available_browsers": [],
                "active_browsers": [],
                "status": "error",
                "error_message": "No browser history databases found. Please ensure Firefox, Chrome, or Safari is installed.",
                "user_action_required": False,
                "recommended_action": "Install Firefox, Chrome, or Safari to use this tool"
            }
        
        browsers_in_use = []
        for browser_name, db_path in browsers_to_check:
            logger.warning(f"Checking {browser_name} database at {db_path}")
            try:
                # Try to connect with read-only mode
                conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
                
                # Test if we can actually query the database
                cursor = conn.cursor()
                cursor.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table';")
                table_count = cursor.fetchone()[0]
                conn.close()
                
                logger.warning(f"Successfully connected to {browser_name} database and queried {table_count} tables. Browser may still be running, encourage the user to close this browser to make history available.")
            except sqlite3.OperationalError as e:
                if "database is locked" in str(e).lower():
                    logger.warning(f"Database locked for {browser_name} - browser is likely open and active - prompt the user to close it to get complete history.")
                    # Short-circuit: return immediately if any browser is locked
                    return {
                        "available_browsers": [browser[0] for browser in browsers_to_check],
                        "active_browsers": [browser_name],
                        "status": "browser_locked",
                        "error_message": f"🔒 BROWSER LOCKED: {browser_name.title()} is currently running and its database is locked.",
                        "user_action_required": True,
                        "recommended_action": f"❗ IMPORTANT: Please close all browsers, especially {browser_name.title()} completely to analyze its history. You can restore your tabs later with Ctrl+Shift+T (Cmd+Shift+T on Mac).",
                        "technical_details": f"Database error: {str(e)}"
                    }
                else:
                    logger.warning(f"Error connecting to {browser_name} database: {e} - please inform the user that this browser is not available for analysis.")
            except Exception as e:
                logger.warning(f"Unexpected error connecting to {browser_name} database: {e}")
                # Short-circuit: return immediately if any browser has an error
                return {
                    "available_browsers": [browser[0] for browser in browsers_to_check],
                    "active_browsers": [browser_name],
                    "status": "error",
                    "error_message": f"❌ ERROR: Cannot access {browser_name.title()} database.",
                    "user_action_required": True,
                    "recommended_action": f"Please close all browsers, especially {browser_name.title()} completely and try again. You can restore your tabs later with Ctrl+Shift+T (Cmd+Shift+T on Mac).",
                    "technical_details": f"Technical error: {str(e)}"
                }
        
        # If we get here, no browsers are locked
        available_browsers = [browser[0] for browser in browsers_to_check]
        logger.warning(f"No active browser detected, available browsers: {available_browsers}")
        return {
            "available_browsers": available_browsers,
            "active_browsers": [],
            "status": "ready",
            "error_message": None,
            "user_action_required": False,
            "recommended_action": f"✅ All browsers are available for analysis. Found: {', '.join(available_browsers)}"
        }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does well by disclosing key behaviors: it returns specific statuses and fields, indicates user action requirements, and provides error handling. However, it doesn't mention potential side effects like performance impact or authentication needs, leaving some gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose, followed by output details and important usage notes. However, the step numbering ('Step 1:') is slightly redundant and could be more concise, though overall it's efficient and informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (status checking with user interactions), no annotations, and the presence of an output schema, the description is complete: it explains the purpose, usage context, output structure, and critical actions, covering all necessary aspects without needing to detail return values since an output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Since there are 0 parameters and schema description coverage is 100%, the baseline is 4. The description appropriately doesn't add parameter details, focusing instead on output semantics, which aligns with the tool's no-input nature.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('check which browsers are available and which are locked') and resources ('browsers'), distinguishing it from siblings like analyze_browser_history or get_browser_history by focusing on status rather than history or analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool ('first step in the workflow - run this to see if you need to close any browsers') and provides a clear action requirement ('If status is "browser_locked", you MUST tell the user to close the specified browser(s)'), effectively guiding usage versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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