mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-25 16:02:26 +08:00
chore: annotate tools (#351)
Fixes https://github.com/microsoft/playwright-mcp/issues/215
This commit is contained in:
parent
8cd7d5a753
commit
d01aa19ffa
66
README.md
66
README.md
@ -276,38 +276,47 @@ X Y coordinate space, based on the provided screenshot.
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_snapshot**
|
||||
- Title: Page snapshot
|
||||
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_click**
|
||||
- Title: Click
|
||||
- Description: Perform click on a web page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_drag**
|
||||
- Title: Drag mouse
|
||||
- Description: Perform drag and drop between two elements
|
||||
- Parameters:
|
||||
- `startElement` (string): Human-readable source element description used to obtain the permission to interact with the element
|
||||
- `startRef` (string): Exact source element reference from the page snapshot
|
||||
- `endElement` (string): Human-readable target element description used to obtain the permission to interact with the element
|
||||
- `endRef` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_hover**
|
||||
- Title: Hover mouse
|
||||
- Description: Hover over element on page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_type**
|
||||
- Title: Type text
|
||||
- Description: Type text into editable element
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
@ -315,54 +324,66 @@ X Y coordinate space, based on the provided screenshot.
|
||||
- `text` (string): Text to type into the element
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
- `slowly` (boolean, optional): 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.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_select_option**
|
||||
- Title: Select option
|
||||
- Description: Select an option in a dropdown
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_take_screenshot**
|
||||
- Title: Take a screenshot
|
||||
- Description: Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
|
||||
- Parameters:
|
||||
- `raw` (boolean, optional): Whether to return without compression (in PNG format). Default is false, which returns a JPEG image.
|
||||
- `element` (string, optional): 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.
|
||||
- `ref` (string, optional): Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.
|
||||
- Read-only: **true**
|
||||
|
||||
### Vision-based Interactions
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_capture**
|
||||
- Title: Take a screenshot
|
||||
- Description: Take a screenshot of the current page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_move_mouse**
|
||||
- Title: Move mouse
|
||||
- Description: Move mouse to a given position
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_click**
|
||||
- Title: Click
|
||||
- Description: Click left mouse button
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_drag**
|
||||
- Title: Drag mouse
|
||||
- Description: Drag left mouse button
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
@ -370,143 +391,188 @@ X Y coordinate space, based on the provided screenshot.
|
||||
- `startY` (number): Start Y coordinate
|
||||
- `endX` (number): End X coordinate
|
||||
- `endY` (number): End Y coordinate
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_type**
|
||||
- Title: Type text
|
||||
- Description: Type text
|
||||
- Parameters:
|
||||
- `text` (string): Text to type into the element
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
- Read-only: **false**
|
||||
|
||||
### Tab Management
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_list**
|
||||
- Title: List tabs
|
||||
- Description: List browser tabs
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_new**
|
||||
- Title: Open a new tab
|
||||
- Description: Open a new tab
|
||||
- Parameters:
|
||||
- `url` (string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_select**
|
||||
- Title: Select a tab
|
||||
- Description: Select a tab by index
|
||||
- Parameters:
|
||||
- `index` (number): The index of the tab to select
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_close**
|
||||
- Title: Close a tab
|
||||
- Description: Close a tab
|
||||
- Parameters:
|
||||
- `index` (number, optional): The index of the tab to close. Closes current tab if not provided.
|
||||
- Read-only: **false**
|
||||
|
||||
### Navigation
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate**
|
||||
- Title: Navigate to a URL
|
||||
- Description: Navigate to a URL
|
||||
- Parameters:
|
||||
- `url` (string): The URL to navigate to
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_back**
|
||||
- Title: Go back
|
||||
- Description: Go back to the previous page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_forward**
|
||||
- Title: Go forward
|
||||
- Description: Go forward to the next page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
### Keyboard
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_press_key**
|
||||
- Title: Press a key
|
||||
- Description: Press a key on the keyboard
|
||||
- Parameters:
|
||||
- `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
|
||||
- Read-only: **false**
|
||||
|
||||
### Console
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_console_messages**
|
||||
- Title: Get console messages
|
||||
- Description: Returns all console messages
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
### Files and Media
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_file_upload**
|
||||
- Title: Upload files
|
||||
- Description: Upload one or multiple files
|
||||
- Parameters:
|
||||
- `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_pdf_save**
|
||||
- Title: Save as PDF
|
||||
- Description: Save page as PDF
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
### Utilities
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_close**
|
||||
- Title: Close browser
|
||||
- Description: Close the page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_wait**
|
||||
- Title: Wait
|
||||
- Description: Wait for a specified time in seconds
|
||||
- Parameters:
|
||||
- `time` (number): The time to wait in seconds
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_resize**
|
||||
- Title: Resize browser window
|
||||
- Description: Resize the browser window
|
||||
- Parameters:
|
||||
- `width` (number): Width of the browser window
|
||||
- `height` (number): Height of the browser window
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_install**
|
||||
- Title: Install the browser specified in the config
|
||||
- Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
|
||||
- Parameters: None
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_handle_dialog**
|
||||
- Title: Handle a dialog
|
||||
- Description: Handle a dialog
|
||||
- Parameters:
|
||||
- `accept` (boolean): Whether to accept the dialog.
|
||||
- `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_network_requests**
|
||||
- Title: List network requests
|
||||
- Description: Returns all network requests since loading the page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
### Testing
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_generate_playwright_test**
|
||||
- Title: Generate a Playwright test
|
||||
- Description: Generate a Playwright test for given scenario
|
||||
- Parameters:
|
||||
- `name` (string): The name of the test
|
||||
- `description` (string): The description of the test
|
||||
- `steps` (array): The steps of the test
|
||||
- Read-only: **true**
|
||||
|
||||
<!--- End of generated section -->
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -9,7 +9,7 @@
|
||||
"version": "0.0.20",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.10.1",
|
||||
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||
"commander": "^13.1.0",
|
||||
"playwright": "1.53.0-alpha-1746218818000",
|
||||
"yaml": "^2.7.1",
|
||||
@ -228,9 +228,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@modelcontextprotocol/sdk": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.10.1.tgz",
|
||||
"integrity": "sha512-xNYdFdkJqEfIaTVP1gPKoEvluACHZsHZegIoICX8DM1o6Qf3G5u2BQJHmgd0n4YgRPqqK/u1ujQvrgAxxSJT9w==",
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz",
|
||||
"integrity": "sha512-k/1pb70eD638anoi0e8wUGAlbMJXyvdV4p62Ko+EZ7eBe1xMx8Uhak1R5DgfoofsK5IBBnRwsYGTaLZl+6/+RQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^1.0.5",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"lint": "npm run update-readme && eslint .",
|
||||
"lint": "npm run update-readme && eslint . && tsc --noEmit",
|
||||
"update-readme": "node utils/update-readme.js",
|
||||
"watch": "tsc --watch",
|
||||
"test": "playwright test",
|
||||
@ -35,7 +35,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.10.1",
|
||||
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||
"commander": "^13.1.0",
|
||||
"playwright": "1.53.0-alpha-1746218818000",
|
||||
"yaml": "^2.7.1",
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
||||
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { CallToolRequestSchema, ListToolsRequestSchema, Tool as McpTool } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { zodToJsonSchema } from 'zod-to-json-schema';
|
||||
|
||||
import { Context } from './context.js';
|
||||
@ -43,8 +43,14 @@ export function createServerWithTools(serverOptions: MCPServerOptions, config: C
|
||||
tools: tools.map(tool => ({
|
||||
name: tool.schema.name,
|
||||
description: tool.schema.description,
|
||||
inputSchema: zodToJsonSchema(tool.schema.inputSchema)
|
||||
})),
|
||||
inputSchema: zodToJsonSchema(tool.schema.inputSchema),
|
||||
annotations: {
|
||||
title: tool.schema.title,
|
||||
readOnlyHint: tool.schema.type === 'readOnly',
|
||||
destructiveHint: tool.schema.type === 'destructive',
|
||||
openWorldHint: true,
|
||||
},
|
||||
})) as McpTool[],
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -22,10 +22,12 @@ const wait: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_wait',
|
||||
title: 'Wait',
|
||||
description: 'Wait for a specified time in seconds',
|
||||
inputSchema: z.object({
|
||||
time: z.number().describe('The time to wait in seconds'),
|
||||
}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -43,8 +45,10 @@ const close = defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_close',
|
||||
title: 'Close browser',
|
||||
description: 'Close the page',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
@ -61,11 +65,13 @@ const resize: ToolFactory = captureSnapshot => defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_resize',
|
||||
title: 'Resize browser window',
|
||||
description: 'Resize the browser window',
|
||||
inputSchema: z.object({
|
||||
width: z.number().describe('Width of the browser window'),
|
||||
height: z.number().describe('Height of the browser window'),
|
||||
}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -21,8 +21,10 @@ const console = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_console_messages',
|
||||
title: 'Get console messages',
|
||||
description: 'Returns all console messages',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
handle: async context => {
|
||||
const messages = context.currentTabOrDie().console();
|
||||
|
@ -22,11 +22,13 @@ const handleDialog: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_handle_dialog',
|
||||
title: 'Handle a dialog',
|
||||
description: 'Handle a dialog',
|
||||
inputSchema: z.object({
|
||||
accept: z.boolean().describe('Whether to accept the dialog.'),
|
||||
promptText: z.string().optional().describe('The text of the prompt in case of a prompt dialog.'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -22,10 +22,12 @@ const uploadFile: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_file_upload',
|
||||
title: 'Upload files',
|
||||
description: 'Upload one or multiple files',
|
||||
inputSchema: z.object({
|
||||
paths: z.array(z.string()).describe('The absolute paths to the files to upload. Can be a single file or multiple files.'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -26,8 +26,10 @@ const install = defineTool({
|
||||
capability: 'install',
|
||||
schema: {
|
||||
name: 'browser_install',
|
||||
title: 'Install the browser specified in the config',
|
||||
description: 'Install the browser specified in the config. Call this if you get an error about the browser not being installed.',
|
||||
inputSchema: z.object({}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
|
@ -22,10 +22,12 @@ const pressKey: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_press_key',
|
||||
title: 'Press a key',
|
||||
description: 'Press a key on the keyboard',
|
||||
inputSchema: z.object({
|
||||
key: z.string().describe('Name of the key to press or a character to generate, such as `ArrowLeft` or `a`'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -22,10 +22,12 @@ const navigate: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_navigate',
|
||||
title: 'Navigate to a URL',
|
||||
description: 'Navigate to a URL',
|
||||
inputSchema: z.object({
|
||||
url: z.string().describe('The URL to navigate to'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -49,8 +51,10 @@ const goBack: ToolFactory = captureSnapshot => defineTool({
|
||||
capability: 'history',
|
||||
schema: {
|
||||
name: 'browser_navigate_back',
|
||||
title: 'Go back',
|
||||
description: 'Go back to the previous page',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
@ -73,8 +77,10 @@ const goForward: ToolFactory = captureSnapshot => defineTool({
|
||||
capability: 'history',
|
||||
schema: {
|
||||
name: 'browser_navigate_forward',
|
||||
title: 'Go forward',
|
||||
description: 'Go forward to the next page',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
handle: async context => {
|
||||
const tab = context.currentTabOrDie();
|
||||
|
@ -24,8 +24,10 @@ const requests = defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_network_requests',
|
||||
title: 'List network requests',
|
||||
description: 'Returns all network requests since loading the page',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
|
@ -25,8 +25,10 @@ const pdf = defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_pdf_save',
|
||||
title: 'Save as PDF',
|
||||
description: 'Save page as PDF',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
|
@ -27,8 +27,10 @@ const screenshot = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_screen_capture',
|
||||
title: 'Take a screenshot',
|
||||
description: 'Take a screenshot of the current page',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
@ -59,11 +61,13 @@ const moveMouse = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_screen_move_mouse',
|
||||
title: 'Move mouse',
|
||||
description: 'Move mouse to a given position',
|
||||
inputSchema: elementSchema.extend({
|
||||
x: z.number().describe('X coordinate'),
|
||||
y: z.number().describe('Y coordinate'),
|
||||
}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -86,11 +90,13 @@ const click = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_screen_click',
|
||||
title: 'Click',
|
||||
description: 'Click left mouse button',
|
||||
inputSchema: elementSchema.extend({
|
||||
x: z.number().describe('X coordinate'),
|
||||
y: z.number().describe('Y coordinate'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -117,9 +123,9 @@ const click = defineTool({
|
||||
|
||||
const drag = defineTool({
|
||||
capability: 'core',
|
||||
|
||||
schema: {
|
||||
name: 'browser_screen_drag',
|
||||
title: 'Drag mouse',
|
||||
description: 'Drag left mouse button',
|
||||
inputSchema: elementSchema.extend({
|
||||
startX: z.number().describe('Start X coordinate'),
|
||||
@ -127,6 +133,7 @@ const drag = defineTool({
|
||||
endX: z.number().describe('End X coordinate'),
|
||||
endY: z.number().describe('End Y coordinate'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -158,14 +165,15 @@ const drag = defineTool({
|
||||
|
||||
const type = defineTool({
|
||||
capability: 'core',
|
||||
|
||||
schema: {
|
||||
name: 'browser_screen_type',
|
||||
title: 'Type text',
|
||||
description: 'Type text',
|
||||
inputSchema: z.object({
|
||||
text: z.string().describe('Text to type into the element'),
|
||||
submit: z.boolean().optional().describe('Whether to submit entered text (press Enter after)'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -26,8 +26,10 @@ const snapshot = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_snapshot',
|
||||
title: 'Page snapshot',
|
||||
description: 'Capture accessibility snapshot of the current page, this is better than screenshot',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
@ -50,8 +52,10 @@ const click = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_click',
|
||||
title: 'Click',
|
||||
description: 'Perform click on a web page',
|
||||
inputSchema: elementSchema,
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -76,6 +80,7 @@ const drag = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_drag',
|
||||
title: 'Drag mouse',
|
||||
description: 'Perform drag and drop between two elements',
|
||||
inputSchema: z.object({
|
||||
startElement: z.string().describe('Human-readable source element description used to obtain the permission to interact with the element'),
|
||||
@ -83,6 +88,7 @@ const drag = defineTool({
|
||||
endElement: z.string().describe('Human-readable target element description used to obtain the permission to interact with the element'),
|
||||
endRef: z.string().describe('Exact target element reference from the page snapshot'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -108,8 +114,10 @@ const hover = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_hover',
|
||||
title: 'Hover mouse',
|
||||
description: 'Hover over element on page',
|
||||
inputSchema: elementSchema,
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -140,8 +148,10 @@ const type = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_type',
|
||||
title: 'Type text',
|
||||
description: 'Type text into editable element',
|
||||
inputSchema: typeSchema,
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -184,8 +194,10 @@ const selectOption = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_select_option',
|
||||
title: 'Select option',
|
||||
description: 'Select an option in a dropdown',
|
||||
inputSchema: selectOptionSchema,
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -221,8 +233,10 @@ const screenshot = defineTool({
|
||||
capability: 'core',
|
||||
schema: {
|
||||
name: 'browser_take_screenshot',
|
||||
title: 'Take a screenshot',
|
||||
description: `Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.`,
|
||||
inputSchema: screenshotSchema,
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -22,8 +22,10 @@ const listTabs = defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_tab_list',
|
||||
title: 'List tabs',
|
||||
description: 'List browser tabs',
|
||||
inputSchema: z.object({}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async context => {
|
||||
@ -47,10 +49,12 @@ const selectTab: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_tab_select',
|
||||
title: 'Select a tab',
|
||||
description: 'Select a tab by index',
|
||||
inputSchema: z.object({
|
||||
index: z.number().describe('The index of the tab to select'),
|
||||
}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -72,10 +76,12 @@ const newTab: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_tab_new',
|
||||
title: 'Open a new tab',
|
||||
description: 'Open a new tab',
|
||||
inputSchema: z.object({
|
||||
url: z.string().optional().describe('The URL to navigate to in the new tab. If not provided, the new tab will be blank.'),
|
||||
}),
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
@ -99,10 +105,12 @@ const closeTab: ToolFactory = captureSnapshot => defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_tab_close',
|
||||
title: 'Close a tab',
|
||||
description: 'Close a tab',
|
||||
inputSchema: z.object({
|
||||
index: z.number().optional().describe('The index of the tab to close. Closes current tab if not provided.'),
|
||||
}),
|
||||
type: 'destructive',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -28,8 +28,10 @@ const generateTest = defineTool({
|
||||
|
||||
schema: {
|
||||
name: 'browser_generate_playwright_test',
|
||||
title: 'Generate a Playwright test',
|
||||
description: 'Generate a Playwright test for given scenario',
|
||||
inputSchema: generateTestSchema,
|
||||
type: 'readOnly',
|
||||
},
|
||||
|
||||
handle: async (context, params) => {
|
||||
|
@ -22,8 +22,10 @@ import type { ToolCapability } from '../../config.js';
|
||||
|
||||
export type ToolSchema<Input extends InputType> = {
|
||||
name: string;
|
||||
title: string;
|
||||
description: string;
|
||||
inputSchema: Input;
|
||||
type: 'readOnly' | 'destructive';
|
||||
};
|
||||
|
||||
type InputType = z.Schema;
|
||||
|
@ -28,6 +28,7 @@ import filesTools from '../lib/tools/files.js';
|
||||
import installTools from '../lib/tools/install.js';
|
||||
import keyboardTools from '../lib/tools/keyboard.js';
|
||||
import navigateTools from '../lib/tools/navigate.js';
|
||||
import networkTools from '../lib/tools/network.js';
|
||||
import pdfTools from '../lib/tools/pdf.js';
|
||||
import snapshotTools from '../lib/tools/snapshot.js';
|
||||
import tabsTools from '../lib/tools/tabs.js';
|
||||
@ -62,6 +63,7 @@ const categories = {
|
||||
...commonTools(true),
|
||||
...installTools,
|
||||
...dialogsTools(true),
|
||||
...networkTools,
|
||||
],
|
||||
'Testing': [
|
||||
...testTools,
|
||||
@ -75,74 +77,37 @@ const kStartMarker = `<!--- Generated by ${path.basename(__filename)} -->`;
|
||||
const kEndMarker = `<!--- End of generated section -->`;
|
||||
|
||||
/**
|
||||
* @param {ParsedToolSchema} tool
|
||||
* @param {import('../src/tools/tool.js').ToolSchema<any>} tool
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatToolForReadme(tool) {
|
||||
const lines = /** @type {string[]} */ ([]);
|
||||
lines.push(`<!-- NOTE: This has been generated via ${path.basename(__filename)} -->\n\n`);
|
||||
lines.push(`- **${tool.name}**\n`);
|
||||
lines.push(` - Title: ${tool.title}\n`);
|
||||
lines.push(` - Description: ${tool.description}\n`);
|
||||
|
||||
if (tool.parameters && tool.parameters.length > 0) {
|
||||
const inputSchema = /** @type {any} */ (zodToJsonSchema(tool.inputSchema || {}));
|
||||
const requiredParams = inputSchema.required || [];
|
||||
if (inputSchema.properties && Object.keys(inputSchema.properties).length) {
|
||||
lines.push(` - Parameters:\n`);
|
||||
tool.parameters.forEach(param => {
|
||||
Object.entries(inputSchema.properties).forEach(([name, param]) => {
|
||||
const optional = !requiredParams.includes(name);
|
||||
const meta = /** @type {string[]} */ ([]);
|
||||
if (param.type)
|
||||
meta.push(param.type);
|
||||
if (param.optional)
|
||||
if (optional)
|
||||
meta.push('optional');
|
||||
lines.push(` - \`${param.name}\` ${meta.length ? `(${meta.join(', ')})` : ''}: ${param.description}\n`);
|
||||
lines.push(` - \`${name}\` ${meta.length ? `(${meta.join(', ')})` : ''}: ${param.description}\n`);
|
||||
});
|
||||
} else {
|
||||
lines.push(` - Parameters: None\n`);
|
||||
}
|
||||
|
||||
lines.push(` - Read-only: **${tool.type === 'readOnly'}**\n`);
|
||||
lines.push('\n');
|
||||
return lines.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* name: any;
|
||||
* description: any;
|
||||
* parameters: {
|
||||
* name: string;
|
||||
* description: string;
|
||||
* optional: boolean;
|
||||
* type: string;
|
||||
* }[];
|
||||
*}} ParsedToolSchema
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {import('../src/tools/tool').ToolSchema<any>} schema
|
||||
* @returns {ParsedToolSchema}
|
||||
*/
|
||||
function processToolSchema(schema) {
|
||||
const inputSchema = /** @type {import('zod-to-json-schema').JsonSchema7ObjectType} */ (zodToJsonSchema(schema.inputSchema || {}));
|
||||
if (inputSchema.type !== 'object')
|
||||
throw new Error(`Tool ${schema.name} input schema is not an object`);
|
||||
|
||||
// In JSON Schema, properties are considered optional unless listed in the required array
|
||||
const requiredParams = inputSchema?.required || [];
|
||||
|
||||
const parameters = Object.entries(inputSchema.properties).map(([name, prop]) => {
|
||||
return {
|
||||
name,
|
||||
description: prop.description || '',
|
||||
optional: !requiredParams.includes(name),
|
||||
type: /** @type {any} */ (prop).type,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
name: schema.name,
|
||||
description: schema.description,
|
||||
parameters
|
||||
};
|
||||
}
|
||||
|
||||
async function updateReadme() {
|
||||
console.log('Loading tool information from compiled modules...');
|
||||
|
||||
@ -154,10 +119,8 @@ async function updateReadme() {
|
||||
|
||||
for (const [category, categoryTools] of Object.entries(categories)) {
|
||||
generatedLines.push(`### ${category}\n\n`);
|
||||
for (const tool of categoryTools) {
|
||||
const scheme = processToolSchema(tool.schema);
|
||||
generatedLines.push(formatToolForReadme(scheme));
|
||||
}
|
||||
for (const tool of categoryTools)
|
||||
generatedLines.push(formatToolForReadme(tool.schema));
|
||||
}
|
||||
|
||||
const readmePath = path.join(path.dirname(__filename), '..', 'README.md');
|
||||
|
Loading…
x
Reference in New Issue
Block a user