豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 2664455

Browse files
atian8179Piotr Paulski
andauthored
fix: list_pages should work after selected page is closed (#1145)
## Problem After closing the currently selected page, calling `list_pages` throws an error: ``` The selected page has been closed. Call list_pages to see open pages. ``` This creates a deadlock: the error message tells users to call `list_pages`, but `list_pages` itself throws the same error. ## Root Cause `list_pages` is defined with `definePageTool`, which marks it as `pageScoped: true`. The handler dispatch in `index.ts` (line ~186) calls `context.getSelectedMcpPage()` for all page-scoped tools **before** invoking the handler. When the selected page is closed, `getSelectedPptrPage()` throws. However, `list_pages` doesn't actually use the `page` parameter — its handler only calls `response.setIncludePages(true)`. ## Fix Change `list_pages` from `definePageTool` to `defineTool`. This bypasses the page-scoped check while preserving all existing behavior since the handler never used the page reference. ## Testing Reproduced the issue following the steps in #1138: 1. Call `list_pages` → returns page list ✅ 2. Close the selected page 3. Call `list_pages` → now returns updated page list instead of throwing ✅ Fixes #1138 --------- Co-authored-by: Piotr Paulski <piotrpaulski@chromium.org>
1 parent 0a7c0a7 commit 2664455

File tree

2 files changed

+19
-21
lines changed

2 files changed

+19
-21
lines changed

src/tools/pages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
timeoutSchema,
1717
} from './ToolDefinition.js';
1818

19-
export const listPages = definePageTool(args => {
19+
export const listPages = defineTool(args => {
2020
return {
2121
name: 'list_pages',
2222
description: `Get a list of pages ${args?.categoryExtensions ? 'including extension service workers' : ''} open in the browser.`,

tests/tools/pages.test.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,21 @@ describe('pages', () => {
4545
describe('list_pages', () => {
4646
it('list pages', async () => {
4747
await withMcpContext(async (response, context) => {
48-
await listPages().handler(
49-
{params: {}, page: context.getSelectedMcpPage()},
50-
response,
51-
context,
52-
);
48+
await listPages().handler({params: {}}, response, context);
49+
assert.ok(response.includePages);
50+
});
51+
});
52+
it('list pages after selected page is closed', async () => {
53+
await withMcpContext(async (response, context) => {
54+
// Create a second page and select it.
55+
const page2 = await context.newPage();
56+
assert.strictEqual(context.getSelectedMcpPage(), page2);
57+
58+
// Close the selected page via puppeteer (simulating external close).
59+
await page2.pptrPage.close();
60+
61+
// list_pages should still work even though the selected page is gone.
62+
await listPages().handler({params: {}}, response, context);
5363
assert.ok(response.includePages);
5464
});
5565
});
@@ -70,11 +80,7 @@ describe('pages', () => {
7080
const listPageDef = listPages({
7181
categoryExtensions: true,
7282
} as ParsedArguments);
73-
await listPageDef.handler(
74-
{params: {}, page: context.getSelectedMcpPage()},
75-
response,
76-
context,
77-
);
83+
await listPageDef.handler({params: {}}, response, context);
7884

7985
const result = await response.handle(listPageDef.name, context);
8086
const textContent = result.content.find(c => c.type === 'text') as {
@@ -116,11 +122,7 @@ describe('pages', () => {
116122
const listPageDef = listPages({
117123
categoryExtensions,
118124
} as ParsedArguments);
119-
await listPageDef.handler(
120-
{params: {}, page: context.getSelectedMcpPage()},
121-
response,
122-
context,
123-
);
125+
await listPageDef.handler({params: {}}, response, context);
124126

125127
const result = await response.handle(listPageDef.name, context);
126128
const textContent = result.content.find(c => c.type === 'text') as {
@@ -177,11 +179,7 @@ describe('pages', () => {
177179
const listPageDef = listPages({
178180
categoryExtensions: true,
179181
} as ParsedArguments);
180-
await listPageDef.handler(
181-
{params: {}, page: context.getSelectedMcpPage()},
182-
response,
183-
context,
184-
);
182+
await listPageDef.handler({params: {}}, response, context);
185183

186184
const result = await response.handle(listPageDef.name, context);
187185
const textContent = result.content.find(c => c.type === 'text') as {

0 commit comments

Comments
 (0)