2025-04-04 15:22:00 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
import { z } from 'zod' ;
2025-07-22 07:53:33 -07:00
import { defineTabTool } from './tool.js' ;
2025-07-16 16:40:00 -07:00
import { elementSchema } from './snapshot.js' ;
import { generateLocator } from './utils.js' ;
import * as javascript from '../javascript.js' ;
2025-07-22 07:53:33 -07:00
const pressKey = defineTabTool ( {
2025-04-04 17:14:30 -07:00
capability : 'core' ,
2025-04-16 19:36:48 -07:00
2025-04-04 15:22:00 -07:00
schema : {
name : 'browser_press_key' ,
2025-05-05 17:38:22 -07:00
title : 'Press a key' ,
feat: add snapshot size limits and optional snapshots to fix token overflow
Implements comprehensive solution for browser_click and other interactive tools
returning massive responses (37K+ tokens) due to full page snapshots.
Features implemented:
1. **Snapshot size limits** (--max-snapshot-tokens, default 10k)
- Automatically truncates large snapshots with helpful messages
- Preserves essential info (URL, title, errors) when truncating
- Shows exact token counts and configuration suggestions
2. **Optional snapshots** (--no-snapshots)
- Disables automatic snapshots after interactive operations
- browser_snapshot tool always works for explicit snapshots
- Maintains backward compatibility (snapshots enabled by default)
3. **Differential snapshots** (--differential-snapshots)
- Shows only changes since last snapshot instead of full page
- Tracks URL, title, DOM structure, and console activity
- Significantly reduces token usage for incremental operations
4. **Enhanced tool descriptions**
- All interactive tools now document snapshot behavior
- Clear guidance on when snapshots are included/excluded
- Helpful suggestions for users experiencing token limits
Configuration options:
- CLI: --no-snapshots, --max-snapshot-tokens N, --differential-snapshots
- ENV: PLAYWRIGHT_MCP_INCLUDE_SNAPSHOTS, PLAYWRIGHT_MCP_MAX_SNAPSHOT_TOKENS, etc.
- Config file: includeSnapshots, maxSnapshotTokens, differentialSnapshots
Fixes token overflow errors while providing users full control over
snapshot behavior and response sizes.
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 07:54:36 -06:00
description : 'Press a key on the keyboard. Returns page snapshot after keypress unless disabled with --no-snapshots.' ,
2025-04-22 13:24:38 +02:00
inputSchema : z.object ( {
key : z.string ( ) . describe ( 'Name of the key to press or a character to generate, such as `ArrowLeft` or `a`' ) ,
} ) ,
2025-05-05 17:38:22 -07:00
type : 'destructive' ,
2025-04-04 15:22:00 -07:00
} ,
2025-04-16 19:36:48 -07:00
2025-07-22 16:36:21 -07:00
handle : async ( tab , params , response ) = > {
response . setIncludeSnapshot ( ) ;
response . addCode ( ` // Press ${ params . key } ` ) ;
response . addCode ( ` await page.keyboard.press(' ${ params . key } '); ` ) ;
2025-04-16 19:36:48 -07:00
2025-07-22 17:43:42 -07:00
await tab . waitForCompletion ( async ( ) = > {
2025-07-22 16:36:21 -07:00
await tab . page . keyboard . press ( params . key ) ;
2025-07-22 17:43:42 -07:00
} ) ;
2025-04-04 15:22:00 -07:00
} ,
} ) ;
2025-07-16 16:40:00 -07:00
const typeSchema = elementSchema . extend ( {
text : z.string ( ) . describe ( 'Text to type into the element' ) ,
submit : z.boolean ( ) . optional ( ) . describe ( 'Whether to submit entered text (press Enter after)' ) ,
slowly : z.boolean ( ) . optional ( ) . describe ( 'Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.' ) ,
} ) ;
2025-07-22 07:53:33 -07:00
const type = defineTabTool ( {
2025-07-16 16:40:00 -07:00
capability : 'core' ,
schema : {
name : 'browser_type' ,
title : 'Type text' ,
feat: add snapshot size limits and optional snapshots to fix token overflow
Implements comprehensive solution for browser_click and other interactive tools
returning massive responses (37K+ tokens) due to full page snapshots.
Features implemented:
1. **Snapshot size limits** (--max-snapshot-tokens, default 10k)
- Automatically truncates large snapshots with helpful messages
- Preserves essential info (URL, title, errors) when truncating
- Shows exact token counts and configuration suggestions
2. **Optional snapshots** (--no-snapshots)
- Disables automatic snapshots after interactive operations
- browser_snapshot tool always works for explicit snapshots
- Maintains backward compatibility (snapshots enabled by default)
3. **Differential snapshots** (--differential-snapshots)
- Shows only changes since last snapshot instead of full page
- Tracks URL, title, DOM structure, and console activity
- Significantly reduces token usage for incremental operations
4. **Enhanced tool descriptions**
- All interactive tools now document snapshot behavior
- Clear guidance on when snapshots are included/excluded
- Helpful suggestions for users experiencing token limits
Configuration options:
- CLI: --no-snapshots, --max-snapshot-tokens N, --differential-snapshots
- ENV: PLAYWRIGHT_MCP_INCLUDE_SNAPSHOTS, PLAYWRIGHT_MCP_MAX_SNAPSHOT_TOKENS, etc.
- Config file: includeSnapshots, maxSnapshotTokens, differentialSnapshots
Fixes token overflow errors while providing users full control over
snapshot behavior and response sizes.
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 07:54:36 -06:00
description : 'Type text into editable element. Returns page snapshot after typing unless disabled with --no-snapshots.' ,
2025-07-16 16:40:00 -07:00
inputSchema : typeSchema ,
type : 'destructive' ,
} ,
2025-07-22 16:36:21 -07:00
handle : async ( tab , params , response ) = > {
response . setIncludeSnapshot ( ) ;
2025-07-16 16:40:00 -07:00
2025-07-22 16:36:21 -07:00
const locator = await tab . refLocator ( params ) ;
2025-07-16 16:40:00 -07:00
2025-07-22 17:43:42 -07:00
await tab . waitForCompletion ( async ( ) = > {
2025-07-22 16:36:21 -07:00
if ( params . slowly ) {
response . addCode ( ` // Press " ${ params . text } " sequentially into " ${ params . element } " ` ) ;
response . addCode ( ` await page. ${ await generateLocator ( locator ) } .pressSequentially( ${ javascript . quote ( params . text ) } ); ` ) ;
await locator . pressSequentially ( params . text ) ;
} else {
response . addCode ( ` // Fill " ${ params . text } " into " ${ params . element } " ` ) ;
response . addCode ( ` await page. ${ await generateLocator ( locator ) } .fill( ${ javascript . quote ( params . text ) } ); ` ) ;
await locator . fill ( params . text ) ;
}
2025-07-16 16:40:00 -07:00
2025-07-22 16:36:21 -07:00
if ( params . submit ) {
response . addCode ( ` await page. ${ await generateLocator ( locator ) } .press('Enter'); ` ) ;
await locator . press ( 'Enter' ) ;
}
2025-07-22 17:43:42 -07:00
} ) ;
2025-07-16 16:40:00 -07:00
} ,
} ) ;
export default [
pressKey ,
type ,
2025-04-04 15:22:00 -07:00
] ;