From 086bc1bf8b1041d3a7ca2e4f1d3aa44d41e149dc Mon Sep 17 00:00:00 2001 From: claude code agent 227 Date: Sat, 4 Jul 2026 18:08:27 +0300 Subject: [PATCH] docs(mcp): search_in_page regex desc names RE2, not JS regex (#330 review F5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RE2 swap narrowed the contract: regex:true rejects lookaround ((?=…)/(?<=…)) and backreferences (\1). The internal JSDoc was updated, but the AGENT-VISIBLE tool-spec (the only text the agent reads at call time, single-sourced to both transports) still said 'a JS regular expression' — so an agent would write a lookahead/backref and hit an error. Updated the .description and the regex flag .describe() to name RE2 (linear-time, ReDoS-safe), list that char classes / word boundaries / anchors / quantifiers work while lookaround and backreferences do NOT, and keep the 'invalid/unsupported regex -> clear error' note. mcp: tsc clean; tool-specs / server-instructions / contract tests green. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/mcp/build/tool-specs.js | 9 ++++++--- packages/mcp/src/tool-specs.ts | 11 ++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/mcp/build/tool-specs.js b/packages/mcp/build/tool-specs.js index 51ceb675..33319e18 100644 --- a/packages/mcp/build/tool-specs.js +++ b/packages/mcp/build/tool-specs.js @@ -93,8 +93,10 @@ export const SHARED_TOOL_SPECS = { 'that unique selection. `total` counts all ' + 'hits and `truncated` is true when more than `limit` were found (nothing ' + 'is silently dropped). Default is a literal, case-INSENSITIVE substring; ' + - 'set regex:true for a JS regular expression (char classes, word ' + - 'boundaries) and caseSensitive:true to match case. Ideal for systematic ' + + 'set regex:true for an RE2 regular expression (linear-time, ReDoS-safe: ' + + 'char classes, word boundaries, anchors and quantifiers work; lookaround ' + + '(?=…)/(?<=…) and backreferences \\1 are NOT supported) and ' + + 'caseSensitive:true to match case. Ideal for systematic ' + 'editorial sweeps (unquoted "ё", straight quotes, "т.е.", stray units). An ' + 'invalid regex or an empty query returns a clear error to fix.', buildShape: (z) => ({ @@ -106,7 +108,8 @@ export const SHARED_TOOL_SPECS = { regex: z .boolean() .optional() - .describe('Treat query as a JS regular expression (default false).'), + .describe('Treat query as an RE2 regular expression — linear-time, ReDoS-safe; ' + + 'no lookaround or backreferences (default false).'), caseSensitive: z .boolean() .optional() diff --git a/packages/mcp/src/tool-specs.ts b/packages/mcp/src/tool-specs.ts index 4f1187a3..79a2c066 100644 --- a/packages/mcp/src/tool-specs.ts +++ b/packages/mcp/src/tool-specs.ts @@ -131,8 +131,10 @@ export const SHARED_TOOL_SPECS = { 'that unique selection. `total` counts all ' + 'hits and `truncated` is true when more than `limit` were found (nothing ' + 'is silently dropped). Default is a literal, case-INSENSITIVE substring; ' + - 'set regex:true for a JS regular expression (char classes, word ' + - 'boundaries) and caseSensitive:true to match case. Ideal for systematic ' + + 'set regex:true for an RE2 regular expression (linear-time, ReDoS-safe: ' + + 'char classes, word boundaries, anchors and quantifiers work; lookaround ' + + '(?=…)/(?<=…) and backreferences \\1 are NOT supported) and ' + + 'caseSensitive:true to match case. Ideal for systematic ' + 'editorial sweeps (unquoted "ё", straight quotes, "т.е.", stray units). An ' + 'invalid regex or an empty query returns a clear error to fix.', buildShape: (z) => ({ @@ -144,7 +146,10 @@ export const SHARED_TOOL_SPECS = { regex: z .boolean() .optional() - .describe('Treat query as a JS regular expression (default false).'), + .describe( + 'Treat query as an RE2 regular expression — linear-time, ReDoS-safe; ' + + 'no lookaround or backreferences (default false).', + ), caseSensitive: z .boolean() .optional()