Skip to content

Commit 2d70d42

Browse files
authored
Merge pull request #18 from tontoko/refactor/simplify-tool-descriptions
Refine tool and schema descriptions for clarity and guidance
2 parents a748104 + 5d0d720 commit 2d70d42

File tree

15 files changed

+140
-133
lines changed

15 files changed

+140
-133
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tontoko/fast-playwright-mcp",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"publishConfig": {
55
"access": "public"
66
},

src/schemas/expectation.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ import { z } from 'zod';
44
*/
55
export const diffOptionsSchema = z
66
.object({
7-
enabled: z.boolean().default(false),
7+
enabled: z
8+
.boolean()
9+
.default(false)
10+
.describe('Show only changes (saves ~80% tokens)'),
811
threshold: z.number().min(0).max(1).default(0.1),
9-
format: z.enum(['unified', 'split', 'minimal']).default('unified'),
12+
format: z
13+
.enum(['unified', 'split', 'minimal'])
14+
.default('unified')
15+
.describe('Diff format ("minimal" for smallest output)'),
1016
maxDiffLines: z.number().positive().default(50),
1117
ignoreWhitespace: z.boolean().default(true),
1218
context: z.number().min(0).default(3),
@@ -17,7 +23,11 @@ export const diffOptionsSchema = z
1723
*/
1824
export const expectationSchema = z
1925
.object({
20-
includeSnapshot: z.boolean().optional().default(false),
26+
includeSnapshot: z
27+
.boolean()
28+
.optional()
29+
.default(false)
30+
.describe('Include accessibility tree (false for chained actions)'),
2131
includeConsole: z.boolean().optional().default(false),
2232
includeDownloads: z.boolean().optional().default(false),
2333
includeTabs: z.boolean().optional().default(false),
@@ -27,11 +37,8 @@ export const expectationSchema = z
2737
selector: z
2838
.string()
2939
.optional()
30-
.describe('CSS selector to limit snapshot scope'),
31-
maxLength: z
32-
.number()
33-
.optional()
34-
.describe('Maximum characters for snapshot'),
40+
.describe('CSS selector to limit scope (e.g., ".result", "form")'),
41+
maxLength: z.number().optional().describe('Max snapshot characters'),
3542
format: z.enum(['aria', 'text', 'html']).optional().default('aria'),
3643
})
3744
.optional(),

src/tools/batch-execute.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export const batchExecuteTool = defineTool({
1313
schema: {
1414
name: 'browser_batch_execute',
1515
title: 'Batch Execute Browser Actions',
16-
description: `Execute multiple browser actions in sequence with optimized response handling.RECOMMENDED:Use this tool instead of individual actions when performing multiple operations to significantly reduce token usage and improve performance.BY DEFAULT use for:form filling(multiple type→click),multi-step navigation,any workflow with 2+ known steps.Saves 90% tokens vs individual calls.globalExpectation:{includeSnapshot:false,snapshotOptions:{selector:"#app"},diffOptions:{enabled:true}}.Per-step override:steps[].expectation.Example:[{tool:"browser_navigate",arguments:{url:"https://example.com"}},{tool:"browser_type",arguments:{element:"username",ref:"#user",text:"john"}},{tool:"browser_click",arguments:{element:"submit",ref:"#btn"}}].Tool names must match exactly(e.g.browser_navigate,browser_click,browser_type).`,
16+
description:
17+
'Execute multiple browser actions in sequence. PREFER over individual tools for 2+ operations.',
1718
inputSchema: batchExecuteSchema,
1819
type: 'destructive',
1920
},

src/tools/dialogs.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ const handleDialog = defineTabTool({
77
schema: {
88
name: 'browser_handle_dialog',
99
title: 'Handle a dialog',
10-
description: `Handle a dialog(alert,confirm,prompt).accept:true to accept,false to dismiss.promptText:"answer" for prompt dialogs.expectation:{includeSnapshot:true} to see page after dialog handling.USE batch_execute if dialog appears during workflow.`,
10+
description: 'Handle a dialog (alert, confirm, prompt)',
1111
inputSchema: z.object({
12-
accept: z.boolean().describe('Whether to accept the dialog.'),
13-
promptText: z
14-
.string()
15-
.optional()
16-
.describe('The text of the prompt in case of a prompt dialog.'),
17-
expectation: expectationSchema,
12+
accept: z.boolean().describe('Accept (true) or dismiss (false)'),
13+
promptText: z.string().optional().describe('Text for prompt dialogs'),
14+
expectation: expectationSchema.describe(
15+
'Page state after dialog. Use batch_execute for workflows'
16+
),
1817
}),
1918
type: 'destructive',
2019
},

src/tools/evaluate.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import { generateLocator } from './utils.js';
88
const evaluateSchema = z.object({
99
function: z
1010
.string()
11-
.describe(
12-
'() => { /* code */ } or (element) => { /* code */ } when element is provided'
13-
),
11+
.describe('JS function: () => {...} or (element) => {...}'),
1412
element: z
1513
.string()
1614
.optional()
@@ -23,15 +21,17 @@ const evaluateSchema = z.object({
2321
.describe(
2422
'System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'
2523
),
26-
expectation: expectationSchema,
24+
expectation: expectationSchema.describe(
25+
'Page state config. false for data extraction, true for DOM changes'
26+
),
2727
});
2828
const evaluate = defineTabTool({
2929
capability: 'core',
3030
schema: {
3131
name: 'browser_evaluate',
3232
title: 'Evaluate JavaScript',
3333
description:
34-
'Evaluate JavaScript expression on page or element.Returns evaluation result.USE CASES:extract data,modify DOM,trigger events.expectation:{includeSnapshot:false} for data extraction,true if modifying page.element+ref to run on specific element.CONSIDER batch_execute for multiple evaluations.',
34+
'Evaluate JavaScript expression on page or element and return result',
3535
inputSchema: evaluateSchema,
3636
type: 'destructive',
3737
},

src/tools/files.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ const uploadFile = defineTabTool({
77
schema: {
88
name: 'browser_file_upload',
99
title: 'Upload files',
10-
description: `Upload one or multiple files to file input.paths:["/path/file1.jpg","/path/file2.pdf"] for multiple files.expectation:{includeSnapshot:true,snapshotOptions:{selector:"form"}} to verify upload.Must be triggered after file input interaction.USE batch_execute for click→upload workflows.`,
10+
description: 'Upload one or multiple files to file input',
1111
inputSchema: z.object({
12-
paths: z
13-
.array(z.string())
14-
.describe(
15-
'The absolute paths to the files to upload. Can be a single file or multiple files.'
16-
),
17-
expectation: expectationSchema,
12+
paths: z.array(z.string()).describe('Absolute paths to upload (array)'),
13+
expectation: expectationSchema.describe(
14+
'Page state config. Use batch_execute for click→upload'
15+
),
1816
}),
1917
type: 'destructive',
2018
},

src/tools/keyboard.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ const pressKey = defineTabTool({
1111
schema: {
1212
name: 'browser_press_key',
1313
title: 'Press a key',
14-
description:
15-
'Press a key on the keyboard.Common keys:Enter,Escape,ArrowUp/Down/Left/Right,Tab,Backspace.expectation:{includeSnapshot:false} for navigation keys,true for content changes.CONSIDER batch_execute for multiple key presses.',
14+
description: 'Press a key on the keyboard',
1615
inputSchema: z.object({
17-
key: z
18-
.string()
19-
.describe(
20-
'Name of the key to press or a character to generate, such as `ArrowLeft` or `a`'
21-
),
22-
expectation: expectationSchema,
16+
key: z.string().describe('Key to press'),
17+
expectation: expectationSchema.describe(
18+
'Page state config. Use batch_execute for multiple keys'
19+
),
2320
}),
2421
type: 'destructive',
2522
},
@@ -45,27 +42,24 @@ const typeSchema = elementSchema.extend({
4542
ref: z
4643
.string()
4744
.describe(
48-
'System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'
45+
'System-generated element ID from previous tool results. Never use custom values.'
4946
),
50-
text: z.string().describe('Text to type into the element'),
51-
submit: z
52-
.boolean()
53-
.optional()
54-
.describe('Whether to submit entered text (press Enter after)'),
47+
text: z.string(),
48+
submit: z.boolean().optional().describe('Press Enter after typing if true'),
5549
slowly: z
5650
.boolean()
5751
.optional()
58-
.describe(
59-
'Whether type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.'
60-
),
61-
expectation: expectationSchema,
52+
.describe('Type slowly for auto-complete if true'),
53+
expectation: expectationSchema.describe(
54+
'Page state config. Use batch_execute for forms'
55+
),
6256
});
6357
const type = defineTabTool({
6458
capability: 'core',
6559
schema: {
6660
name: 'browser_type',
6761
title: 'Type text',
68-
description: `Type text into editable element.FOR FORMS:Use batch_execute to fill multiple fields efficiently.slowly:true for auto-complete fields,submit:true to press Enter after.expectation:{includeSnapshot:false} when filling multiple fields(use batch),true for final verification.snapshotOptions:{selector:"form"} to focus on form only.diffOptions:{enabled:true} shows only what changed in form.`,
62+
description: 'Type text into editable element',
6963
inputSchema: typeSchema,
7064
type: 'destructive',
7165
},

src/tools/mouse.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@ const mouseClick = defineTabTool({
3939
schema: {
4040
name: 'browser_mouse_click_xy',
4141
title: 'Click',
42-
description:
43-
'Click at specific coordinates.Requires --caps=vision.x,y:click position.expectation:{includeSnapshot:true} to verify result.PREFER browser_click with element ref over coordinates.USE batch_execute for coordinate-based workflows.',
42+
description: 'Click at specific coordinates',
4443
inputSchema: elementSchema.extend({
45-
x: z.number().describe('X coordinate'),
46-
y: z.number().describe('Y coordinate'),
47-
expectation: expectationSchema,
44+
x: z.number().describe('X coordinate (requires --caps=vision)'),
45+
y: z.number().describe('Y coordinate (requires --caps=vision)'),
46+
expectation: expectationSchema.describe(
47+
'Page state after click. Prefer element ref over coords'
48+
),
4849
}),
4950
type: 'destructive',
5051
},
@@ -69,13 +70,15 @@ const mouseDrag = defineTabTool({
6970
schema: {
7071
name: 'browser_mouse_drag_xy',
7172
title: 'Drag mouse',
72-
description: `Drag from one coordinate to another.Requires --caps=vision.startX,startY→endX,endY.expectation:{includeSnapshot:true,snapshotOptions:{selector:".drop-zone"}} to verify.PREFER browser_drag with element refs over coordinates.`,
73+
description: 'Drag from one coordinate to another',
7374
inputSchema: elementSchema.extend({
74-
startX: z.number().describe('Start X coordinate'),
75-
startY: z.number().describe('Start Y coordinate'),
76-
endX: z.number().describe('End X coordinate'),
77-
endY: z.number().describe('End Y coordinate'),
78-
expectation: expectationSchema,
75+
startX: z.number().describe('Start X (requires --caps=vision)'),
76+
startY: z.number().describe('Start Y (requires --caps=vision)'),
77+
endX: z.number().describe('End X'),
78+
endY: z.number().describe('End Y'),
79+
expectation: expectationSchema.describe(
80+
'Page state after drag. Prefer element refs over coords'
81+
),
7982
}),
8083
type: 'destructive',
8184
},

src/tools/navigate.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const navigate = defineTool({
1212
schema: {
1313
name: 'browser_navigate',
1414
title: 'Navigate to a URL',
15-
description: `Navigate to a URL.expectation:{includeSnapshot:true} to see what loaded,false if you know what to do next.snapshotOptions:{selector:"#content"} to focus on main content(saves 50% tokens).diffOptions:{enabled:true} when revisiting pages to see only changes.CONSIDER batch_execute for navigate→interact workflows.`,
15+
description: 'Navigate to a URL',
1616
inputSchema: z.object({
1717
url: z.string().describe('The URL to navigate to'),
18-
expectation: expectationSchema,
18+
expectation: expectationSchema.describe('Page state after navigation'),
1919
}),
2020
type: 'destructive',
2121
},
@@ -29,11 +29,10 @@ const goBack = defineTabTool({
2929
capability: 'core',
3030
schema: {
3131
name: 'browser_navigate_back',
32-
title: 'Go back',
33-
description:
34-
'Go back to previous page.expectation:{includeSnapshot:true} to see previous page,false if continuing workflow.diffOptions:{enabled:true} shows only what changed from forward page.USE batch_execute for back→interact sequences.',
32+
title: 'Go back to previous page',
33+
description: 'Go back to previous page',
3534
inputSchema: z.object({
36-
expectation: expectationSchema,
35+
expectation: expectationSchema.describe('Page state after going back'),
3736
}),
3837
type: 'readOnly',
3938
},
@@ -46,11 +45,10 @@ const goForward = defineTabTool({
4645
capability: 'core',
4746
schema: {
4847
name: 'browser_navigate_forward',
49-
title: 'Go forward',
50-
description:
51-
'Go forward to next page.expectation:{includeSnapshot:true} to see next page,false if continuing workflow.diffOptions:{enabled:true} shows only what changed from previous page.USE batch_execute for forward→interact sequences.',
48+
title: 'Go forward to next page',
49+
description: 'Go forward to next page',
5250
inputSchema: z.object({
53-
expectation: expectationSchema,
51+
expectation: expectationSchema.describe('Page state after going forward'),
5452
}),
5553
type: 'readOnly',
5654
},

src/tools/network.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,32 @@ import {
88
import { defineTabTool } from './tool.js';
99

1010
const networkFilterSchema = z.object({
11-
urlPatterns: z.array(z.string()).optional(),
12-
excludeUrlPatterns: z.array(z.string()).optional(),
11+
urlPatterns: z
12+
.array(z.string())
13+
.optional()
14+
.describe('URL patterns to filter (supports regex)'),
15+
excludeUrlPatterns: z
16+
.array(z.string())
17+
.optional()
18+
.describe('URL patterns to exclude (takes precedence)'),
1319
statusRanges: z
1420
.array(
1521
z.object({
16-
min: z.number(),
17-
max: z.number(),
22+
min: z.number().describe('Minimum status code'),
23+
max: z.number().describe('Maximum status code'),
1824
})
1925
)
20-
.optional(),
21-
methods: z.array(z.string()).optional(),
22-
maxRequests: z.number().default(20),
23-
newestFirst: z.boolean().default(true),
26+
.optional()
27+
.describe('Status code ranges (e.g., [{min:200,max:299}])'),
28+
methods: z.array(z.string()).optional().describe('HTTP methods to filter'),
29+
maxRequests: z
30+
.number()
31+
.default(20)
32+
.describe('Max requests to return (default: 20)'),
33+
newestFirst: z
34+
.boolean()
35+
.default(true)
36+
.describe('Order by timestamp (default: newest first)'),
2437
});
2538

2639
const requests = defineTabTool({
@@ -29,7 +42,7 @@ const requests = defineTabTool({
2942
name: 'browser_network_requests',
3043
title: 'List network requests',
3144
description:
32-
'Returns network requests since loading the page with optional filtering. urlPatterns:["api/users"] to filter by URL patterns. excludeUrlPatterns:["analytics"] to exclude specific patterns. statusRanges:[{min:200,max:299}] for success codes only. methods:["GET","POST"] to filter by HTTP method. maxRequests:10 to limit results. newestFirst:false for chronological order. Supports regex patterns for advanced filtering.',
45+
'Returns network requests since loading the page with optional filtering',
3346
inputSchema: networkFilterSchema.partial(),
3447
type: 'readOnly',
3548
},

0 commit comments

Comments
 (0)