@@ -53,7 +53,7 @@ const stagehandConfig: ConstructorParams = {
53
53
debugDom : true /* Enable DOM debugging features */ ,
54
54
headless : false /* Run browser in headless mode */ ,
55
55
logger : ( message : LogLine ) =>
56
- console . log ( logLineToString ( message ) ) /* Custom logging function */ ,
56
+ console . error ( logLineToString ( message ) ) /* Custom logging function to stderr */ ,
57
57
domSettleTimeoutMs : 30_000 /* Timeout for DOM to settle in milliseconds */ ,
58
58
browserbaseSessionCreateParams : {
59
59
projectId : process . env . BROWSERBASE_PROJECT_ID ! ,
@@ -209,50 +209,59 @@ const TOOLS: Tool[] = [
209
209
210
210
// Global state
211
211
let stagehand : Stagehand | undefined ;
212
+ let serverInstance : Server | undefined ;
212
213
const consoleLogs : string [ ] = [ ] ;
213
214
const operationLogs : string [ ] = [ ] ;
214
215
215
216
function log ( message : string , level : 'info' | 'error' | 'debug' = 'info' ) {
216
- const timestamp = new Date ( ) . toISOString ( ) ;
217
- const logMessage = `[${ timestamp } ] [${ level . toUpperCase ( ) } ] ${ message } ` ;
218
- operationLogs . push ( logMessage ) ;
217
+ // const timestamp = new Date().toISOString();
218
+ // const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
219
+ // operationLogs.push(logMessage);
219
220
220
- // Write to file
221
- fs . appendFileSync ( LOG_FILE , logMessage + '\n' ) ;
221
+ // // Write to file
222
+ // fs.appendFileSync(LOG_FILE, logMessage + '\n');
222
223
223
- // Console output if debug is enabled
224
- if ( process . env . DEBUG || level === 'error' ) {
225
- console . error ( logMessage ) ;
226
- }
224
+ // // Console output to stderr
225
+ // if (process.env.DEBUG || level === 'error') {
226
+ // console.error(logMessage);
227
+ // }
228
+
229
+ // // Send logging message to client for important events
230
+ // if (serverInstance && (level === 'info' || level === 'error')) {
231
+ // serverInstance.sendLoggingMessage({
232
+ // level: level,
233
+ // data: message,
234
+ // });
235
+ // }
227
236
}
228
237
229
238
function logRequest ( type : string , params : any ) {
230
- const requestLog = {
231
- timestamp : new Date ( ) . toISOString ( ) ,
232
- type,
233
- params,
234
- } ;
235
- log ( `REQUEST: ${ JSON . stringify ( requestLog , null , 2 ) } ` , 'debug' ) ;
239
+ // const requestLog = {
240
+ // timestamp: new Date().toISOString(),
241
+ // type,
242
+ // params,
243
+ // };
244
+ // log(`REQUEST: ${JSON.stringify(requestLog, null, 2)}`, 'debug');
236
245
}
237
246
238
247
function logResponse ( type : string , response : any ) {
239
- const responseLog = {
240
- timestamp : new Date ( ) . toISOString ( ) ,
241
- type,
242
- response,
243
- } ;
244
- log ( `RESPONSE: ${ JSON . stringify ( responseLog , null , 2 ) } ` , 'debug' ) ;
248
+ // const responseLog = {
249
+ // timestamp: new Date().toISOString(),
250
+ // type,
251
+ // response,
252
+ // };
253
+ // log(`RESPONSE: ${JSON.stringify(responseLog, null, 2)}`, 'debug');
245
254
}
246
255
247
256
// Ensure Stagehand is initialized
248
257
async function ensureStagehand ( ) {
249
- log ( "Ensuring Stagehand is initialized..." ) ;
258
+ // log("Ensuring Stagehand is initialized...");
250
259
if ( ! stagehand ) {
251
- log ( "Initializing Stagehand..." ) ;
260
+ // log("Initializing Stagehand...");
252
261
stagehand = new Stagehand ( stagehandConfig ) ;
253
- log ( "Running init()" ) ;
262
+ // log("Running init()");
254
263
await stagehand . init ( ) ;
255
- log ( "Stagehand initialized successfully" ) ;
264
+ // log("Stagehand initialized successfully");
256
265
}
257
266
return stagehand ;
258
267
}
@@ -277,7 +286,7 @@ function sanitizeMessage(message: any): string {
277
286
}
278
287
return JSON . stringify ( message ) ;
279
288
} catch ( error ) {
280
- log ( `Invalid message format: ${ error } ` , 'error' ) ;
289
+ // log(`Invalid message format: ${error}`, 'error');
281
290
return JSON . stringify ( {
282
291
jsonrpc : '2.0' ,
283
292
error : {
@@ -294,13 +303,13 @@ async function handleToolCall(
294
303
name : string ,
295
304
args : any
296
305
) : Promise < CallToolResult > {
297
- log ( `Handling tool call: ${ name } with args: ${ JSON . stringify ( args ) } ` ) ;
306
+ // log(`Handling tool call: ${name} with args: ${JSON.stringify(args)}`, 'info' );
298
307
299
308
try {
300
309
stagehand = await ensureStagehand ( ) ;
301
310
} catch ( error ) {
302
311
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
303
- log ( `Failed to initialize Stagehand: ${ errorMsg } ` , 'error' ) ;
312
+ // log(`Failed to initialize Stagehand: ${errorMsg}`, 'error');
304
313
return {
305
314
content : [
306
315
{
@@ -315,13 +324,17 @@ async function handleToolCall(
315
324
isError : true ,
316
325
} ;
317
326
}
327
+ // log(`Stagehand initialized successfully`);
328
+ // log(`name: ${name}`);
329
+ // log(`args: ${JSON.stringify(args)}`);
330
+
318
331
319
332
switch ( name ) {
320
333
case "stagehand_navigate" :
321
334
try {
322
- log ( `Navigating to URL: ${ args . url } ` ) ;
335
+ // log(`Navigating to URL: ${args.url}`, 'info' );
323
336
await stagehand . page . goto ( args . url ) ;
324
- log ( "Navigation successful" ) ;
337
+ // log("Navigation successful", 'info' );
325
338
return {
326
339
content : [
327
340
{
@@ -333,7 +346,7 @@ async function handleToolCall(
333
346
} ;
334
347
} catch ( error ) {
335
348
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
336
- log ( `Navigation failed: ${ errorMsg } ` ) ;
349
+ // log(`Navigation failed: ${errorMsg}`, 'error' );
337
350
return {
338
351
content : [
339
352
{
@@ -351,12 +364,12 @@ async function handleToolCall(
351
364
352
365
case "stagehand_act" :
353
366
try {
354
- log ( `Performing action: ${ args . action } ` ) ;
367
+ // log(`Performing action: ${args.action}`, 'info' );
355
368
await stagehand . page . act ( {
356
369
action : args . action ,
357
370
variables : args . variables ,
358
371
} ) ;
359
- log ( "Action completed successfully" ) ;
372
+ // log("Action completed successfully", 'info' );
360
373
return {
361
374
content : [
362
375
{
@@ -368,7 +381,7 @@ async function handleToolCall(
368
381
} ;
369
382
} catch ( error ) {
370
383
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
371
- log ( `Action failed: ${ errorMsg } ` ) ;
384
+ // log(`Action failed: ${errorMsg}`, 'error' );
372
385
return {
373
386
content : [
374
387
{
@@ -386,8 +399,8 @@ async function handleToolCall(
386
399
387
400
case "stagehand_extract" :
388
401
try {
389
- log ( `Extracting data with instruction: ${ args . instruction } ` ) ;
390
- log ( `Schema: ${ JSON . stringify ( args . schema ) } ` ) ;
402
+ // log(`Extracting data with instruction: ${args.instruction}`, 'info' );
403
+ // log(`Schema: ${JSON.stringify(args.schema)}`, 'debug' );
391
404
// Convert the JSON schema from args.schema to a zod schema
392
405
const zodSchema = jsonSchemaToZod ( args . schema ) as AnyZodObject ;
393
406
const data = await stagehand . extract ( {
@@ -398,7 +411,7 @@ async function handleToolCall(
398
411
throw new Error ( "Invalid extraction response format" ) ;
399
412
}
400
413
const extractedData = data . data ;
401
- log ( `Data extracted successfully: ${ JSON . stringify ( extractedData ) } ` ) ;
414
+ // log(`Data extracted successfully: ${JSON.stringify(extractedData)}`, 'info' );
402
415
return {
403
416
content : [
404
417
{
@@ -414,7 +427,7 @@ async function handleToolCall(
414
427
} ;
415
428
} catch ( error ) {
416
429
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
417
- log ( `Extraction failed: ${ errorMsg } ` ) ;
430
+ // log(`Extraction failed: ${errorMsg}`, 'error' );
418
431
return {
419
432
content : [
420
433
{
@@ -431,13 +444,13 @@ async function handleToolCall(
431
444
}
432
445
case "stagehand_observe" :
433
446
try {
434
- log ( `Starting observation with instruction: ${ args . instruction } ` ) ;
447
+ // log(`Starting observation with instruction: ${args.instruction}`, 'info' );
435
448
const observations = await stagehand . page . observe ( {
436
449
instruction : args . instruction ,
437
450
} ) ;
438
- log (
439
- `Observation completed successfully: ${ JSON . stringify ( observations ) } `
440
- ) ;
451
+ // log(
452
+ // `Observation completed successfully: ${JSON.stringify(observations)}`, 'info'
453
+ // );
441
454
return {
442
455
content : [
443
456
{
@@ -449,7 +462,7 @@ async function handleToolCall(
449
462
} ;
450
463
} catch ( error ) {
451
464
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
452
- log ( `Observation failed: ${ errorMsg } ` ) ;
465
+ // log(`Observation failed: ${errorMsg}`, 'error' );
453
466
return {
454
467
content : [
455
468
{
@@ -466,7 +479,7 @@ async function handleToolCall(
466
479
}
467
480
468
481
default:
469
- log ( `Unknown tool called: ${ name } ` ) ;
482
+ // log(`Unknown tool called: ${name}`, 'error' );
470
483
return {
471
484
content : [
472
485
{
@@ -497,6 +510,9 @@ const server = new Server(
497
510
}
498
511
) ;
499
512
513
+ // Store server instance for logging
514
+ serverInstance = server ;
515
+
500
516
// Setup request handlers
501
517
server . setRequestHandler ( ListToolsRequestSchema , async ( request ) => {
502
518
try {
@@ -507,7 +523,7 @@ server.setRequestHandler(ListToolsRequestSchema, async (request) => {
507
523
return JSON . parse ( sanitizedResponse ) ;
508
524
} catch ( error ) {
509
525
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
510
- log ( `ListTools handler error: ${ errorMsg } ` , 'error' ) ;
526
+ // log(`ListTools handler error: ${errorMsg}`, 'error');
511
527
return {
512
528
error : {
513
529
code : - 32603 ,
@@ -536,7 +552,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
536
552
return JSON . parse ( sanitizedResult ) ;
537
553
} catch ( error ) {
538
554
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
539
- log ( `CallTool handler error: ${ errorMsg } ` , 'error' ) ;
555
+ // log(`CallTool handler error: ${errorMsg}`, 'error');
540
556
return {
541
557
error : {
542
558
code : - 32603 ,
@@ -557,7 +573,7 @@ server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
557
573
return JSON . parse ( sanitizedResponse ) ;
558
574
} catch ( error ) {
559
575
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
560
- log ( `ListResources handler error: ${ errorMsg } ` , 'error' ) ;
576
+ // log(`ListResources handler error: ${errorMsg}`, 'error');
561
577
return {
562
578
error : {
563
579
code : - 32603 ,
@@ -577,7 +593,7 @@ server.setRequestHandler(ListResourceTemplatesRequestSchema, async (request) =>
577
593
return JSON . parse ( sanitizedResponse ) ;
578
594
} catch ( error ) {
579
595
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
580
- log ( `ListResourceTemplates handler error: ${ errorMsg } ` , 'error' ) ;
596
+ // log(`ListResourceTemplates handler error: ${errorMsg}`, 'error');
581
597
return {
582
598
error : {
583
599
code : - 32603 ,
@@ -589,14 +605,18 @@ server.setRequestHandler(ListResourceTemplatesRequestSchema, async (request) =>
589
605
590
606
// Run the server
591
607
async function runServer ( ) {
592
- log ( "Starting Stagehand MCP server..." , 'info' ) ;
608
+ // log("Starting Stagehand MCP server...", 'info');
593
609
const transport = new StdioServerTransport ( ) ;
594
610
await server . connect ( transport ) ;
595
- log ( "Server started successfully" , 'info' ) ;
611
+ // log("Server started successfully", 'info');
612
+ server . sendLoggingMessage ( {
613
+ level : "info" ,
614
+ data : "Stagehand MCP server is ready to accept requests" ,
615
+ } ) ;
596
616
}
597
617
598
618
runServer ( ) . catch ( ( error ) => {
599
619
const errorMsg = error instanceof Error ? error . message : String ( error ) ;
600
- log ( `Server error: ${ errorMsg } ` , 'error' ) ;
620
+ // log(`Server error: ${errorMsg}`, 'error');
601
621
console . error ( error ) ;
602
622
} ) ;
0 commit comments