From 98de525b9d6bec4be1f620c2326e5e4df0995d91 Mon Sep 17 00:00:00 2001 From: Will-hxw Date: Wed, 29 Apr 2026 09:12:20 +0800 Subject: [PATCH 1/4] fix(docs): sort tools by required args in tool reference Issue #1932: Tools within each category should be sorted with no-arg tools first, followed by tools with required args, then tools with only optional args. This matches the requested ordering in the issue. Updated both the TOC generation (generateToolsTOC) and the main reference generation (generateReference) to use the new sort order. Co-Authored-By: Claude Opus 4.7 --- scripts/generate-docs.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/scripts/generate-docs.ts b/scripts/generate-docs.ts index 4be8fcbd7..cf3f107db 100644 --- a/scripts/generate-docs.ts +++ b/scripts/generate-docs.ts @@ -141,8 +141,14 @@ function generateToolsTOC( const categoryName = labels[category]; toc += `- **${categoryName}** (${categoryTools.length} tools)\n`; - // Sort tools within category for TOC - categoryTools.sort((a: Tool, b: Tool) => a.name.localeCompare(b.name)); + // Sort tools within category for TOC: no-arg tools first, then with args + categoryTools.sort((a: Tool, b: Tool) => { + const aHasRequired = a.inputSchema?.required?.length ?? 0 > 0; + const bHasRequired = b.inputSchema?.required?.length ?? 0 > 0; + if (!aHasRequired && bHasRequired) return -1; + if (aHasRequired && !bHasRequired) return 1; + return a.name.localeCompare(b.name); + }); for (const tool of categoryTools) { const anchorLink = tool.name.toLowerCase(); toc += ` - [\`${tool.name}\`](docs/tool-reference.md#${anchorLink})\n`; @@ -361,8 +367,14 @@ async function generateReference( markdown += `> NOTE: ${categoryName} are not active by default. Use the '${flagName}' flag\n\n`; } - // Sort tools within category - categoryTools.sort((a: Tool, b: Tool) => a.name.localeCompare(b.name)); + // Sort tools within category: no-arg tools first, then tools with required args, then optional-arg tools + categoryTools.sort((a: Tool, b: Tool) => { + const aHasRequired = a.inputSchema?.required?.length ?? 0 > 0; + const bHasRequired = b.inputSchema?.required?.length ?? 0 > 0; + if (!aHasRequired && bHasRequired) return -1; + if (aHasRequired && !bHasRequired) return 1; + return a.name.localeCompare(b.name); + }); for (const tool of categoryTools) { markdown += `### \`${tool.name}\`\n\n`; From 6629adde446fdf4c1818356d2a14d488b9f59f0b Mon Sep 17 00:00:00 2001 From: Will-hxw Date: Wed, 29 Apr 2026 09:37:05 +0800 Subject: [PATCH 2/4] docs(input): clarify click tool limitations for select/combobox Issue #1941: The click tool description did not make clear that for dropdowns or comboboxes, use the 'fill' tool instead to select options directly.`, annotations: { category: ToolCategory.INPUT, readOnlyHint: false, From a220dbc8830c24e3ca754f1f8773973830f1ddb3 Mon Sep 17 00:00:00 2001 From: Will-hxw Date: Wed, 29 Apr 2026 09:51:13 +0800 Subject: [PATCH 3/4] feat(chrome-devtools-mcp): add limit and query params to list_pages Add limit and query parameters to list_pages tool to address Issue #1921. When many browser tabs are open, listing all pages can cause token budget issues and browser hangs. These parameters allow truncating and filtering the page list: - limit: maximum number of pages to return - query: filter pages by URL containing the query string The URL dump in McpResponse.build() now respects these options and shows a note when pages are truncated (e.g., 'showing 10 of 50'). --- src/McpResponse.ts | 26 ++++++++++++++++++++++++-- src/tools/pages.ts | 16 ++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/McpResponse.ts b/src/McpResponse.ts index a5153d401..5b7f67c29 100644 --- a/src/McpResponse.ts +++ b/src/McpResponse.ts @@ -202,11 +202,18 @@ export class McpResponse implements Response { #args: ParsedArguments; #page?: McpPage; #redactNetworkHeaders = true; + #pageLimit?: number; + #pageQuery?: string; constructor(args: ParsedArguments) { this.#args = args; } + setPageListOptions(limit?: number, query?: string): void { + this.#pageLimit = limit; + this.#pageQuery = query; + } + setPage(page: McpPage): void { this.#page = page; } @@ -790,9 +797,24 @@ Call ${handleDialog.name} to handle it before continuing.`); ); if (regularPages.length) { - const parts = [`## Pages`]; + // Apply query filter if specified + let filteredPages = regularPages; + if (this.#pageQuery) { + const queryLower = this.#pageQuery.toLowerCase(); + filteredPages = regularPages.filter(page => + page.url().toLowerCase().includes(queryLower), + ); + } + + // Apply limit if specified + const displayPages = this.#pageLimit + ? filteredPages.slice(0, this.#pageLimit) + : filteredPages; + const hasMore = filteredPages.length > displayPages.length; + + const parts = [`## Pages${hasMore ? ` (showing ${displayPages.length} of ${filteredPages.length})` : ''}`]; const structuredPages = []; - for (const page of regularPages) { + for (const page of displayPages) { const isolatedContextName = context.getIsolatedContextName(page); const contextLabel = isolatedContextName ? ` isolatedContext=${isolatedContextName}` diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 92fe6afcd..5d243316f 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -83,11 +83,23 @@ export const listPages = defineTool(args => { category: ToolCategory.NAVIGATION, readOnlyHint: true, }, - schema: {}, - handler: async (_request, response) => { + schema: { + limit: zod + .number() + .optional() + .describe('Maximum number of pages to return.'), + query: zod + .string() + .optional() + .describe('Filter pages by URL containing this query string.'), + }, + handler: async (request, response) => { response.setIncludePages(true); response.setListInPageTools(); response.setListWebMcpTools(); + if (request.params.limit || request.params.query) { + response.setPageListOptions(request.params.limit, request.params.query); + } }, }; }); From 482e6e8f98fa79c055f3a59fee1b234f2329b19d Mon Sep 17 00:00:00 2001 From: Will-hxw Date: Wed, 29 Apr 2026 10:40:18 +0800 Subject: [PATCH 4/4] fix(check): respect user's npm registry configuration Use npm_config_registry env var if set, falling back to the public registry only if no custom registry is configured. This allows corporate proxy and private registry users to avoid blocked requests. Fixes #1943 --- src/bin/check-latest-version.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin/check-latest-version.ts b/src/bin/check-latest-version.ts index eb45674df..f8f0c652d 100644 --- a/src/bin/check-latest-version.ts +++ b/src/bin/check-latest-version.ts @@ -12,8 +12,9 @@ const cachePath = process.argv[2]; if (cachePath) { try { + const registry = process.env.npm_config_registry?.replace(/\/$/, '') || 'https://registry.npmjs.org'; const response = await fetch( - 'https://registry.npmjs.org/chrome-devtools-mcp/latest', + `${registry}/chrome-devtools-mcp/latest`, ); const data = response.ok ? await response.json() : null;