diff --git a/README.md b/README.md
index 462fd43..3f281f8 100644
--- a/README.md
+++ b/README.md
@@ -276,38 +276,47 @@ X Y coordinate space, based on the provided screenshot.
- **browser_snapshot**
+ - Title: Page snapshot
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
- Parameters: None
+ - Read-only: **true**
- **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**
- **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**
- **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**
- **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**
- **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**
- **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
- **browser_screen_capture**
+ - Title: Take a screenshot
- Description: Take a screenshot of the current page
- Parameters: None
+ - Read-only: **true**
- **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**
- **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**
- **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**
- **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
- **browser_tab_list**
+ - Title: List tabs
- Description: List browser tabs
- Parameters: None
+ - Read-only: **true**
- **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**
- **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**
- **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
- **browser_navigate**
+ - Title: Navigate to a URL
- Description: Navigate to a URL
- Parameters:
- `url` (string): The URL to navigate to
+ - Read-only: **false**
- **browser_navigate_back**
+ - Title: Go back
- Description: Go back to the previous page
- Parameters: None
+ - Read-only: **true**
- **browser_navigate_forward**
+ - Title: Go forward
- Description: Go forward to the next page
- Parameters: None
+ - Read-only: **true**
### Keyboard
- **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
- **browser_console_messages**
+ - Title: Get console messages
- Description: Returns all console messages
- Parameters: None
+ - Read-only: **true**
### Files and Media
- **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**
- **browser_pdf_save**
+ - Title: Save as PDF
- Description: Save page as PDF
- Parameters: None
+ - Read-only: **true**
### Utilities
- **browser_close**
+ - Title: Close browser
- Description: Close the page
- Parameters: None
+ - Read-only: **true**
- **browser_wait**
+ - Title: Wait
- Description: Wait for a specified time in seconds
- Parameters:
- `time` (number): The time to wait in seconds
+ - Read-only: **true**
- **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**
- **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**
- **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**
+
+
+
+- **browser_network_requests**
+ - Title: List network requests
+ - Description: Returns all network requests since loading the page
+ - Parameters: None
+ - Read-only: **true**
### Testing
- **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**
diff --git a/package-lock.json b/package-lock.json
index b5dff03..f684c63 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index df49b9c..65da207 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/server.ts b/src/server.ts
index 5e7da17..405af78 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -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[],
};
});
diff --git a/src/tools/common.ts b/src/tools/common.ts
index a615f0d..40c7e3f 100644
--- a/src/tools/common.ts
+++ b/src/tools/common.ts
@@ -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) => {
diff --git a/src/tools/console.ts b/src/tools/console.ts
index b0c58f5..2779e34 100644
--- a/src/tools/console.ts
+++ b/src/tools/console.ts
@@ -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();
diff --git a/src/tools/dialogs.ts b/src/tools/dialogs.ts
index 62105cc..348e461 100644
--- a/src/tools/dialogs.ts
+++ b/src/tools/dialogs.ts
@@ -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) => {
diff --git a/src/tools/files.ts b/src/tools/files.ts
index 4ab6d3f..2dc7837 100644
--- a/src/tools/files.ts
+++ b/src/tools/files.ts
@@ -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) => {
diff --git a/src/tools/install.ts b/src/tools/install.ts
index f9b16ad..afa3247 100644
--- a/src/tools/install.ts
+++ b/src/tools/install.ts
@@ -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 => {
diff --git a/src/tools/keyboard.ts b/src/tools/keyboard.ts
index 0527cbf..521aab2 100644
--- a/src/tools/keyboard.ts
+++ b/src/tools/keyboard.ts
@@ -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) => {
diff --git a/src/tools/navigate.ts b/src/tools/navigate.ts
index 1279418..501576e 100644
--- a/src/tools/navigate.ts
+++ b/src/tools/navigate.ts
@@ -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();
diff --git a/src/tools/network.ts b/src/tools/network.ts
index e9499e2..9e1946c 100644
--- a/src/tools/network.ts
+++ b/src/tools/network.ts
@@ -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 => {
diff --git a/src/tools/pdf.ts b/src/tools/pdf.ts
index 79dca64..ff2465b 100644
--- a/src/tools/pdf.ts
+++ b/src/tools/pdf.ts
@@ -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 => {
diff --git a/src/tools/screen.ts b/src/tools/screen.ts
index 88ca40c..a380311 100644
--- a/src/tools/screen.ts
+++ b/src/tools/screen.ts
@@ -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) => {
diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts
index b0a4bd1..b969b88 100644
--- a/src/tools/snapshot.ts
+++ b/src/tools/snapshot.ts
@@ -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) => {
diff --git a/src/tools/tabs.ts b/src/tools/tabs.ts
index f2226da..4133bf1 100644
--- a/src/tools/tabs.ts
+++ b/src/tools/tabs.ts
@@ -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) => {
diff --git a/src/tools/testing.ts b/src/tools/testing.ts
index 3046cde..9518d19 100644
--- a/src/tools/testing.ts
+++ b/src/tools/testing.ts
@@ -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) => {
diff --git a/src/tools/tool.ts b/src/tools/tool.ts
index 84e9bce..4b88c89 100644
--- a/src/tools/tool.ts
+++ b/src/tools/tool.ts
@@ -22,8 +22,10 @@ import type { ToolCapability } from '../../config.js';
export type ToolSchema = {
name: string;
+ title: string;
description: string;
inputSchema: Input;
+ type: 'readOnly' | 'destructive';
};
type InputType = z.Schema;
diff --git a/utils/update-readme.js b/utils/update-readme.js
index 35d5e63..d0f6cea 100644
--- a/utils/update-readme.js
+++ b/utils/update-readme.js
@@ -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 = ``;
const kEndMarker = ``;
/**
- * @param {ParsedToolSchema} tool
+ * @param {import('../src/tools/tool.js').ToolSchema} tool
* @returns {string}
*/
function formatToolForReadme(tool) {
const lines = /** @type {string[]} */ ([]);
lines.push(`\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} 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');