@tontoko/fast-playwright-mcp 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,22 +20,22 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
  // src/schemas/expectation.ts
21
21
  import { z } from "zod";
22
22
  var diffOptionsSchema = z.object({
23
- enabled: z.boolean().default(false),
23
+ enabled: z.boolean().default(false).describe("Show only changes (saves ~80% tokens)"),
24
24
  threshold: z.number().min(0).max(1).default(0.1),
25
- format: z.enum(["unified", "split", "minimal"]).default("unified"),
25
+ format: z.enum(["unified", "split", "minimal"]).default("unified").describe('Diff format ("minimal" for smallest output)'),
26
26
  maxDiffLines: z.number().positive().default(50),
27
27
  ignoreWhitespace: z.boolean().default(true),
28
28
  context: z.number().min(0).default(3)
29
29
  }).optional();
30
30
  var expectationSchema = z.object({
31
- includeSnapshot: z.boolean().optional().default(false),
31
+ includeSnapshot: z.boolean().optional().default(false).describe("Include accessibility tree (false for chained actions)"),
32
32
  includeConsole: z.boolean().optional().default(false),
33
33
  includeDownloads: z.boolean().optional().default(false),
34
34
  includeTabs: z.boolean().optional().default(false),
35
35
  includeCode: z.boolean().optional().default(false),
36
36
  snapshotOptions: z.object({
37
- selector: z.string().optional().describe("CSS selector to limit snapshot scope"),
38
- maxLength: z.number().optional().describe("Maximum characters for snapshot"),
37
+ selector: z.string().optional().describe('CSS selector to limit scope (e.g., ".result", "form")'),
38
+ maxLength: z.number().optional().describe("Max snapshot characters"),
39
39
  format: z.enum(["aria", "text", "html"]).optional().default("aria")
40
40
  }).optional(),
41
41
  consoleOptions: z.object({
@@ -26,7 +26,7 @@ var batchExecuteTool = defineTool({
26
26
  schema: {
27
27
  name: "browser_batch_execute",
28
28
  title: "Batch Execute Browser Actions",
29
- 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).`,
29
+ description: "Execute multiple browser actions in sequence. PREFER over individual tools for 2+ operations.",
30
30
  inputSchema: batchExecuteSchema,
31
31
  type: "destructive"
32
32
  },
@@ -26,11 +26,11 @@ var handleDialog = defineTabTool({
26
26
  schema: {
27
27
  name: "browser_handle_dialog",
28
28
  title: "Handle a dialog",
29
- 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.`,
29
+ description: "Handle a dialog (alert, confirm, prompt)",
30
30
  inputSchema: z.object({
31
- accept: z.boolean().describe("Whether to accept the dialog."),
32
- promptText: z.string().optional().describe("The text of the prompt in case of a prompt dialog."),
33
- expectation: expectationSchema
31
+ accept: z.boolean().describe("Accept (true) or dismiss (false)"),
32
+ promptText: z.string().optional().describe("Text for prompt dialogs"),
33
+ expectation: expectationSchema.describe("Page state after dialog. Use batch_execute for workflows")
34
34
  }),
35
35
  type: "destructive"
36
36
  },
@@ -24,17 +24,17 @@ import { quote } from "../utils/codegen.js";
24
24
  import { defineTabTool } from "./tool.js";
25
25
  import { generateLocator } from "./utils.js";
26
26
  var evaluateSchema = z.object({
27
- function: z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
27
+ function: z.string().describe("JS function: () => {...} or (element) => {...}"),
28
28
  element: z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
29
29
  ref: z.string().optional().describe('System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'),
30
- expectation: expectationSchema
30
+ expectation: expectationSchema.describe("Page state config. false for data extraction, true for DOM changes")
31
31
  });
32
32
  var evaluate = defineTabTool({
33
33
  capability: "core",
34
34
  schema: {
35
35
  name: "browser_evaluate",
36
36
  title: "Evaluate JavaScript",
37
- description: "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.",
37
+ description: "Evaluate JavaScript expression on page or element and return result",
38
38
  inputSchema: evaluateSchema,
39
39
  type: "destructive"
40
40
  },
@@ -26,10 +26,10 @@ var uploadFile = defineTabTool({
26
26
  schema: {
27
27
  name: "browser_file_upload",
28
28
  title: "Upload files",
29
- 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.`,
29
+ description: "Upload one or multiple files to file input",
30
30
  inputSchema: z.object({
31
- paths: z.array(z.string()).describe("The absolute paths to the files to upload. Can be a single file or multiple files."),
32
- expectation: expectationSchema
31
+ paths: z.array(z.string()).describe("Absolute paths to upload (array)"),
32
+ expectation: expectationSchema.describe("Page state config. Use batch_execute for click→upload")
33
33
  }),
34
34
  type: "destructive"
35
35
  },
@@ -30,10 +30,10 @@ var pressKey = defineTabTool({
30
30
  schema: {
31
31
  name: "browser_press_key",
32
32
  title: "Press a key",
33
- description: "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.",
33
+ description: "Press a key on the keyboard",
34
34
  inputSchema: z.object({
35
- key: z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`"),
36
- expectation: expectationSchema
35
+ key: z.string().describe("Key to press"),
36
+ expectation: expectationSchema.describe("Page state config. Use batch_execute for multiple keys")
37
37
  }),
38
38
  type: "destructive"
39
39
  },
@@ -51,18 +51,18 @@ var pressKey = defineTabTool({
51
51
  });
52
52
  var typeSchema = elementSchema.extend({
53
53
  element: z.string().describe("Human-readable element description used to obtain permission to interact with the element"),
54
- ref: z.string().describe('System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'),
55
- text: z.string().describe("Text to type into the element"),
56
- submit: z.boolean().optional().describe("Whether to submit entered text (press Enter after)"),
57
- slowly: z.boolean().optional().describe("Whether type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once."),
58
- expectation: expectationSchema
54
+ ref: z.string().describe("System-generated element ID from previous tool results. Never use custom values."),
55
+ text: z.string(),
56
+ submit: z.boolean().optional().describe("Press Enter after typing if true"),
57
+ slowly: z.boolean().optional().describe("Type slowly for auto-complete if true"),
58
+ expectation: expectationSchema.describe("Page state config. Use batch_execute for forms")
59
59
  });
60
60
  var type = defineTabTool({
61
61
  capability: "core",
62
62
  schema: {
63
63
  name: "browser_type",
64
64
  title: "Type text",
65
- 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.`,
65
+ description: "Type text into editable element",
66
66
  inputSchema: typeSchema,
67
67
  type: "destructive"
68
68
  },
@@ -54,11 +54,11 @@ var mouseClick = defineTabTool({
54
54
  schema: {
55
55
  name: "browser_mouse_click_xy",
56
56
  title: "Click",
57
- description: "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.",
57
+ description: "Click at specific coordinates",
58
58
  inputSchema: elementSchema.extend({
59
- x: z.number().describe("X coordinate"),
60
- y: z.number().describe("Y coordinate"),
61
- expectation: expectationSchema
59
+ x: z.number().describe("X coordinate (requires --caps=vision)"),
60
+ y: z.number().describe("Y coordinate (requires --caps=vision)"),
61
+ expectation: expectationSchema.describe("Page state after click. Prefer element ref over coords")
62
62
  }),
63
63
  type: "destructive"
64
64
  },
@@ -81,13 +81,13 @@ var mouseDrag = defineTabTool({
81
81
  schema: {
82
82
  name: "browser_mouse_drag_xy",
83
83
  title: "Drag mouse",
84
- 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.`,
84
+ description: "Drag from one coordinate to another",
85
85
  inputSchema: elementSchema.extend({
86
- startX: z.number().describe("Start X coordinate"),
87
- startY: z.number().describe("Start Y coordinate"),
88
- endX: z.number().describe("End X coordinate"),
89
- endY: z.number().describe("End Y coordinate"),
90
- expectation: expectationSchema
86
+ startX: z.number().describe("Start X (requires --caps=vision)"),
87
+ startY: z.number().describe("Start Y (requires --caps=vision)"),
88
+ endX: z.number().describe("End X"),
89
+ endY: z.number().describe("End Y"),
90
+ expectation: expectationSchema.describe("Page state after drag. Prefer element refs over coords")
91
91
  }),
92
92
  type: "destructive"
93
93
  },
@@ -31,10 +31,10 @@ var navigate = defineTool({
31
31
  schema: {
32
32
  name: "browser_navigate",
33
33
  title: "Navigate to a URL",
34
- 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.`,
34
+ description: "Navigate to a URL",
35
35
  inputSchema: z.object({
36
36
  url: z.string().describe("The URL to navigate to"),
37
- expectation: expectationSchema
37
+ expectation: expectationSchema.describe("Page state after navigation")
38
38
  }),
39
39
  type: "destructive"
40
40
  },
@@ -48,10 +48,10 @@ var goBack = defineTabTool({
48
48
  capability: "core",
49
49
  schema: {
50
50
  name: "browser_navigate_back",
51
- title: "Go back",
52
- description: "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.",
51
+ title: "Go back to previous page",
52
+ description: "Go back to previous page",
53
53
  inputSchema: z.object({
54
- expectation: expectationSchema
54
+ expectation: expectationSchema.describe("Page state after going back")
55
55
  }),
56
56
  type: "readOnly"
57
57
  },
@@ -64,10 +64,10 @@ var goForward = defineTabTool({
64
64
  capability: "core",
65
65
  schema: {
66
66
  name: "browser_navigate_forward",
67
- title: "Go forward",
68
- description: "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.",
67
+ title: "Go forward to next page",
68
+ description: "Go forward to next page",
69
69
  inputSchema: z.object({
70
- expectation: expectationSchema
70
+ expectation: expectationSchema.describe("Page state after going forward")
71
71
  }),
72
72
  type: "readOnly"
73
73
  },
@@ -24,22 +24,22 @@ import {
24
24
  } from "../utils/network-filter.js";
25
25
  import { defineTabTool } from "./tool.js";
26
26
  var networkFilterSchema = z.object({
27
- urlPatterns: z.array(z.string()).optional(),
28
- excludeUrlPatterns: z.array(z.string()).optional(),
27
+ urlPatterns: z.array(z.string()).optional().describe("URL patterns to filter (supports regex)"),
28
+ excludeUrlPatterns: z.array(z.string()).optional().describe("URL patterns to exclude (takes precedence)"),
29
29
  statusRanges: z.array(z.object({
30
- min: z.number(),
31
- max: z.number()
32
- })).optional(),
33
- methods: z.array(z.string()).optional(),
34
- maxRequests: z.number().default(20),
35
- newestFirst: z.boolean().default(true)
30
+ min: z.number().describe("Minimum status code"),
31
+ max: z.number().describe("Maximum status code")
32
+ })).optional().describe("Status code ranges (e.g., [{min:200,max:299}])"),
33
+ methods: z.array(z.string()).optional().describe("HTTP methods to filter"),
34
+ maxRequests: z.number().default(20).describe("Max requests to return (default: 20)"),
35
+ newestFirst: z.boolean().default(true).describe("Order by timestamp (default: newest first)")
36
36
  });
37
37
  var requests = defineTabTool({
38
38
  capability: "core",
39
39
  schema: {
40
40
  name: "browser_network_requests",
41
41
  title: "List network requests",
42
- description: '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.',
42
+ description: "Returns network requests since loading the page with optional filtering",
43
43
  inputSchema: networkFilterSchema.partial(),
44
44
  type: "readOnly"
45
45
  },
@@ -29,7 +29,7 @@ var screenshotSchema = z.object({
29
29
  element: z.string().optional().describe("Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too."),
30
30
  ref: z.string().optional().describe('System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.'),
31
31
  fullPage: z.boolean().optional().describe("When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots."),
32
- expectation: expectationSchema
32
+ expectation: expectationSchema.describe("Additional page state config")
33
33
  }).refine((data) => {
34
34
  return !!data.element === !!data.ref;
35
35
  }, {
@@ -84,7 +84,7 @@ var screenshot = defineTabTool({
84
84
  schema: {
85
85
  name: "browser_take_screenshot",
86
86
  title: "Take a screenshot",
87
- description: `Take a screenshot of current page.Returns image data.expectation:{includeSnapshot:false} to avoid redundant accessibility tree(screenshot≠snapshot).imageOptions:{quality:50,format:"jpeg"} for 70% size reduction.fullPage:true for entire page,element+ref for specific element.USE CASES:visual verification,documentation,error capture.`,
87
+ description: "Take a screenshot of current page and return image data",
88
88
  inputSchema: screenshotSchema,
89
89
  type: "readOnly"
90
90
  },
@@ -28,9 +28,9 @@ var snapshot = defineTool({
28
28
  schema: {
29
29
  name: "browser_snapshot",
30
30
  title: "Page snapshot",
31
- description: `Capture accessibility snapshot of current page.AVOID calling directly - use expectation:{includeSnapshot:true} on other tools instead.USE CASES:Initial page inspection,debugging when other tools didn't capture needed info.snapshotOptions:{selector:"#content"} to focus on specific area.`,
31
+ description: "Capture accessibility snapshot of current page",
32
32
  inputSchema: z.object({
33
- expectation: expectationSchema
33
+ expectation: expectationSchema.describe("Page state config")
34
34
  }),
35
35
  type: "readOnly"
36
36
  },
@@ -47,19 +47,19 @@ var snapshot = defineTool({
47
47
  });
48
48
  var elementSchema = z.object({
49
49
  element: z.string().describe("Human-readable element description used to obtain permission to interact with the element"),
50
- ref: z.string().describe('System-generated element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.')
50
+ ref: z.string().describe("System-generated element ID from previous tool results. Never use custom values.")
51
51
  });
52
52
  var clickSchema = elementSchema.extend({
53
- doubleClick: z.boolean().optional().describe("Whether to perform a double click instead of a single click"),
54
- button: z.enum(["left", "right", "middle"]).optional().describe("Button to click, defaults to left"),
55
- expectation: expectationSchema
53
+ doubleClick: z.boolean().optional().describe("Double-click if true"),
54
+ button: z.enum(["left", "right", "middle"]).optional().describe("Mouse button (default: left)"),
55
+ expectation: expectationSchema.describe("Page state capture config. Use batch_execute for multi-clicks")
56
56
  });
57
57
  var click = defineTabTool({
58
58
  capability: "core",
59
59
  schema: {
60
60
  name: "browser_click",
61
- title: "Click",
62
- description: `Perform click on web page.USE batch_execute for multi-click workflows.expectation:{includeSnapshot:false} when next action follows immediately,true to verify result.diffOptions:{enabled:true,format:"minimal"} shows only changes(saves 80% tokens).snapshotOptions:{selector:".result"} to focus on result area.doubleClick:true for double-click,button:"right" for context menu.`,
61
+ title: "Perform click on web page",
62
+ description: "Perform click on web page",
63
63
  inputSchema: clickSchema,
64
64
  type: "destructive"
65
65
  },
@@ -90,13 +90,13 @@ var drag = defineTabTool({
90
90
  schema: {
91
91
  name: "browser_drag",
92
92
  title: "Drag mouse",
93
- description: `Perform drag and drop between two elements.expectation:{includeSnapshot:true,snapshotOptions:{selector:".drop-zone"}} to verify drop result.diffOptions:{enabled:true} shows only what moved.CONSIDER batch_execute if part of larger workflow.`,
93
+ description: "Perform drag and drop between two elements",
94
94
  inputSchema: z.object({
95
95
  startElement: z.string().describe("Human-readable source element description used to obtain the permission to interact with the element"),
96
- startRef: z.string().describe('System-generated source element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'),
96
+ startRef: z.string().describe("System-generated source element ID from previous tool results. Never use custom values."),
97
97
  endElement: z.string().describe("Human-readable target element description used to obtain the permission to interact with the element"),
98
- endRef: z.string().describe('System-generated target element ID from previous tool results (e.g., "rNODE-45-1"). Never use custom values.'),
99
- expectation: expectationSchema
98
+ endRef: z.string().describe("System-generated target element ID from previous tool results. Never use custom values."),
99
+ expectation: expectationSchema.describe("Page state after drag. Use batch_execute for workflows")
100
100
  }),
101
101
  type: "destructive"
102
102
  },
@@ -116,9 +116,9 @@ var hover = defineTabTool({
116
116
  schema: {
117
117
  name: "browser_hover",
118
118
  title: "Hover mouse",
119
- description: `Hover over element on page.expectation:{includeSnapshot:true} to capture tooltips/dropdown menus,false for simple hover.snapshotOptions:{selector:".tooltip"} to focus on tooltip area.Often followed by click - use batch_execute for hover→click sequences.`,
119
+ description: "Hover over element on page",
120
120
  inputSchema: elementSchema.extend({
121
- expectation: expectationSchema
121
+ expectation: expectationSchema.describe("Page state after hover. Use batch_execute for hover→click")
122
122
  }),
123
123
  type: "readOnly"
124
124
  },
@@ -131,15 +131,15 @@ var hover = defineTabTool({
131
131
  }
132
132
  });
133
133
  var selectOptionSchema = elementSchema.extend({
134
- values: z.array(z.string()).describe("Array of values to select in the dropdown. This can be a single value or multiple values."),
135
- expectation: expectationSchema
134
+ values: z.array(z.string()).describe("Values to select (array)"),
135
+ expectation: expectationSchema.describe("Page state after selection. Use batch_execute for forms")
136
136
  });
137
137
  var selectOption = defineTabTool({
138
138
  capability: "core",
139
139
  schema: {
140
140
  name: "browser_select_option",
141
141
  title: "Select option",
142
- description: `Select option in dropdown.values:["option1","option2"] for multi-select.expectation:{includeSnapshot:false} when part of form filling(use batch),true to verify selection.snapshotOptions:{selector:"form"} for form context.USE batch_execute for form workflows with multiple selects.`,
142
+ description: "Select option in dropdown",
143
143
  inputSchema: selectOptionSchema,
144
144
  type: "destructive"
145
145
  },
package/lib/tools/tabs.js CHANGED
@@ -26,9 +26,9 @@ var listTabs = defineTool({
26
26
  schema: {
27
27
  name: "browser_tab_list",
28
28
  title: "List tabs",
29
- description: "List browser tabs.Always returns tab list with titles and URLs.expectation:{includeSnapshot:false} for just tab info,true to also see current tab content.USE before tab_select to find right tab.",
29
+ description: "List browser tabs with titles and URLs",
30
30
  inputSchema: z.object({
31
- expectation: expectationSchema
31
+ expectation: expectationSchema.describe("Page state config")
32
32
  }),
33
33
  type: "readOnly"
34
34
  },
@@ -42,10 +42,10 @@ var selectTab = defineTool({
42
42
  schema: {
43
43
  name: "browser_tab_select",
44
44
  title: "Select a tab",
45
- description: `Select a tab by index.expectation:{includeSnapshot:true} to see selected tab content,false if you know what's there.USE batch_execute for tab_select→interact workflows.`,
45
+ description: "Select a tab by index",
46
46
  inputSchema: z.object({
47
47
  index: z.number().describe("The index of the tab to select"),
48
- expectation: expectationSchema
48
+ expectation: expectationSchema.describe("Page state after tab switch")
49
49
  }),
50
50
  type: "readOnly"
51
51
  },
@@ -59,10 +59,10 @@ var newTab = defineTool({
59
59
  schema: {
60
60
  name: "browser_tab_new",
61
61
  title: "Open a new tab",
62
- description: `Open a new tab.url:"https://example.com" to navigate immediately,omit for blank tab.expectation:{includeSnapshot:true} to see new tab,false if opening for later use.CONSIDER batch_execute for new_tab→navigate→interact.`,
62
+ description: "Open a new tab",
63
63
  inputSchema: z.object({
64
- url: z.string().optional().describe("The URL to navigate to in the new tab. If not provided, the new tab will be blank."),
65
- expectation: expectationSchema
64
+ url: z.string().optional().describe("URL for new tab (optional)"),
65
+ expectation: expectationSchema.describe("Page state of new tab")
66
66
  }),
67
67
  type: "readOnly"
68
68
  },
@@ -79,10 +79,10 @@ var closeTab = defineTool({
79
79
  schema: {
80
80
  name: "browser_tab_close",
81
81
  title: "Close a tab",
82
- description: "Close a tab.index:N to close specific tab,omit to close current.expectation:{includeSnapshot:false} usually sufficient,true to verify remaining tabs.USE batch_execute for multi-tab cleanup.",
82
+ description: "Close a tab by index or close current tab",
83
83
  inputSchema: z.object({
84
- index: z.number().optional().describe("The index of the tab to close. Closes current tab if not provided."),
85
- expectation: expectationSchema
84
+ index: z.number().optional().describe("Tab index to close (omit for current)"),
85
+ expectation: expectationSchema.describe("Page state after close")
86
86
  }),
87
87
  type: "destructive"
88
88
  },
package/lib/tools/wait.js CHANGED
@@ -26,12 +26,12 @@ var wait = defineTool({
26
26
  schema: {
27
27
  name: "browser_wait_for",
28
28
  title: "Wait for",
29
- description: `Wait for text to appear/disappear or time to pass.PREFER text-based wait over time for reliability.For loading states:wait for text:"Loading..." textGone:true.For dynamic content:wait for specific text to appear.expectation:{includeSnapshot:true,snapshotOptions:{selector:"#status"},diffOptions:{enabled:true}} shows only what changed.AVOID:fixed time waits unless necessary.`,
29
+ description: "Wait for text to appear or disappear or a specified time to pass",
30
30
  inputSchema: z.object({
31
- time: z.number().optional().describe("The time to wait in seconds"),
32
- text: z.string().optional().describe("The text to wait for"),
33
- textGone: z.string().optional().describe("The text to wait for to disappear"),
34
- expectation: expectationSchema
31
+ time: z.number().optional().describe("Wait time in seconds"),
32
+ text: z.string().optional(),
33
+ textGone: z.string().optional(),
34
+ expectation: expectationSchema.describe("Page state after wait")
35
35
  }),
36
36
  type: "readOnly"
37
37
  },
@@ -37,9 +37,9 @@ var batchStepSchema = z.object({
37
37
  expectation: expectationSchema.describe("Expected output configuration for this step")
38
38
  });
39
39
  var batchExecuteSchema = z.object({
40
- steps: z.array(batchStepSchema).min(1).describe("Array of steps to execute in sequence"),
40
+ steps: z.array(batchStepSchema).min(1).describe('Array of steps to execute in sequence. Recommended for form filling (multiple type→click), multi-step navigation, any workflow with 2+ known steps. Saves 90% tokens vs individual calls. 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"}}]'),
41
41
  stopOnFirstError: z.boolean().optional().default(false).describe("Stop entire batch on first error"),
42
- globalExpectation: z.preprocess(parseJsonString, expectationSchema).optional().describe("Default expectation for all steps")
42
+ globalExpectation: z.preprocess(parseJsonString, expectationSchema).optional().describe('Default expectation for all steps. Recommended: {includeSnapshot:false,snapshotOptions:{selector:"#app"},diffOptions:{enabled:true}}. Per-step override with steps[].expectation')
43
43
  });
44
44
  export {
45
45
  batchStepSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tontoko/fast-playwright-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },