88
99# Import from the browser-use-mcp-server package
1010from browser_use_mcp_server .server import (
11- initialize_browser_context ,
1211 create_mcp_server ,
1312)
1413from langchain_openai import ChatOpenAI
@@ -64,97 +63,21 @@ def main(
6463 task_expiry_minutes : int ,
6564) -> int :
6665 """Run the browser-use MCP server."""
67- # If Chrome path is explicitly provided, use it
68- if chrome_path and os .path . exists ( chrome_path ):
69- chrome_executable_path = chrome_path
70- logger .info (f"Using explicitly provided Chrome path: { chrome_executable_path } " )
66+ # Use Chrome path from command line arg, environment variable, or None
67+ chrome_executable_path = chrome_path or os .environ . get ( "CHROME_PATH" )
68+ if chrome_executable_path :
69+ logger .info (f"Using Chrome path: { chrome_executable_path } " )
7170 else :
72- # Try to find Playwright's installed Chromium first
73- import os .path
74- import platform
75- from pathlib import Path
76- import subprocess
77-
78- # Try to get Playwright browsers directory
79- home_dir = str (Path .home ())
80- system = platform .system ()
81-
82- if system == "Darwin" : # macOS
83- playwright_browsers_path = os .path .join (home_dir , "Library" , "Caches" , "ms-playwright" )
84- elif system == "Linux" :
85- playwright_browsers_path = os .path .join (home_dir , ".cache" , "ms-playwright" )
86- elif system == "Windows" :
87- playwright_browsers_path = os .path .join (home_dir , "AppData" , "Local" , "ms-playwright" )
88- else :
89- playwright_browsers_path = None
90-
91- # Try to find the Chromium executable in the Playwright directory
92- chromium_executable_path = None
93- if playwright_browsers_path and os .path .exists (playwright_browsers_path ):
94- logger .info (f"Found Playwright browsers directory at { playwright_browsers_path } " )
95- # Look for chromium directories
96- try :
97- for root , dirs , files in os .walk (playwright_browsers_path ):
98- for dir in dirs :
99- if "chromium" in dir .lower ():
100- # Check for executable in this directory
101- if system == "Darwin" : # macOS
102- exec_path = os .path .join (root , dir , "chrome-mac" , "Chromium.app" , "Contents" , "MacOS" , "Chromium" )
103- elif system == "Linux" :
104- exec_path = os .path .join (root , dir , "chrome-linux" , "chrome" )
105- elif system == "Windows" :
106- exec_path = os .path .join (root , dir , "chrome-win" , "chrome.exe" )
107- else :
108- continue
109-
110- if os .path .exists (exec_path ):
111- chromium_executable_path = exec_path
112- logger .info (f"Found Playwright Chromium at { chromium_executable_path } " )
113- break
114- if chromium_executable_path :
115- break
116- except Exception as e :
117- logger .warning (f"Error searching for Playwright Chromium: { str (e )} " )
118-
119- # If Playwright Chromium not found, try standard locations
120- if not chromium_executable_path :
121- # Try to find Chromium/Chrome in common locations
122- potential_paths = [
123- # Environment variable
124- os .environ .get ("CHROME_PATH" ),
125-
126- # Common macOS paths
127- "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ,
128- "/Applications/Chromium.app/Contents/MacOS/Chromium" ,
129-
130- # Common Linux paths
131- "/usr/bin/chromium" ,
132- "/usr/bin/chromium-browser" ,
133- "/usr/bin/google-chrome" ,
134- "/usr/bin/google-chrome-stable" ,
135- ]
136-
137- for path in potential_paths :
138- if path and os .path .exists (path ):
139- logger .info (f"Found browser at { path } " )
140- chromium_executable_path = path
141- break
142-
143- # Use the found path or try with Playwright's default
144- if chromium_executable_path :
145- chrome_executable_path = chromium_executable_path
146- logger .info (f"Using browser executable at: { chrome_executable_path } " )
147- else :
148- # If no specific path found, let Playwright find its own browser
149- logger .warning ("No Chrome/Chromium path found, will let Playwright use its default browser" )
150- chrome_executable_path = None
151-
71+ logger .info (
72+ "No Chrome path specified, letting Playwright use its default browser"
73+ )
74+
15275 # Initialize browser context
15376 try :
15477 # Using the approach from backup/server.py
15578 from browser_use .browser .context import BrowserContextConfig , BrowserContext
15679 from browser_use .browser .browser import Browser , BrowserConfig
157-
80+
15881 # Browser context configuration
15982 config = BrowserContextConfig (
16083 wait_for_network_idle_page_load_time = 0.6 ,
@@ -166,7 +89,7 @@ def main(
16689 highlight_elements = True ,
16790 viewport_expansion = 0 ,
16891 )
169-
92+
17093 # Initialize browser and context directly
17194 browser_config = BrowserConfig (
17295 extra_chromium_args = [
@@ -177,36 +100,36 @@ def main(
177100 "--remote-debugging-port=9222" ,
178101 ],
179102 )
180-
181- # Only set chrome_instance_path if we actually found a path
103+
104+ # Only set chrome_instance_path if we actually set a path in the env file
182105 if chrome_executable_path :
183106 browser_config .chrome_instance_path = chrome_executable_path
184-
107+
185108 browser = Browser (config = browser_config )
186109 context = BrowserContext (browser = browser , config = config )
187110 logger .info ("Browser context initialized successfully" )
188111 except Exception as e :
189112 logger .error (f"Failed to initialize browser context: { str (e )} " )
190113 return 1
191-
114+
192115 # Initialize LLM
193116 llm = ChatOpenAI (model = "gpt-4o" , temperature = 0.0 )
194-
117+
195118 # Create MCP server
196119 app = create_mcp_server (
197120 context = context ,
198121 llm = llm ,
199122 task_expiry_minutes = task_expiry_minutes ,
200123 )
201-
124+
202125 if transport == "sse" :
203126 from mcp .server .sse import SseServerTransport
204127 from starlette .applications import Starlette
205128 from starlette .routing import Mount , Route
206129 import uvicorn
207-
130+
208131 sse = SseServerTransport ("/messages/" )
209-
132+
210133 async def handle_sse (request ):
211134 try :
212135 async with sse .connect_sse (
@@ -218,25 +141,25 @@ async def handle_sse(request):
218141 except Exception as e :
219142 logger .error (f"Error in handle_sse: { str (e )} " )
220143 raise
221-
144+
222145 starlette_app = Starlette (
223146 debug = True ,
224147 routes = [
225148 Route ("/sse" , endpoint = handle_sse ),
226149 Mount ("/messages/" , app = sse .handle_post_message ),
227150 ],
228151 )
229-
152+
230153 # Add a startup event to initialize the browser and start task cleanup
231154 @starlette_app .on_event ("startup" )
232155 async def startup_event ():
233156 logger .info ("Starting server and scheduling cleanup..." )
234-
157+
235158 # Start the cleanup task now that we have an event loop
236- if hasattr (app , ' cleanup_old_tasks' ):
159+ if hasattr (app , " cleanup_old_tasks" ):
237160 asyncio .create_task (app .cleanup_old_tasks ())
238161 logger .info ("Task cleanup process scheduled" )
239-
162+
240163 # Add a shutdown event to clean up browser resources
241164 @starlette_app .on_event ("shutdown" )
242165 async def shutdown_event ():
@@ -246,18 +169,18 @@ async def shutdown_event():
246169 logger .info ("Browser context closed successfully" )
247170 except Exception as e :
248171 logger .error (f"Error closing browser: { str (e )} " )
249-
172+
250173 uvicorn .run (starlette_app , host = "0.0.0.0" , port = port )
251174 else :
252175 from mcp .server .stdio import stdio_server
253-
176+
254177 async def arun ():
255178 try :
256179 # Start the cleanup task now that we have an event loop
257- if hasattr (app , ' cleanup_old_tasks' ):
180+ if hasattr (app , " cleanup_old_tasks" ):
258181 asyncio .create_task (app .cleanup_old_tasks ())
259182 logger .info ("Task cleanup process scheduled" )
260-
183+
261184 async with stdio_server () as streams :
262185 await app .run (
263186 streams [0 ], streams [1 ], app .create_initialization_options ()
@@ -270,9 +193,9 @@ async def arun():
270193 await context .browser .close ()
271194 except Exception as e :
272195 logger .error (f"Error cleaning up resources: { str (e )} " )
273-
196+
274197 anyio .run (arun )
275-
198+
276199 return 0
277200
278201
0 commit comments