opera-devtools-mcp 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -205,15 +205,21 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
|
|
|
205
205
|
- [`get_heapsnapshot_retainers`](docs/tool-reference.md#get_heapsnapshot_retainers)
|
|
206
206
|
- [`get_heapsnapshot_retaining_paths`](docs/tool-reference.md#get_heapsnapshot_retaining_paths)
|
|
207
207
|
- [`get_heapsnapshot_summary`](docs/tool-reference.md#get_heapsnapshot_summary)
|
|
208
|
-
- **Opera** (
|
|
208
|
+
- **Opera** (14 tools)
|
|
209
|
+
- [`opera_authenticate_mcp_server`](docs/tool-reference.md#opera_authenticate_mcp_server)
|
|
209
210
|
- [`opera_call_mcp_tool`](docs/tool-reference.md#opera_call_mcp_tool)
|
|
210
211
|
- [`opera_chat`](docs/tool-reference.md#opera_chat)
|
|
212
|
+
- [`opera_connect_mcp_server`](docs/tool-reference.md#opera_connect_mcp_server)
|
|
213
|
+
- [`opera_disable_mcp_server`](docs/tool-reference.md#opera_disable_mcp_server)
|
|
211
214
|
- [`opera_do`](docs/tool-reference.md#opera_do)
|
|
215
|
+
- [`opera_enable_mcp_server`](docs/tool-reference.md#opera_enable_mcp_server)
|
|
212
216
|
- [`opera_list_mcp_servers`](docs/tool-reference.md#opera_list_mcp_servers)
|
|
213
217
|
- [`opera_list_mcp_tools`](docs/tool-reference.md#opera_list_mcp_tools)
|
|
214
218
|
- [`opera_list_models`](docs/tool-reference.md#opera_list_models)
|
|
215
219
|
- [`opera_make`](docs/tool-reference.md#opera_make)
|
|
220
|
+
- [`opera_register_mcp_server`](docs/tool-reference.md#opera_register_mcp_server)
|
|
216
221
|
- [`opera_research`](docs/tool-reference.md#opera_research)
|
|
222
|
+
- [`opera_unregister_mcp_server`](docs/tool-reference.md#opera_unregister_mcp_server)
|
|
217
223
|
- **Extensions** (5 tools)
|
|
218
224
|
- [`install_extension`](docs/tool-reference.md#install_extension)
|
|
219
225
|
- [`list_extensions`](docs/tool-reference.md#list_extensions)
|
|
@@ -898,6 +898,18 @@ export const commands = {
|
|
|
898
898
|
},
|
|
899
899
|
},
|
|
900
900
|
},
|
|
901
|
+
opera_authenticate_mcp_server: {
|
|
902
|
+
description: 'Complete OAuth sign-in for an MCP server that requires authentication. Opens a browser popup for the OAuth flow; requires a headed (visible) browser. Only available when connected to Opera Neon.',
|
|
903
|
+
category: 'Opera',
|
|
904
|
+
args: {
|
|
905
|
+
server: {
|
|
906
|
+
name: 'server',
|
|
907
|
+
type: 'string',
|
|
908
|
+
description: 'The MCP server name to authenticate.',
|
|
909
|
+
required: true,
|
|
910
|
+
},
|
|
911
|
+
},
|
|
912
|
+
},
|
|
901
913
|
opera_call_mcp_tool: {
|
|
902
914
|
description: 'Execute a tool on a specific MCP server registered in the browser. Use opera_list_mcp_servers to discover available servers and tools. Only available when connected to Opera Neon.',
|
|
903
915
|
category: 'Opera',
|
|
@@ -940,6 +952,30 @@ export const commands = {
|
|
|
940
952
|
},
|
|
941
953
|
},
|
|
942
954
|
},
|
|
955
|
+
opera_connect_mcp_server: {
|
|
956
|
+
description: 'Connect to a registered MCP server. If the server requires OAuth, the response includes requiresAuth: "needed" — follow with opera_authenticate_mcp_server. Only available when connected to Opera Neon.',
|
|
957
|
+
category: 'Opera',
|
|
958
|
+
args: {
|
|
959
|
+
server: {
|
|
960
|
+
name: 'server',
|
|
961
|
+
type: 'string',
|
|
962
|
+
description: 'The MCP server name to connect.',
|
|
963
|
+
required: true,
|
|
964
|
+
},
|
|
965
|
+
},
|
|
966
|
+
},
|
|
967
|
+
opera_disable_mcp_server: {
|
|
968
|
+
description: 'Disable an MCP server without unregistering it. Only available when connected to Opera Neon.',
|
|
969
|
+
category: 'Opera',
|
|
970
|
+
args: {
|
|
971
|
+
server: {
|
|
972
|
+
name: 'server',
|
|
973
|
+
type: 'string',
|
|
974
|
+
description: 'The MCP server name to disable.',
|
|
975
|
+
required: true,
|
|
976
|
+
},
|
|
977
|
+
},
|
|
978
|
+
},
|
|
943
979
|
opera_do: {
|
|
944
980
|
description: "Instruct Opera's built-in AI to perform an action on the current page and return the result. Only available when connected to Opera Neon.",
|
|
945
981
|
category: 'Opera',
|
|
@@ -952,6 +988,18 @@ export const commands = {
|
|
|
952
988
|
},
|
|
953
989
|
},
|
|
954
990
|
},
|
|
991
|
+
opera_enable_mcp_server: {
|
|
992
|
+
description: 'Enable a disabled MCP server. Only available when connected to Opera Neon.',
|
|
993
|
+
category: 'Opera',
|
|
994
|
+
args: {
|
|
995
|
+
server: {
|
|
996
|
+
name: 'server',
|
|
997
|
+
type: 'string',
|
|
998
|
+
description: 'The MCP server name to enable.',
|
|
999
|
+
required: true,
|
|
1000
|
+
},
|
|
1001
|
+
},
|
|
1002
|
+
},
|
|
955
1003
|
opera_list_mcp_servers: {
|
|
956
1004
|
description: 'List MCP servers registered in the browser, including their connection status. Only available when connected to Opera Neon.',
|
|
957
1005
|
category: 'Opera',
|
|
@@ -986,6 +1034,24 @@ export const commands = {
|
|
|
986
1034
|
},
|
|
987
1035
|
},
|
|
988
1036
|
},
|
|
1037
|
+
opera_register_mcp_server: {
|
|
1038
|
+
description: 'Register an MCP server in the browser. Does not connect or authenticate — follow with opera_connect_mcp_server. Only available when connected to Opera Neon.',
|
|
1039
|
+
category: 'Opera',
|
|
1040
|
+
args: {
|
|
1041
|
+
server: {
|
|
1042
|
+
name: 'server',
|
|
1043
|
+
type: 'string',
|
|
1044
|
+
description: 'The MCP server name to register.',
|
|
1045
|
+
required: true,
|
|
1046
|
+
},
|
|
1047
|
+
url: {
|
|
1048
|
+
name: 'url',
|
|
1049
|
+
type: 'string',
|
|
1050
|
+
description: 'The HTTP URL of the MCP server.',
|
|
1051
|
+
required: true,
|
|
1052
|
+
},
|
|
1053
|
+
},
|
|
1054
|
+
},
|
|
989
1055
|
opera_research: {
|
|
990
1056
|
description: "Ask Opera's built-in AI to research a topic and return a summary. Only available when connected to Opera Neon.",
|
|
991
1057
|
category: 'Opera',
|
|
@@ -1005,6 +1071,18 @@ export const commands = {
|
|
|
1005
1071
|
},
|
|
1006
1072
|
},
|
|
1007
1073
|
},
|
|
1074
|
+
opera_unregister_mcp_server: {
|
|
1075
|
+
description: 'Remove a registered MCP server and its stored auth tokens. Only available when connected to Opera Neon.',
|
|
1076
|
+
category: 'Opera',
|
|
1077
|
+
args: {
|
|
1078
|
+
server: {
|
|
1079
|
+
name: 'server',
|
|
1080
|
+
type: 'string',
|
|
1081
|
+
description: 'The MCP server name to unregister.',
|
|
1082
|
+
required: true,
|
|
1083
|
+
},
|
|
1084
|
+
},
|
|
1085
|
+
},
|
|
1008
1086
|
performance_analyze_insight: {
|
|
1009
1087
|
description: 'Provides more detailed information on a specific Performance Insight of an insight set that was highlighted in the results of a trace recording.',
|
|
1010
1088
|
category: 'Performance',
|
|
@@ -73,7 +73,7 @@ export const operaChat = definePageTool({
|
|
|
73
73
|
.describe('Model ID to use for the chat. Omit to use the browser default. Use opera_list_models to discover available IDs.'),
|
|
74
74
|
},
|
|
75
75
|
handler: async (request, response) => {
|
|
76
|
-
//
|
|
76
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
77
77
|
const session = getCDPSession(request.page.pptrPage);
|
|
78
78
|
try {
|
|
79
79
|
const payload = {
|
|
@@ -106,7 +106,7 @@ export const operaDo = definePageTool({
|
|
|
106
106
|
.describe('The action to perform, described in natural language.'),
|
|
107
107
|
},
|
|
108
108
|
handler: async (request, response) => {
|
|
109
|
-
//
|
|
109
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
110
110
|
const session = getCDPSession(request.page.pptrPage);
|
|
111
111
|
try {
|
|
112
112
|
const result = await dispatchWithStreamedResponse(session, {
|
|
@@ -136,7 +136,7 @@ export const operaMake = definePageTool({
|
|
|
136
136
|
prompt: zod.string().describe('Description of what to create or generate.'),
|
|
137
137
|
},
|
|
138
138
|
handler: async (request, response) => {
|
|
139
|
-
//
|
|
139
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
140
140
|
const session = getCDPSession(request.page.pptrPage);
|
|
141
141
|
try {
|
|
142
142
|
const result = await dispatchAction(session, {
|
|
@@ -167,7 +167,7 @@ export const operaResearch = definePageTool({
|
|
|
167
167
|
.describe('Depth of research. "local" uses only on-page context, "one-minute" performs a quick web search, "deep" performs a thorough multi-source search.'),
|
|
168
168
|
},
|
|
169
169
|
handler: async (request, response) => {
|
|
170
|
-
//
|
|
170
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
171
171
|
const session = getCDPSession(request.page.pptrPage);
|
|
172
172
|
const payload = {
|
|
173
173
|
action: 'research',
|
|
@@ -199,7 +199,7 @@ export const operaListModels = definePageTool({
|
|
|
199
199
|
},
|
|
200
200
|
schema: {},
|
|
201
201
|
handler: async (request, response) => {
|
|
202
|
-
//
|
|
202
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
203
203
|
const session = getCDPSession(request.page.pptrPage);
|
|
204
204
|
try {
|
|
205
205
|
const result = await dispatchAction(session, { action: 'listModels' });
|
|
@@ -223,7 +223,7 @@ export const operaListMcpServers = definePageTool({
|
|
|
223
223
|
},
|
|
224
224
|
schema: {},
|
|
225
225
|
handler: async (request, response) => {
|
|
226
|
-
//
|
|
226
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
227
227
|
const session = getCDPSession(request.page.pptrPage);
|
|
228
228
|
try {
|
|
229
229
|
const result = await dispatchAction(session, {
|
|
@@ -255,7 +255,7 @@ export const operaListMcpTools = definePageTool({
|
|
|
255
255
|
.describe('The MCP server name (from opera_list_mcp_servers).'),
|
|
256
256
|
},
|
|
257
257
|
handler: async (request, response) => {
|
|
258
|
-
//
|
|
258
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
259
259
|
const session = getCDPSession(request.page.pptrPage);
|
|
260
260
|
try {
|
|
261
261
|
const result = await dispatchAction(session, {
|
|
@@ -297,7 +297,7 @@ export const operaCallMcpTool = definePageTool({
|
|
|
297
297
|
.describe('Parameters to pass to the tool. Omit if the tool takes none.'),
|
|
298
298
|
},
|
|
299
299
|
handler: async (request, response) => {
|
|
300
|
-
//
|
|
300
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
301
301
|
const session = getCDPSession(request.page.pptrPage);
|
|
302
302
|
try {
|
|
303
303
|
const payload = {
|
|
@@ -320,4 +320,182 @@ export const operaCallMcpTool = definePageTool({
|
|
|
320
320
|
}
|
|
321
321
|
},
|
|
322
322
|
});
|
|
323
|
+
export const operaRegisterMcpServer = definePageTool({
|
|
324
|
+
name: 'opera_register_mcp_server',
|
|
325
|
+
description: 'Register an MCP server in the browser. Does not connect or authenticate — ' +
|
|
326
|
+
'follow with opera_connect_mcp_server. Only available when connected to Opera Neon.',
|
|
327
|
+
blockedByDialog: false,
|
|
328
|
+
verifyFilesSchema: {},
|
|
329
|
+
annotations: {
|
|
330
|
+
category: ToolCategory.OPERA,
|
|
331
|
+
readOnlyHint: false,
|
|
332
|
+
},
|
|
333
|
+
schema: {
|
|
334
|
+
server: zod.string().min(1).describe('The MCP server name to register.'),
|
|
335
|
+
url: zod.string().min(1).describe('The HTTP URL of the MCP server.'),
|
|
336
|
+
},
|
|
337
|
+
handler: async (request, response) => {
|
|
338
|
+
// puppeteer's _client() is internal; cast to the shape getCDPSession needs
|
|
339
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
340
|
+
try {
|
|
341
|
+
const result = await dispatchAction(session, {
|
|
342
|
+
action: 'registerMcpServer',
|
|
343
|
+
type: 'REGISTER_SERVER',
|
|
344
|
+
server: request.params.server,
|
|
345
|
+
transportInfo: { type: 'http', url: request.params.url },
|
|
346
|
+
});
|
|
347
|
+
response.appendResponseLine(result);
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
response.appendResponseLine(`Opera.dispatchAction(registerMcpServer) failed with error: ${e.message}`);
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
export const operaConnectMcpServer = definePageTool({
|
|
355
|
+
name: 'opera_connect_mcp_server',
|
|
356
|
+
description: 'Connect to a registered MCP server. If the server requires OAuth, ' +
|
|
357
|
+
'the response includes requiresAuth: "needed" — follow with ' +
|
|
358
|
+
'opera_authenticate_mcp_server. Only available when connected to Opera Neon.',
|
|
359
|
+
blockedByDialog: false,
|
|
360
|
+
verifyFilesSchema: {},
|
|
361
|
+
annotations: {
|
|
362
|
+
category: ToolCategory.OPERA,
|
|
363
|
+
readOnlyHint: false,
|
|
364
|
+
},
|
|
365
|
+
schema: {
|
|
366
|
+
server: zod.string().min(1).describe('The MCP server name to connect.'),
|
|
367
|
+
},
|
|
368
|
+
handler: async (request, response) => {
|
|
369
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
370
|
+
try {
|
|
371
|
+
const result = await dispatchAction(session, {
|
|
372
|
+
action: 'connectMcpServer',
|
|
373
|
+
type: 'CONNECT_SERVER',
|
|
374
|
+
server: request.params.server,
|
|
375
|
+
});
|
|
376
|
+
response.appendResponseLine(result);
|
|
377
|
+
}
|
|
378
|
+
catch (e) {
|
|
379
|
+
response.appendResponseLine(`Opera.dispatchAction(connectMcpServer) failed with error: ${e.message}`);
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
export const operaAuthenticateMcpServer = definePageTool({
|
|
384
|
+
name: 'opera_authenticate_mcp_server',
|
|
385
|
+
description: 'Complete OAuth sign-in for an MCP server that requires authentication. ' +
|
|
386
|
+
'Opens a browser popup for the OAuth flow; requires a headed (visible) browser. ' +
|
|
387
|
+
'Only available when connected to Opera Neon.',
|
|
388
|
+
blockedByDialog: false,
|
|
389
|
+
verifyFilesSchema: {},
|
|
390
|
+
annotations: {
|
|
391
|
+
category: ToolCategory.OPERA,
|
|
392
|
+
readOnlyHint: false,
|
|
393
|
+
},
|
|
394
|
+
schema: {
|
|
395
|
+
server: zod
|
|
396
|
+
.string()
|
|
397
|
+
.min(1)
|
|
398
|
+
.describe('The MCP server name to authenticate.'),
|
|
399
|
+
},
|
|
400
|
+
handler: async (request, response) => {
|
|
401
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
402
|
+
try {
|
|
403
|
+
const result = await dispatchWithStreamedResponse(session, {
|
|
404
|
+
action: 'authenticateMcpServer',
|
|
405
|
+
type: 'AUTHENTICATE_SERVER',
|
|
406
|
+
server: request.params.server,
|
|
407
|
+
}, chunk => response.sendLog(chunk), request.signal);
|
|
408
|
+
response.appendResponseLine(result);
|
|
409
|
+
}
|
|
410
|
+
catch (e) {
|
|
411
|
+
if (e.name === 'AbortError') {
|
|
412
|
+
throw e;
|
|
413
|
+
}
|
|
414
|
+
response.appendResponseLine(`Opera.dispatchWithStreamedResponse(authenticateMcpServer) failed with error: ${e.message}`);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
export const operaUnregisterMcpServer = definePageTool({
|
|
419
|
+
name: 'opera_unregister_mcp_server',
|
|
420
|
+
description: 'Remove a registered MCP server and its stored auth tokens. ' +
|
|
421
|
+
'Only available when connected to Opera Neon.',
|
|
422
|
+
blockedByDialog: false,
|
|
423
|
+
verifyFilesSchema: {},
|
|
424
|
+
annotations: {
|
|
425
|
+
category: ToolCategory.OPERA,
|
|
426
|
+
readOnlyHint: false,
|
|
427
|
+
},
|
|
428
|
+
schema: {
|
|
429
|
+
server: zod.string().min(1).describe('The MCP server name to unregister.'),
|
|
430
|
+
},
|
|
431
|
+
handler: async (request, response) => {
|
|
432
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
433
|
+
try {
|
|
434
|
+
const result = await dispatchAction(session, {
|
|
435
|
+
action: 'unregisterMcpServer',
|
|
436
|
+
type: 'UNREGISTER_SERVER',
|
|
437
|
+
server: request.params.server,
|
|
438
|
+
});
|
|
439
|
+
response.appendResponseLine(result);
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
response.appendResponseLine(`Opera.dispatchAction(unregisterMcpServer) failed with error: ${e.message}`);
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
export const operaEnableMcpServer = definePageTool({
|
|
447
|
+
name: 'opera_enable_mcp_server',
|
|
448
|
+
description: 'Enable a disabled MCP server. Only available when connected to Opera Neon.',
|
|
449
|
+
blockedByDialog: false,
|
|
450
|
+
verifyFilesSchema: {},
|
|
451
|
+
annotations: {
|
|
452
|
+
category: ToolCategory.OPERA,
|
|
453
|
+
readOnlyHint: false,
|
|
454
|
+
},
|
|
455
|
+
schema: {
|
|
456
|
+
server: zod.string().min(1).describe('The MCP server name to enable.'),
|
|
457
|
+
},
|
|
458
|
+
handler: async (request, response) => {
|
|
459
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
460
|
+
try {
|
|
461
|
+
const result = await dispatchAction(session, {
|
|
462
|
+
action: 'enableMcpServer',
|
|
463
|
+
type: 'ENABLE_SERVER',
|
|
464
|
+
server: request.params.server,
|
|
465
|
+
});
|
|
466
|
+
response.appendResponseLine(result);
|
|
467
|
+
}
|
|
468
|
+
catch (e) {
|
|
469
|
+
response.appendResponseLine(`Opera.dispatchAction(enableMcpServer) failed with error: ${e.message}`);
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
});
|
|
473
|
+
export const operaDisableMcpServer = definePageTool({
|
|
474
|
+
name: 'opera_disable_mcp_server',
|
|
475
|
+
description: 'Disable an MCP server without unregistering it. ' +
|
|
476
|
+
'Only available when connected to Opera Neon.',
|
|
477
|
+
blockedByDialog: false,
|
|
478
|
+
verifyFilesSchema: {},
|
|
479
|
+
annotations: {
|
|
480
|
+
category: ToolCategory.OPERA,
|
|
481
|
+
readOnlyHint: false,
|
|
482
|
+
},
|
|
483
|
+
schema: {
|
|
484
|
+
server: zod.string().min(1).describe('The MCP server name to disable.'),
|
|
485
|
+
},
|
|
486
|
+
handler: async (request, response) => {
|
|
487
|
+
const session = getCDPSession(request.page.pptrPage);
|
|
488
|
+
try {
|
|
489
|
+
const result = await dispatchAction(session, {
|
|
490
|
+
action: 'disableMcpServer',
|
|
491
|
+
type: 'DISABLE_SERVER',
|
|
492
|
+
server: request.params.server,
|
|
493
|
+
});
|
|
494
|
+
response.appendResponseLine(result);
|
|
495
|
+
}
|
|
496
|
+
catch (e) {
|
|
497
|
+
response.appendResponseLine(`Opera.dispatchAction(disableMcpServer) failed with error: ${e.message}`);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
});
|
|
323
501
|
//# sourceMappingURL=opera.js.map
|
package/build/src/version.js
CHANGED