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

Commit 8f3fcf6

Browse files
authored
chore: get tab ID tool (#756)
An experimental tools to allow interop with other CDP tooling.
1 parent e8c9192 commit 8f3fcf6

File tree

7 files changed

+81
-0
lines changed

7 files changed

+81
-0
lines changed

src/McpResponse.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,16 @@ export class McpResponse implements Response {
5757
includePreservedMessages?: boolean;
5858
};
5959
#devToolsData?: DevToolsData;
60+
#tabId?: string;
6061

6162
attachDevToolsData(data: DevToolsData): void {
6263
this.#devToolsData = data;
6364
}
6465

66+
setTabId(tabId: string): void {
67+
this.#tabId = tabId;
68+
}
69+
6570
setIncludePages(value: boolean): void {
6671
this.#includePages = value;
6772
}
@@ -398,8 +403,13 @@ Call ${handleDialog.name} to handle it before continuing.`);
398403
const structuredContent: {
399404
snapshot?: object;
400405
snapshotFilePath?: string;
406+
tabId?: string;
401407
} = {};
402408

409+
if (this.#tabId) {
410+
structuredContent.tabId = this.#tabId;
411+
}
412+
403413
if (data.snapshot) {
404414
if (typeof data.snapshot === 'string') {
405415
response.push(`Saved snapshot to ${data.snapshot}.`);

src/cli.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ export const cliOptions = {
168168
'Whether to include all kinds of pages such as webviews or background pages as pages.',
169169
hidden: true,
170170
},
171+
experimentalInteropTools: {
172+
type: 'boolean',
173+
describe: 'Whether to enable interoperability tools',
174+
hidden: true,
175+
},
171176
chromeArg: {
172177
type: 'array',
173178
describe:

src/main.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ function registerTool(tool: ToolDefinition): void {
139139
) {
140140
return;
141141
}
142+
if (
143+
tool.annotations.conditions?.includes('experimentalInteropTools') &&
144+
!args.experimentalInteropTools
145+
) {
146+
return;
147+
}
142148
server.registerTool(
143149
tool.name,
144150
{

src/tools/ToolDefinition.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export interface Response {
7777
attachConsoleMessage(msgid: number): void;
7878
// Allows re-using DevTools data queried by some tools.
7979
attachDevToolsData(data: DevToolsData): void;
80+
setTabId(tabId: string): void;
8081
}
8182

8283
/**

src/tools/pages.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,26 @@ export const handleDialog = defineTool({
269269
response.setIncludePages(true);
270270
},
271271
});
272+
273+
export const getTabId = defineTool({
274+
name: 'get_tab_id',
275+
description: `Get the tab ID of the page`,
276+
annotations: {
277+
category: ToolCategory.NAVIGATION,
278+
readOnlyHint: true,
279+
conditions: ['experimentalInteropTools'],
280+
},
281+
schema: {
282+
pageId: zod
283+
.number()
284+
.describe(
285+
`The ID of the page to get the tab ID for. Call ${listPages.name} to get available pages.`,
286+
),
287+
},
288+
handler: async (request, response, context) => {
289+
const page = context.getPageById(request.params.pageId);
290+
// @ts-expect-error _tabId is internal.
291+
const tabId = page._tabId;
292+
response.setTabId(tabId);
293+
},
294+
});

tests/index.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ describe('e2e', () => {
101101
if (maybeTool.annotations?.conditions?.includes('computerVision')) {
102102
continue;
103103
}
104+
if (
105+
maybeTool.annotations?.conditions?.includes(
106+
'experimentalInteropTools',
107+
)
108+
) {
109+
continue;
110+
}
104111
definedNames.push(maybeTool.name);
105112
}
106113
}
@@ -120,4 +127,15 @@ describe('e2e', () => {
120127
['--experimental-vision'],
121128
);
122129
});
130+
131+
it('has experimental interop tools', async () => {
132+
await withClient(
133+
async client => {
134+
const {tools} = await client.listTools();
135+
const getTabId = tools.find(t => t.name === 'get_tab_id');
136+
assert.ok(getTabId);
137+
},
138+
['--experimental-interop-tools'],
139+
);
140+
});
123141
});

tests/tools/pages.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
navigatePage,
1818
resizePage,
1919
handleDialog,
20+
getTabId,
2021
} from '../../src/tools/pages.js';
2122
import {withMcpContext} from '../utils.js';
2223

@@ -322,4 +323,21 @@ describe('pages', () => {
322323
});
323324
});
324325
});
326+
327+
describe('get_tab_id', () => {
328+
it('returns the tab id', async () => {
329+
await withMcpContext(async (response, context) => {
330+
const page = context.getSelectedPage();
331+
// @ts-expect-error _tabId is internal.
332+
assert.ok(typeof page._tabId === 'string');
333+
// @ts-expect-error _tabId is internal.
334+
page._tabId = 'test-tab-id';
335+
await getTabId.handler({params: {pageId: 1}}, response, context);
336+
const result = await response.handle('get_tab_id', context);
337+
// @ts-expect-error _tabId is internal.
338+
assert.strictEqual(result.structuredContent.tabId, 'test-tab-id');
339+
assert.deepStrictEqual(response.responseLines, []);
340+
});
341+
});
342+
});
325343
});

0 commit comments

Comments
 (0)