From aa2a4c24415c817d0871f30d3e2afb4579e3ea51 Mon Sep 17 00:00:00 2001 From: serhiizghama Date: Tue, 2 Jun 2026 03:26:58 +0700 Subject: [PATCH] feat: include page title in list_pages output --- src/McpResponse.ts | 23 ++++++++++++++++------- tests/McpResponse.test.js.snapshot | 5 +++++ tests/tools/pages.test.js.snapshot | 12 ++++++------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/McpResponse.ts b/src/McpResponse.ts index e8070737d..ec9973803 100644 --- a/src/McpResponse.ts +++ b/src/McpResponse.ts @@ -675,7 +675,7 @@ export class McpResponse implements Response { }); } - format( + async format( toolName: string, context: McpContext, data: { @@ -692,7 +692,7 @@ export class McpResponse implements Response { webmcpTools?: WebMCPTool[]; errorMessage?: string; }, - ): {content: Array; structuredContent: object} { + ): Promise<{content: Array; structuredContent: object}> { const structuredContent: { snapshot?: object; snapshotFilePath?: string; @@ -810,10 +810,12 @@ Call ${handleDialog.name} to handle it before continuing.`); const contextLabel = isolatedContextName ? ` isolatedContext=${isolatedContextName}` : ''; + const title = await page.title().catch(() => ''); + const pageLabel = title ? `${title} (${page.url()})` : page.url(); parts.push( - `${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`, + `${context.getPageId(page)}: ${pageLabel}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`, ); - structuredPages.push(createStructuredPage(page, context)); + structuredPages.push(await createStructuredPage(page, context)); } response.push(...parts); structuredContent.pages = structuredPages; @@ -828,10 +830,14 @@ Call ${handleDialog.name} to handle it before continuing.`); const contextLabel = isolatedContextName ? ` isolatedContext=${isolatedContextName}` : ''; + const title = await page.title().catch(() => ''); + const pageLabel = title ? `${title} (${page.url()})` : page.url(); response.push( - `${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`, + `${context.getPageId(page)}: ${pageLabel}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`, + ); + structuredExtensionPages.push( + await createStructuredPage(page, context), ); - structuredExtensionPages.push(createStructuredPage(page, context)); } structuredContent.extensionPages = structuredExtensionPages; } @@ -1157,16 +1163,19 @@ Call ${handleDialog.name} to handle it before continuing.`); this.#textResponseLines = []; } } -function createStructuredPage(page: Page, context: McpContext) { +async function createStructuredPage(page: Page, context: McpContext) { const isolatedContextName = context.getIsolatedContextName(page); + const title = await page.title().catch(() => ''); const entry: { id: number | undefined; url: string; + title: string; selected: boolean; isolatedContext?: string; } = { id: context.getPageId(page), url: page.url(), + title, selected: context.isPageSelected(page), }; if (isolatedContextName) { diff --git a/tests/McpResponse.test.js.snapshot b/tests/McpResponse.test.js.snapshot index 9b5597d12..ab7d0ae6a 100644 --- a/tests/McpResponse.test.js.snapshot +++ b/tests/McpResponse.test.js.snapshot @@ -324,6 +324,7 @@ exports[`McpResponse > list pages 2`] = ` { "id": 1, "url": "about:blank", + "title": "", "selected": true } ] @@ -1295,6 +1296,7 @@ exports[`webmcp > includes webmcp tools in list_pages response 2`] = ` { "id": 1, "url": "about:blank", + "title": "", "selected": true } ], @@ -1323,6 +1325,7 @@ exports[`webmcp > includes webmcp tools in navigate_page response 2`] = ` { "id": 1, "url": "about:blank", + "title": "", "selected": true } ], @@ -1349,6 +1352,7 @@ exports[`webmcp > includes webmcp tools in select_page response 2`] = ` { "id": 1, "url": "about:blank", + "title": "", "selected": true } ], @@ -1375,6 +1379,7 @@ exports[`webmcp > list no webmcp tools if experimentalWebmcp is false 2`] = ` { "id": 1, "url": "about:blank", + "title": "", "selected": true } ] diff --git a/tests/tools/pages.test.js.snapshot b/tests/tools/pages.test.js.snapshot index 684f2e4e7..a60a614b2 100644 --- a/tests/tools/pages.test.js.snapshot +++ b/tests/tools/pages.test.js.snapshot @@ -1,5 +1,5 @@ exports[`pages > close_page > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"## Pages\\n1: about:blank [selected]"}],"structuredContent":{"pages":[{"id":1,"url":"about:blank","selected":true}]}} +{"content":[{"type":"text","text":"## Pages\\n1: about:blank [selected]"}],"structuredContent":{"pages":[{"id":1,"url":"about:blank","title":"","selected":true}]}} `; exports[`pages > list_pages > list pages for extension pages with --category-extensions 1`] = ` @@ -31,21 +31,21 @@ sw-1: chrome-extension:///sw.js `; exports[`pages > list_pages > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","selected":true}]}} +{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","title":"","selected":true}]}} `; exports[`pages > navigate_page > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"Successfully navigated to data:text/html,
Navigated
.\\n# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: data:text/html,
Navigated
[selected]"}],"structuredContent":{"message":"Successfully navigated to data:text/html,
Navigated
.","dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"data:text/html,
Navigated
","selected":true}]}} +{"content":[{"type":"text","text":"Successfully navigated to data:text/html,
Navigated
.\\n# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: data:text/html,
Navigated
[selected]"}],"structuredContent":{"message":"Successfully navigated to data:text/html,
Navigated
.","dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"data:text/html,
Navigated
","title":"","selected":true}]}} `; exports[`pages > new_page with isolatedContext > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank\\n2: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","selected":false},{"id":2,"url":"about:blank","selected":true}]}} +{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank\\n2: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","title":"","selected":false},{"id":2,"url":"about:blank","title":"","selected":true}]}} `; exports[`pages > resize > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","selected":true}]}} +{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","title":"","selected":true}]}} `; exports[`pages > select_page > when dialog is open 1`] = ` -{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","selected":true}]}} +{"content":[{"type":"text","text":"# Open dialog\\nalert: test dialog.\\nCall handle_dialog to handle it before continuing.\\n## Pages\\n1: about:blank [selected]"}],"structuredContent":{"dialog":{"type":"alert","message":"test dialog","defaultValue":""},"pages":[{"id":1,"url":"about:blank","title":"","selected":true}]}} `;