Skip to content

Commit 6d361a9

Browse files
committed
chore: py lint
1 parent 0505727 commit 6d361a9

File tree

3 files changed

+65
-52
lines changed

3 files changed

+65
-52
lines changed

src/browser_use_mcp_server/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
run_browser_task_async,
1212
check_browser_health,
1313
reset_browser_context,
14-
create_mcp_server
14+
create_mcp_server,
1515
)
1616

1717
__all__ = [
@@ -22,4 +22,4 @@
2222
"check_browser_health",
2323
"reset_browser_context",
2424
"create_mcp_server",
25-
]
25+
]

src/browser_use_mcp_server/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
from .cli import cli
77

88
if __name__ == "__main__":
9-
sys.exit(cli())
9+
sys.exit(cli())

src/browser_use_mcp_server/cli.py

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,25 @@
2929
logging.basicConfig(level=logging.INFO)
3030
logger = logging.getLogger(__name__)
3131

32+
3233
class AsyncStdinReader:
3334
"""Async wrapper for stdin."""
34-
35+
3536
async def receive(self) -> bytes:
3637
line = await asyncio.get_event_loop().run_in_executor(None, sys.stdin.readline)
3738
return line.encode()
3839

40+
3941
class AsyncStdoutWriter:
4042
"""Async wrapper for stdout."""
41-
43+
4244
async def send(self, data: bytes) -> None:
4345
text = data.decode()
4446
sys.stdout.write(text)
4547
sys.stdout.flush()
4648
await asyncio.sleep(0) # Yield control back to the event loop
4749

