11import sqlite3
22import os
3+ import enum
34from contextlib import AsyncIterator
45from contextlib import asynccontextmanager
56from dataclasses import dataclass
67import logging
78from mcp .server .fastmcp import FastMCP , Context
89
10+ logging .basicConfig (level = logging .INFO )
11+
12+ logger = logging .getLogger ("browser-storage-mcp" )
913
1014FIREFOX_PROFILE_DIR = "`/Users/eleanor.mazzarella/Library/Application Support/Firefox/Profiles/l42msng6.default-release`"
1115
1216PATH_TO_FIREFOX_HISTORY = os .path .join (FIREFOX_PROFILE_DIR , "places.sqlite" )
1317
14- logging .basicConfig (level = logging .INFO )
18+ @dataclass (frozen = True )
19+ class BrowserType (enum .Enum ):
20+ FIREFOX = "firefox"
21+ CHROME = "chrome"
1522
16- logger = logging .getLogger ("browser-storage-mcp" )
1723
1824mcp = FastMCP ("firefox-history" )
1925
@@ -36,41 +42,29 @@ async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
3642mcp = FastMCP ("firefox-history" , lifespan = app_lifespan )
3743
3844@mcp .prompt ()
39- def explore_firefox_history () -> str :
40- """Create a prompt to explore the Firefox history """
45+ def productivity_analysis () -> str :
46+ """Creates a user prompt for analyzing productivity """
4147 return """
42- I can help you explore your Firefox history.
43-
44- Here are some of the things I can do:
45- - I can list all of the sites you visited today or in the last week.
48+ Focus on work vs. entertainment ratios, identify time sinks, suggest optimizations.
49+ Group history by "session", which can be inferred by the gap between timestamps.
50+ For example, a "session" might be a period of time with no more than 2 hours between visits.
4651 """
4752
48- @mcp .prompt ()
49- def analyze_firefox_history (number_of_days : int ) -> str :
50- """Analyze the Firefox history"""
51- return f"""
52- I can analyze the Firefox history from the past '{ number_of_days } ' days.
53-
54- I can help you understand:
55- - What sites you visited the most
56- - What common themes arise from your browsing history
57- - Areas you have been focusing on in the past { number_of_days } days
58- """
59-
60- @mcp .prompt ()
61- def create_firefox_history_report (number_of_days : int ) -> str :
62- """Create a report of the Firefox history"""
63- return f"""
64- I can create a report of the Firefox history from the past '{ number_of_days } ' days.
53+ def learning_analysis () -> str :
54+ """Creates a user prompt for analyzing learning"""
55+ return """
56+ Analyze the browser history through the lens of learning and research. Try to infer when
57+ a url was visited in order to solve a specific problem versus when it was visited for general purpose understanding.
58+ If you think any URLs were visited in order for a "quick fix" or "quick answer", group this into a special section
59+ where there are opportunities for deeper understanding and more lasting learning.
6560
66- The report will be in markdown with a clear structure, and will be saved to a file in the current directory.
61+ Group history by "session", which can be inferred by the gap between timestamps.
62+ For example, a "session" might be a period of time with no more than 2 hours between visits.
6763 """
6864
6965
70-
7166@mcp .tool ()
72- async def get_history (context : AppContext , query : str ) -> list [str ]:
73- """Get history from Firefox"""
67+ async def get_browser_history (context : AppContext , time_period_in_days : int , browser_type : BrowserType ) -> list [str ]:
68+ """Get history from Firefox or Chrome """
7469 cursor = context .db .cursor ()
75- cursor .execute ("SELECT url FROM moz_places WHERE url LIKE ?" , (f"%{ query } %" ,))
76- return [row [0 ] for row in cursor .fetchall ()]
70+ # TODO
0 commit comments