From 01be73897f1878babf219ad05aa5c3f47c622e42 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Mon, 25 May 2026 17:35:23 +0200 Subject: [PATCH 01/14] feat(mcp): add optional model param to opera_chat tool Co-authored-by: Cursor --- src/tools/opera.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/tools/opera.ts b/src/tools/opera.ts index d68f58f..18ce0bf 100644 --- a/src/tools/opera.ts +++ b/src/tools/opera.ts @@ -129,15 +129,25 @@ export const operaChat = definePageTool({ }, schema: { prompt: zod.string().describe('The prompt to send to Opera AI.'), + model: zod + .string() + .optional() + .describe( + 'Model ID to use for the chat. Omit to use the browser default. Use opera_list_models to discover available IDs.', + ), }, handler: async (request, response) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const session = getCDPSession(request.page.pptrPage as any); try { - const result = await dispatchAction(session, { + const payload: Record = { action: 'chat', prompt: request.params.prompt, - }); + }; + if (request.params.model !== undefined) { + payload['model'] = request.params.model; + } + const result = await dispatchAction(session, payload); response.appendResponseLine(result); } catch (e) { response.appendResponseLine( From c86f4dff5ae03b4474dea2ad588a6d69d3f19934 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Mon, 25 May 2026 17:36:57 +0200 Subject: [PATCH 02/14] feat(mcp): add opera_list_models tool Co-authored-by: Cursor --- src/tools/opera.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/tools/opera.ts b/src/tools/opera.ts index 18ce0bf..cca00c9 100644 --- a/src/tools/opera.ts +++ b/src/tools/opera.ts @@ -271,3 +271,27 @@ export const operaResearch = definePageTool({ } }, }); + +export const operaListModels = definePageTool({ + name: 'opera_list_models', + description: + 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default.', + blockedByDialog: false, + annotations: { + category: ToolCategory.OPERA, + readOnlyHint: true, + }, + schema: {}, + handler: async (request, response) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const session = getCDPSession(request.page.pptrPage as any); + try { + const result = await session.send('Opera.getAvailableModels'); + response.appendResponseLine(JSON.stringify(result)); + } catch (e) { + response.appendResponseLine( + `Opera.getAvailableModels failed with error: ${(e as Error).message}`, + ); + } + }, +}); From f7ae844355d37bed50e2c32276282378fdaa5439 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Mon, 25 May 2026 17:37:50 +0200 Subject: [PATCH 03/14] feat(mcp): update generated CLI options for model selector Co-authored-by: Cursor --- src/bin/chrome-devtools-cli-options.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/bin/chrome-devtools-cli-options.ts b/src/bin/chrome-devtools-cli-options.ts index 7ef2827..54537e3 100644 --- a/src/bin/chrome-devtools-cli-options.ts +++ b/src/bin/chrome-devtools-cli-options.ts @@ -477,6 +477,13 @@ export const commands: Commands = { description: 'The prompt to send to Opera AI.', required: true, }, + model: { + name: 'model', + type: 'string', + description: + 'Model ID to use for the chat. Omit to use the browser default. Use opera_list_models to discover available IDs.', + required: false, + }, }, }, opera_do: { @@ -492,6 +499,12 @@ export const commands: Commands = { }, }, }, + opera_list_models: { + description: + 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default.', + category: 'Opera', + args: {}, + }, opera_make: { description: "Ask Opera's built-in AI to create or generate content and return the result. Only available when connected to Opera Neon.", From 2d0b02f641b629fb554ad0b6a857d8f18186994a Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Mon, 25 May 2026 18:01:52 +0200 Subject: [PATCH 04/14] refactor(mcp): use dispatchAction for listModels instead of separate CDP method Co-authored-by: Cursor --- src/tools/opera.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/opera.ts b/src/tools/opera.ts index cca00c9..1a096ca 100644 --- a/src/tools/opera.ts +++ b/src/tools/opera.ts @@ -286,11 +286,11 @@ export const operaListModels = definePageTool({ // eslint-disable-next-line @typescript-eslint/no-explicit-any const session = getCDPSession(request.page.pptrPage as any); try { - const result = await session.send('Opera.getAvailableModels'); - response.appendResponseLine(JSON.stringify(result)); + const result = await dispatchAction(session, {action: 'listModels'}); + response.appendResponseLine(result); } catch (e) { response.appendResponseLine( - `Opera.getAvailableModels failed with error: ${(e as Error).message}`, + `Opera.dispatchAction(listModels) failed with error: ${(e as Error).message}`, ); } }, From 5e7aefa72fc836a85ab444de8a98fb4de5de31f1 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Tue, 26 May 2026 16:21:41 +0200 Subject: [PATCH 05/14] chore: bump version --- package-lock.json | 4 ++-- package.json | 2 +- src/version.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index abf0d4d..474c680 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "opera-devtools-mcp", - "version": "0.2.0", + "version": "0.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "opera-devtools-mcp", - "version": "0.2.0", + "version": "0.2.2", "license": "Apache-2.0", "bin": { "opera-devtools": "build/src/bin/opera-devtools.js", diff --git a/package.json b/package.json index e3468aa..f363f6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opera-devtools-mcp", - "version": "0.2.2", + "version": "0.2.3", "description": "MCP server for Opera DevTools", "type": "module", "bin": { diff --git a/src/version.ts b/src/version.ts index 629f09d..56c07d5 100644 --- a/src/version.ts +++ b/src/version.ts @@ -8,5 +8,5 @@ // If moved update release-please config // x-release-please-start-version -export const VERSION = '0.2.2'; +export const VERSION = '0.2.3'; // x-release-please-end From 1f2f9546fb782385d7465a3675a0d333b7c56e67 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Tue, 26 May 2026 17:45:36 +0200 Subject: [PATCH 06/14] chore: bump version to 0.2.3 in package-lock.json --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 474c680..5045bf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "opera-devtools-mcp", - "version": "0.2.2", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "opera-devtools-mcp", - "version": "0.2.2", + "version": "0.2.3", "license": "Apache-2.0", "bin": { "opera-devtools": "build/src/bin/opera-devtools.js", From dcb64bcc2e5e0f68b9210b378cd7eaa3902f5a2a Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Wed, 27 May 2026 12:02:54 +0200 Subject: [PATCH 07/14] chore: downgrade version to 0.2.2 in package.json, package-lock.json, and version.ts --- package-lock.json | 4 ++-- package.json | 2 +- src/version.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5045bf6..474c680 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "opera-devtools-mcp", - "version": "0.2.3", + "version": "0.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "opera-devtools-mcp", - "version": "0.2.3", + "version": "0.2.2", "license": "Apache-2.0", "bin": { "opera-devtools": "build/src/bin/opera-devtools.js", diff --git a/package.json b/package.json index f363f6e..e3468aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opera-devtools-mcp", - "version": "0.2.3", + "version": "0.2.2", "description": "MCP server for Opera DevTools", "type": "module", "bin": { diff --git a/src/version.ts b/src/version.ts index 56c07d5..629f09d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -8,5 +8,5 @@ // If moved update release-please config // x-release-please-start-version -export const VERSION = '0.2.3'; +export const VERSION = '0.2.2'; // x-release-please-end From cf45c92cb7dddb5dea1dacc894be0a684a620ac9 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 12:02:07 +0200 Subject: [PATCH 08/14] fix(opera): increase service worker retry delay from 1000ms to 2500ms --- src/tools/opera.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/opera.ts b/src/tools/opera.ts index 1a096ca..d1e0927 100644 --- a/src/tools/opera.ts +++ b/src/tools/opera.ts @@ -20,7 +20,7 @@ const getCDPSession = (page: {_client(): CDPSession}): CDPSession => page._client(); const MAX_SW_RETRIES = 5; -const SW_RETRY_DELAY_MS = 1000; +const SW_RETRY_DELAY_MS = 2500; const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); From 4655f823e1688148bfa01fb3a9a4f61378a441b9 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 12:34:48 +0200 Subject: [PATCH 09/14] feat(opera): add `opera_list_models` tool and update documentation - Introduced the `opera_list_models` tool to list available AI models for Opera chat. - Updated README and tool reference documentation to reflect the addition of the new tool and its parameters. - Added optional `model` parameter to the `opera_chat` tool documentation. --- README.md | 3 ++- docs/tool-reference.md | 12 +++++++++++- src/telemetry/tool_call_metrics.json | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9bcbd03..d151c00 100644 --- a/README.md +++ b/README.md @@ -197,9 +197,10 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles - [`get_memory_snapshot_details`](docs/tool-reference.md#get_memory_snapshot_details) - [`get_nodes_by_class`](docs/tool-reference.md#get_nodes_by_class) - [`load_memory_snapshot`](docs/tool-reference.md#load_memory_snapshot) -- **Opera** (4 tools) +- **Opera** (5 tools) - [`opera_chat`](docs/tool-reference.md#opera_chat) - [`opera_do`](docs/tool-reference.md#opera_do) + - [`opera_list_models`](docs/tool-reference.md#opera_list_models) - [`opera_make`](docs/tool-reference.md#opera_make) - [`opera_research`](docs/tool-reference.md#opera_research) - **Extensions** (5 tools) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 2985f4a..411a45d 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -44,9 +44,10 @@ - [`get_memory_snapshot_details`](#get_memory_snapshot_details) - [`get_nodes_by_class`](#get_nodes_by_class) - [`load_memory_snapshot`](#load_memory_snapshot) -- **[Opera](#opera)** (4 tools) +- **[Opera](#opera)** (5 tools) - [`opera_chat`](#opera_chat) - [`opera_do`](#opera_do) + - [`opera_list_models`](#opera_list_models) - [`opera_make`](#opera_make) - [`opera_research`](#opera_research) - **[Extensions](#extensions)** (5 tools) @@ -500,6 +501,7 @@ in the DevTools Elements panel (if any). **Parameters:** - **prompt** (string) **(required)**: The prompt to send to Opera AI. +- **model** (string) _(optional)_: Model ID to use for the chat. Omit to use the browser default. Use [`opera_list_models`](#opera_list_models) to discover available IDs. --- @@ -513,6 +515,14 @@ in the DevTools Elements panel (if any). --- +### `opera_list_models` + +**Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. + +**Parameters:** None + +--- + ### `opera_make` **Description:** Ask Opera's built-in AI to create or generate content and return the result. Only available when connected to Opera Neon. diff --git a/src/telemetry/tool_call_metrics.json b/src/telemetry/tool_call_metrics.json index be3e38a..2a1a53e 100644 --- a/src/telemetry/tool_call_metrics.json +++ b/src/telemetry/tool_call_metrics.json @@ -634,6 +634,10 @@ { "name": "prompt_length", "argType": "number" + }, + { + "name": "model_length", + "argType": "number" } ] }, @@ -667,5 +671,9 @@ "argType": "string" } ] + }, + { + "name": "opera_list_models", + "args": [] } ] From d4eb20fbeb07380b85ffe85c7c4fb35538b3d602 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 12:36:17 +0200 Subject: [PATCH 10/14] fix(opera): update description for `opera_list_models` tool to clarify availability - Enhanced the description of the `opera_list_models` tool to specify that it is only available when connected to Opera Neon. --- src/bin/chrome-devtools-cli-options.ts | 2 +- src/tools/opera.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/chrome-devtools-cli-options.ts b/src/bin/chrome-devtools-cli-options.ts index 54537e3..b57d58a 100644 --- a/src/bin/chrome-devtools-cli-options.ts +++ b/src/bin/chrome-devtools-cli-options.ts @@ -501,7 +501,7 @@ export const commands: Commands = { }, opera_list_models: { description: - 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default.', + 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon.', category: 'Opera', args: {}, }, diff --git a/src/tools/opera.ts b/src/tools/opera.ts index d1e0927..1b0a086 100644 --- a/src/tools/opera.ts +++ b/src/tools/opera.ts @@ -275,7 +275,7 @@ export const operaResearch = definePageTool({ export const operaListModels = definePageTool({ name: 'opera_list_models', description: - 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default.', + 'List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon.', blockedByDialog: false, annotations: { category: ToolCategory.OPERA, From 18698700a757ecf24fc7ef6daac4248a2a482ed4 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 13:56:27 +0200 Subject: [PATCH 11/14] fix(opera): correct description for `opera_list_models` tool to indicate availability with Opera Neon --- docs/tool-reference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 411a45d..d6370c4 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -517,7 +517,8 @@ in the DevTools Elements panel (if any). ### `opera_list_models` -**Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. +**Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon., + **Parameters:** None From 30c0972535ec527fa39074079acbceec2af591a9 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 14:00:20 +0200 Subject: [PATCH 12/14] fix(opera): remove unnecessary blank line in `opera_list_models` tool documentation --- docs/tool-reference.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index d6370c4..20a9975 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -519,7 +519,6 @@ in the DevTools Elements panel (if any). **Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon., - **Parameters:** None --- From de86728e4ac20de92ba23356faaadae6ed8417a2 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 14:03:42 +0200 Subject: [PATCH 13/14] fix(opera): remove trailing comma in `opera_list_models` tool documentation --- docs/tool-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 20a9975..b39949d 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -517,7 +517,7 @@ in the DevTools Elements panel (if any). ### `opera_list_models` -**Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon., +**Description:** List available AI models for Opera chat. Returns model IDs, display names, and which is the default. Only available when connected to Opera Neon. **Parameters:** None From f51161439a9807dfe1aba9410fd634eb59241cd4 Mon Sep 17 00:00:00 2001 From: Patryk Srednicki Date: Thu, 28 May 2026 14:26:38 +0200 Subject: [PATCH 14/14] chore(ci): add step to disable AppArmor in CI workflow --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3853ba..8481ae6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,4 +18,9 @@ jobs: cache: npm - run: npm ci + + - name: Disable AppArmor + shell: bash + run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns + - run: npm test