50+
4851
@click.group()
4952
def cli():
5053
"""Browser MCP Server CLI."""
@@ -100,9 +103,11 @@ def start(
100103
# Set up browser context and LLM
101104
if chrome_path is None:
102105
chrome_path = os.environ.get("CHROME_PATH")
103-
106+
104107
try:
105-
logger.info(f"Initializing browser context with Chrome path: {chrome_path or 'default'}")
108+
logger.info(
109+
f"Initializing browser context with Chrome path: {chrome_path or 'default'}"
110+
)
106111
context = initialize_browser_context(
107112
chrome_path=chrome_path,
108113
window_width=window_width,
@@ -112,15 +117,15 @@ def start(
112117
except Exception as e:
113118
logger.error(f"Failed to initialize browser context: {e}")
114119
return 1
115-
120+
116121
try:
117122
logger.info(f"Initializing LLM with model: {model}")
118123
llm = ChatOpenAI(model=model, temperature=0.0)
119124
logger.info("LLM initialized successfully")
120125
except Exception as e:
121126
logger.error(f"Failed to initialize LLM: {e}")
122127
return 1
123-
128+
124129
try:
125130
# Create MCP server
126131
logger.info("Creating MCP server")
@@ -134,70 +139,70 @@ def start(
134139
except Exception as e:
135140
logger.error(f"Failed to create MCP server: {e}")
136141
return 1
137-
142+
138143
if transport == "stdio":
139144
# Run the server with stdio transport
140145
logger.info("Starting browser MCP server with stdio transport")
141146
return asyncio.run(_run_stdio(app))
142-
147+
143148
else:
144149
# Set up Starlette app for SSE transport
145150
async def handle_sse(request):
146151
"""Handle SSE connections."""
147152
logger.info(f"New SSE connection from {request.client}")
148153
logger.info(f"Request headers: {request.headers}")
149-
154+
150155
# Create a queue for sending messages
151156
send_queue = asyncio.Queue()
152-
157+
153158
# Define message handlers for MCP server
154159
class SSEReadStream:
155160
async def __aenter__(self):
156161
return self
157-
162+
158163
async def __aexit__(self, exc_type, exc_val, exc_tb):
159164
pass
160-
165+
161166
async def receive(self) -> bytes:
162167
# For SSE, we don't receive anything from client
163168
# Just block indefinitely
164169
future = asyncio.Future()
165170
await future # This will block forever
166171
return b"" # Never reached
167-
172+
168173
class SSEWriteStream:
169174
async def __aenter__(self):
170175
return self
171-
176+
172177
async def __aexit__(self, exc_type, exc_val, exc_tb):
173178
pass
174-
179+
175180
async def send(self, data: bytes) -> None:
176181
# Queue the message to be sent over SSE
177182
await send_queue.put(data)
178-
183+
179184
# Create async generator to stream SSE responses
180185
async def stream_response():
181186
"""Stream SSE responses."""
182187
logger.info("Setting up SSE stream")
183-
188+
184189
# Start MCP server in background
185190
read_stream = SSEReadStream()
186191
write_stream = SSEWriteStream()
187-
192+
188193
server_task = asyncio.create_task(
189194
app.run(
190195
read_stream=read_stream,
191196
write_stream=write_stream,
192-
initialization_options={}
197+
initialization_options={},
193198
)
194199
)
195-
200+
196201
try:
197202
# Send initial connected event
198203
logger.info("Sending initial connected event")
199204
yield b"event: connected\ndata: {}\n\n"
200-
205+
201206
# Stream messages from the queue
202207
logger.info("Starting to stream messages")
203208
while True:
@@ -212,119 +217,126 @@ async def stream_response():
212217
# Clean up
213218
server_task.cancel()
214219
logger.info("SSE connection closed")
215-
220+
216221
return StreamingResponse(
217222
stream_response(),
218223
media_type="text/event-stream",
219224
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
220225
)
221-
226+
222227
async def health_check(request):
223228
"""Health check endpoint."""
224229
try:
225230
# Check browser health
226231
healthy = await check_browser_health(context)
227232
return JSONResponse({"status": "healthy" if healthy else "unhealthy"})
228233
except Exception as e:
229-
return JSONResponse({"status": "error", "message": str(e)}, status_code=500)
230-
234+
return JSONResponse(
235+
{"status": "error", "message": str(e)}, status_code=500
236+
)
237+
231238
async def reset_context(request):
232239
"""Reset browser context endpoint."""
233240
try:
234241
# Reset browser context
235242
await reset_browser_context(context)
236-
return JSONResponse({"status": "success", "message": "Browser context reset"})
243+
return JSONResponse(
244+
{"status": "success", "message": "Browser context reset"}
245+
)
237246
except Exception as e:
238-
return JSONResponse({"status": "error", "message": str(e)}, status_code=500)
239-
247+
return JSONResponse(
248+
{"status": "error", "message": str(e)}, status_code=500
249+
)
250+
240251
# Define startup and shutdown events
241252
async def startup_event():
242253
"""Run on server startup."""
243254
logger.info("Starting server...")
244-
255+
245256
# Start task cleanup job
246257
asyncio.create_task(cleanup_old_tasks())
247-
258+
248259
logger.info(f"Server started on port {port}")
249-
260+
250261
async def shutdown_event():
251262
"""Run on server shutdown."""
252263
logger.info("Shutting down server...")
253-
264+
254265
try:
255266
# Close the browser
256267
await context.browser.close()
257268
logger.info("Browser closed successfully")
258269
except Exception as e:
259270
logger.error(f"Error closing browser: {e}")
260-
271+
261272
logger.info("Server shut down")
262-
273+
263274
async def cleanup_old_tasks():
264275
"""Periodically clean up expired tasks."""
265276
from datetime import datetime
266-
277+
267278
while True:
268279
try:
269280
# Check for expired tasks every minute
270281
await asyncio.sleep(60)
271-
282+
272283
# Get current time
273284
now = datetime.now()
274-
285+
275286
# Check each task
276287
expired_tasks = []
277288
for task_id, task in task_store.items():
278289
if "expiry_time" in task:
279290
# Parse expiry time
280291
expiry_time = datetime.fromisoformat(task["expiry_time"])
281-
292+
282293
# Check if expired
283294
if now > expiry_time:
284295
expired_tasks.append(task_id)
285-
296+
286297
# Remove expired tasks
287298
for task_id in expired_tasks:
288299
logger.info(f"Removing expired task {task_id}")
289300
task_store.pop(task_id, None)
290-
301+
291302
except Exception as e:
292303
logger.error(f"Error cleaning up old tasks: {e}")
293-
304+
294305
# Create Starlette app with routes
295306
routes = [
296307
Route("/sse", endpoint=handle_sse, methods=["GET"]),
297308
Route("/health", endpoint=health_check, methods=["GET"]),
298309
Route("/reset", endpoint=reset_context, methods=["POST"]),
299310
]
300-
311+
301312
starlette_app = Starlette(
302313
routes=routes,
303314
on_startup=[startup_event],
304315
on_shutdown=[shutdown_event],
305-
debug=True
316+
debug=True,
306317
)
307-
318+
308319
# Run with uvicorn
309320
logger.info(f"Starting browser MCP server with SSE transport on port {port}")
310321
uvicorn.run(starlette_app, host="0.0.0.0", port=port)
311-
322+
312323
return 0
313324

325+
314326
async def _run_stdio(app: Server) -> int:
315327
"""Run the server using stdio transport."""
316328
try:
317329
stdin_reader = AsyncStdinReader()
318330
stdout_writer = AsyncStdoutWriter()
319-
331+
320332
# Create initialization options
321333
initialization_options = {}
322-
334+
323335
# Run the server
324336
await app.run(
325337
read_stream=stdin_reader,
326338
write_stream=stdout_writer,
327-
initialization_options=initialization_options
339+
initialization_options=initialization_options,
328340
)
329341
return 0
330342
except KeyboardInterrupt:
@@ -334,5 +346,6 @@ async def _run_stdio(app: Server) -> int:
334346
logger.error(f"Error running server: {e}")
335347
return 1
336348

349+
337350
if __name__ == "__main__":
338-
cli()
351+
cli()

0 commit comments

Comments
 (0)