@@ -17,38 +17,45 @@ import fs from 'fs';
17
17
18
18
let browser : Browser | undefined ;
19
19
20
- const ignoredPrefixes = new Set ( [
21
- 'chrome://' ,
22
- 'chrome-extension ://' ,
23
- 'chrome-untrusted ://' ,
24
- 'devtools ://',
25
- ] ) ;
20
+ function makeTargetFilter ( devtools : boolean ) {
21
+ const ignoredPrefixes = new Set ( [
22
+ 'chrome://' ,
23
+ 'chrome-extension ://' ,
24
+ 'chrome-untrusted ://',
25
+ ] ) ;
26
26
27
- function targetFilter ( target : Target ) : boolean {
28
- if ( target . url ( ) === 'chrome://newtab/' ) {
29
- return true ;
27
+ if ( ! devtools ) {
28
+ ignoredPrefixes . add ( 'devtools://' ) ;
30
29
}
31
- for ( const prefix of ignoredPrefixes ) {
32
- if ( target . url ( ) . startsWith ( prefix ) ) {
33
- return false ;
30
+ return function targetFilter ( target : Target ) : boolean {
31
+ if ( target . url ( ) === 'chrome://newtab/' ) {
32
+ return true ;
34
33
}
35
- }
36
- return true ;
34
+ for ( const prefix of ignoredPrefixes ) {
35
+ if ( target . url ( ) . startsWith ( prefix ) ) {
36
+ return false ;
37
+ }
38
+ }
39
+ return true ;
40
+ } ;
37
41
}
38
42
39
43
const connectOptions : ConnectOptions = {
40
- targetFilter,
41
44
// We do not expect any single CDP command to take more than 10sec.
42
45
protocolTimeout : 10_000 ,
43
46
} ;
44
47
45
- async function ensureBrowserConnected ( browserURL : string ) {
48
+ async function ensureBrowserConnected ( options : {
49
+ browserURL : string ;
50
+ devtools : boolean ;
51
+ } ) {
46
52
if ( browser ?. connected ) {
47
53
return browser ;
48
54
}
49
55
browser = await puppeteer . connect ( {
50
56
...connectOptions ,
51
- browserURL,
57
+ targetFilter : makeTargetFilter ( options . devtools ) ,
58
+ browserURL : options . browserURL ,
52
59
defaultViewport : null ,
53
60
} ) ;
54
61
return browser ;
@@ -61,6 +68,7 @@ type McpLaunchOptions = {
61
68
userDataDir ?: string ;
62
69
headless : boolean ;
63
70
isolated : boolean ;
71
+ devtools : boolean ;
64
72
} ;
65
73
66
74
export async function launch ( options : McpLaunchOptions ) : Promise < Browser > {
@@ -91,6 +99,9 @@ export async function launch(options: McpLaunchOptions): Promise<Browser> {
91
99
if ( customDevTools ) {
92
100
args . push ( `--custom-devtools-frontend=file://${ customDevTools } ` ) ;
93
101
}
102
+ if ( options . devtools ) {
103
+ args . push ( '--auto-open-devtools-for-tabs' ) ;
104
+ }
94
105
let puppeterChannel : ChromeReleaseChannel | undefined ;
95
106
if ( ! executablePath ) {
96
107
puppeterChannel =
@@ -102,6 +113,7 @@ export async function launch(options: McpLaunchOptions): Promise<Browser> {
102
113
try {
103
114
return await puppeteer . launch ( {
104
115
...connectOptions ,
116
+ targetFilter : makeTargetFilter ( options . devtools ) ,
105
117
channel : puppeterChannel ,
106
118
executablePath,
107
119
defaultViewport : null ,
@@ -138,16 +150,16 @@ async function ensureBrowserLaunched(
138
150
return browser ;
139
151
}
140
152
141
- export async function resolveBrowser ( options : {
142
- browserUrl ?: string ;
143
- executablePath ?: string ;
144
- customDevTools ?: string ;
145
- channel ?: Channel ;
146
- headless : boolean ;
147
- isolated : boolean ;
148
- } ) {
153
+ export async function resolveBrowser (
154
+ options : McpLaunchOptions & {
155
+ browserUrl ?: string ;
156
+ } ,
157
+ ) {
149
158
const browser = options . browserUrl
150
- ? await ensureBrowserConnected ( options . browserUrl )
159
+ ? await ensureBrowserConnected ( {
160
+ browserURL : options . browserUrl ,
161
+ devtools : options . devtools ,
162
+ } )
151
163
: await ensureBrowserLaunched ( options ) ;
152
164
153
165
return browser ;
0 commit comments