Skip to content

Commit b427392

Browse files
authored
feat: add a press_key tool (#458)
Press key can be used to test shortcuts and individual key presses.
1 parent ad307f6 commit b427392

File tree

5 files changed

+417
-2
lines changed

5 files changed

+417
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,14 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
238238

239239
<!-- BEGIN AUTO GENERATED TOOLS -->
240240

241-
- **Input automation** (7 tools)
241+
- **Input automation** (8 tools)
242242
- [`click`](docs/tool-reference.md#click)
243243
- [`drag`](docs/tool-reference.md#drag)
244244
- [`fill`](docs/tool-reference.md#fill)
245245
- [`fill_form`](docs/tool-reference.md#fill_form)
246246
- [`handle_dialog`](docs/tool-reference.md#handle_dialog)
247247
- [`hover`](docs/tool-reference.md#hover)
248+
- [`press_key`](docs/tool-reference.md#press_key)
248249
- [`upload_file`](docs/tool-reference.md#upload_file)
249250
- **Navigation automation** (7 tools)
250251
- [`close_page`](docs/tool-reference.md#close_page)

docs/tool-reference.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
# Chrome DevTools MCP Tool Reference
44

5-
- **[Input automation](#input-automation)** (7 tools)
5+
- **[Input automation](#input-automation)** (8 tools)
66
- [`click`](#click)
77
- [`drag`](#drag)
88
- [`fill`](#fill)
99
- [`fill_form`](#fill_form)
1010
- [`handle_dialog`](#handle_dialog)
1111
- [`hover`](#hover)
12+
- [`press_key`](#press_key)
1213
- [`upload_file`](#upload_file)
1314
- **[Navigation automation](#navigation-automation)** (7 tools)
1415
- [`close_page`](#close_page)
@@ -102,6 +103,16 @@
102103

103104
---
104105

106+
### `press_key`
107+
108+
**Description:** Press a key or key combination. Use this when other input methods like [`fill`](#fill)() cannot be used (e.g., keyboard shortcuts, navigation keys, or special key combinations).
109+
110+
**Parameters:**
111+
112+
- **key** (string) **(required)**: A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta
113+
114+
---
115+
105116
### `upload_file`
106117

107118
**Description:** Upload a file through a provided element.

src/tools/input.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import type {McpContext, TextSnapshotNode} from '../McpContext.js';
88
import {zod} from '../third_party/index.js';
99
import type {ElementHandle} from '../third_party/index.js';
10+
import {parseKey} from '../utils/keyboard.js';
1011

1112
import {ToolCategory} from './categories.js';
1213
import {defineTool} from './ToolDefinition.js';
@@ -270,3 +271,39 @@ export const uploadFile = defineTool({
270271
}
271272
},
272273
});
274+
275+
export const pressKey = defineTool({
276+
name: 'press_key',
277+
description: `Press a key or key combination. Use this when other input methods like fill() cannot be used (e.g., keyboard shortcuts, navigation keys, or special key combinations).`,
278+
annotations: {
279+
category: ToolCategory.INPUT,
280+
readOnlyHint: false,
281+
},
282+
schema: {
283+
key: zod
284+
.string()
285+
.describe(
286+
'A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta',
287+
),
288+
},
289+
handler: async (request, response, context) => {
290+
const page = context.getSelectedPage();
291+
const tokens = parseKey(request.params.key);
292+
const [key, ...modifiers] = tokens;
293+
294+
await context.waitForEventsAfterAction(async () => {
295+
for (const modifier of modifiers) {
296+
await page.keyboard.down(modifier);
297+
}
298+
await page.keyboard.press(key);
299+
for (const modifier of modifiers.toReversed()) {
300+
await page.keyboard.up(modifier);
301+
}
302+
});
303+
304+
response.appendResponseLine(
305+
`Successfully pressed key: ${request.params.key}`,
306+
);
307+
response.setIncludeSnapshot(true);
308+
},
309+
});

0 commit comments

Comments
 (0)