@testdriverai/mcp 7.11.177-test → 7.11.178-test
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.
- package/docs/_data/examples-manifest.json +40 -40
- package/docs/examples/assert.mdx +1 -1
- package/docs/examples/element-not-found.mdx +1 -1
- package/docs/examples/findall-coffee-icons.mdx +1 -1
- package/docs/examples/hover-image.mdx +1 -1
- package/docs/examples/hover-text-with-description.mdx +1 -1
- package/docs/examples/hover-text.mdx +1 -1
- package/docs/examples/installer.mdx +1 -1
- package/docs/examples/launch-vscode-linux.mdx +1 -1
- package/docs/examples/parse.mdx +1 -1
- package/docs/examples/press-keys.mdx +1 -1
- package/docs/examples/scroll-keyboard.mdx +1 -1
- package/docs/examples/scroll.mdx +1 -1
- package/docs/examples/type.mdx +1 -1
- package/mcp-server/dist/mcp-app.html +15 -15
- package/mcp-server/dist/server.mjs +22 -0
- package/mcp-server/mcp-app.html +1 -1
- package/mcp-server/src/mcp-app.css +3 -5
- package/mcp-server/src/mcp-app.ts +26 -5
- package/mcp-server/src/server.ts +22 -0
- package/package.json +1 -1
|
@@ -511,6 +511,7 @@ function buildServer() {
|
|
|
511
511
|
// Session Start
|
|
512
512
|
registerAppTool(server, "session_start", {
|
|
513
513
|
title: "Session Start",
|
|
514
|
+
annotations: { title: "Session Start", readOnlyHint: false, destructiveHint: true },
|
|
514
515
|
description: `Start a new TestDriver session and provision a sandbox with browser or app.
|
|
515
516
|
|
|
516
517
|
⚠️ IMPORTANT - Test File Parameter:
|
|
@@ -644,6 +645,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
644
645
|
});
|
|
645
646
|
// Session Status
|
|
646
647
|
server.registerTool("session_status", {
|
|
648
|
+
annotations: { title: "Session Status", readOnlyHint: true },
|
|
647
649
|
description: "Check the current session status and time remaining",
|
|
648
650
|
inputSchema: z.object({}),
|
|
649
651
|
}, async () => {
|
|
@@ -661,6 +663,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
661
663
|
});
|
|
662
664
|
// Session Extend
|
|
663
665
|
server.registerTool("session_extend", {
|
|
666
|
+
annotations: { title: "Session Extend", readOnlyHint: false, destructiveHint: false },
|
|
664
667
|
description: "Extend the session keepAlive time",
|
|
665
668
|
inputSchema: z.object({
|
|
666
669
|
additionalMs: z.number().default(60000).describe("Additional time in ms"),
|
|
@@ -686,6 +689,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
686
689
|
// Find Element
|
|
687
690
|
registerAppTool(server, "find", {
|
|
688
691
|
title: "Find Element",
|
|
692
|
+
annotations: { title: "Find Element", readOnlyHint: true },
|
|
689
693
|
description: "Find an element on screen by natural language description",
|
|
690
694
|
inputSchema: z.object({
|
|
691
695
|
description: z.string().describe("Natural language description of the element"),
|
|
@@ -726,6 +730,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
726
730
|
// Find All Elements
|
|
727
731
|
registerAppTool(server, "findall", {
|
|
728
732
|
title: "Find All Elements",
|
|
733
|
+
annotations: { title: "Find All Elements", readOnlyHint: true },
|
|
729
734
|
description: "Find all elements on screen matching a natural language description. Returns an array of element references.",
|
|
730
735
|
inputSchema: z.object({
|
|
731
736
|
description: z.string().describe("Natural language description of the elements to find"),
|
|
@@ -766,6 +771,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
766
771
|
// Click
|
|
767
772
|
registerAppTool(server, "click", {
|
|
768
773
|
title: "Click Element",
|
|
774
|
+
annotations: { title: "Click Element", readOnlyHint: false, destructiveHint: true },
|
|
769
775
|
description: "Click on a previously found element. Use 'find' first to locate the element.",
|
|
770
776
|
inputSchema: z.object({
|
|
771
777
|
elementRef: z.string().describe("Reference to previously found element (required). Get this from a 'find' call."),
|
|
@@ -795,6 +801,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
795
801
|
// Hover
|
|
796
802
|
registerAppTool(server, "hover", {
|
|
797
803
|
title: "Hover Element",
|
|
804
|
+
annotations: { title: "Hover Element", readOnlyHint: true },
|
|
798
805
|
description: "Hover over a previously found element. Use 'find' first to locate the element.",
|
|
799
806
|
inputSchema: z.object({
|
|
800
807
|
elementRef: z.string().describe("Reference to previously found element (required). Get this from a 'find' call."),
|
|
@@ -822,6 +829,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
822
829
|
});
|
|
823
830
|
// Wait
|
|
824
831
|
server.registerTool("wait", {
|
|
832
|
+
annotations: { title: "Wait", readOnlyHint: true },
|
|
825
833
|
description: "Wait for a specified amount of time",
|
|
826
834
|
inputSchema: z.object({
|
|
827
835
|
timeout: z.number().default(3000).describe("Time to wait in milliseconds (default: 3000)"),
|
|
@@ -848,6 +856,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
848
856
|
});
|
|
849
857
|
// Focus Application
|
|
850
858
|
server.registerTool("focus_application", {
|
|
859
|
+
annotations: { title: "Focus Application", readOnlyHint: false, destructiveHint: true },
|
|
851
860
|
description: "Bring an application window to the foreground",
|
|
852
861
|
inputSchema: z.object({
|
|
853
862
|
name: z.string().describe("Name of the application to focus (e.g., 'Google Chrome', 'Visual Studio Code')"),
|
|
@@ -875,6 +884,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
875
884
|
// Find and Click
|
|
876
885
|
registerAppTool(server, "find_and_click", {
|
|
877
886
|
title: "Find and Click",
|
|
887
|
+
annotations: { title: "Find and Click", readOnlyHint: false, destructiveHint: true },
|
|
878
888
|
description: "Find an element and click it in one action",
|
|
879
889
|
inputSchema: z.object({
|
|
880
890
|
description: z.string().describe("Natural language description of element"),
|
|
@@ -914,6 +924,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
914
924
|
});
|
|
915
925
|
// Type
|
|
916
926
|
server.registerTool("type", {
|
|
927
|
+
annotations: { title: "Type Text", readOnlyHint: false, destructiveHint: true },
|
|
917
928
|
description: "Type text into the currently focused field",
|
|
918
929
|
inputSchema: z.object({
|
|
919
930
|
text: z.string().describe("Text to type"),
|
|
@@ -942,6 +953,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
942
953
|
});
|
|
943
954
|
// Press Keys
|
|
944
955
|
server.registerTool("press_keys", {
|
|
956
|
+
annotations: { title: "Press Keys", readOnlyHint: false, destructiveHint: true },
|
|
945
957
|
description: "Press keyboard keys or shortcuts",
|
|
946
958
|
inputSchema: z.object({
|
|
947
959
|
keys: z.array(z.string()).describe("Array of keys to press (e.g., ['ctrl', 'a'])"),
|
|
@@ -968,6 +980,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
968
980
|
});
|
|
969
981
|
// Scroll
|
|
970
982
|
server.registerTool("scroll", {
|
|
983
|
+
annotations: { title: "Scroll", readOnlyHint: false, destructiveHint: true },
|
|
971
984
|
description: "Scroll the page or element",
|
|
972
985
|
inputSchema: z.object({
|
|
973
986
|
direction: z.enum(["up", "down", "left", "right"]).default("down"),
|
|
@@ -995,6 +1008,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
995
1008
|
});
|
|
996
1009
|
// Assert - generates code for test files
|
|
997
1010
|
server.registerTool("assert", {
|
|
1011
|
+
annotations: { title: "Assert", readOnlyHint: true },
|
|
998
1012
|
description: `Make an AI-powered assertion about the current screen state. GENERATES CODE for the test file.
|
|
999
1013
|
|
|
1000
1014
|
Use this when you want a verification step recorded in the generated test. This will add code like:
|
|
@@ -1028,6 +1042,7 @@ Unlike 'check' which is for your understanding during development, 'assert' crea
|
|
|
1028
1042
|
// Check - AI uses this to understand the screen state (DOES NOT generate code)
|
|
1029
1043
|
registerAppTool(server, "check", {
|
|
1030
1044
|
title: "Check Screen State",
|
|
1045
|
+
annotations: { title: "Check Screen State", readOnlyHint: true },
|
|
1031
1046
|
description: `👁️ THIS IS HOW YOU SEE THE SCREEN. Use this tool whenever you need to understand what's currently displayed.
|
|
1032
1047
|
|
|
1033
1048
|
This tool captures a screenshot and returns AI analysis to YOU. Use it to:
|
|
@@ -1116,6 +1131,7 @@ You can optionally provide a reference image URI to compare against a previous s
|
|
|
1116
1131
|
});
|
|
1117
1132
|
// Exec
|
|
1118
1133
|
server.registerTool("exec", {
|
|
1134
|
+
annotations: { title: "Execute Command", readOnlyHint: false, destructiveHint: true },
|
|
1119
1135
|
description: "Execute shell or PowerShell commands in the sandbox",
|
|
1120
1136
|
inputSchema: z.object({
|
|
1121
1137
|
language: z.enum(["sh", "pwsh"]).default("sh"),
|
|
@@ -1158,6 +1174,7 @@ You can optionally provide a reference image URI to compare against a previous s
|
|
|
1158
1174
|
}
|
|
1159
1175
|
// List Local Screenshots - lists screenshots saved to .testdriver directory
|
|
1160
1176
|
server.registerTool("list_local_screenshots", {
|
|
1177
|
+
annotations: { title: "List Local Screenshots", readOnlyHint: true },
|
|
1161
1178
|
description: `List and filter screenshots saved in the .testdriver directory.
|
|
1162
1179
|
|
|
1163
1180
|
Screenshots from auto-screenshot feature use the format: <seq>-<action>-<phase>-L<line>-<description>.png
|
|
@@ -1378,6 +1395,7 @@ Returns a list of screenshot paths that can be viewed with the 'view_local_scree
|
|
|
1378
1395
|
// Also displays to the user via MCP App
|
|
1379
1396
|
registerAppTool(server, "view_local_screenshot", {
|
|
1380
1397
|
title: "View Local Screenshot",
|
|
1398
|
+
annotations: { title: "View Local Screenshot", readOnlyHint: true },
|
|
1381
1399
|
description: `View a screenshot from the .testdriver directory.
|
|
1382
1400
|
|
|
1383
1401
|
Use 'list_local_screenshots' first to see available screenshots, then use this tool to view one.
|
|
@@ -1457,6 +1475,7 @@ Useful for:
|
|
|
1457
1475
|
// Use 'check' tool for AI to understand screen state.
|
|
1458
1476
|
registerAppTool(server, "screenshot", {
|
|
1459
1477
|
title: "Screenshot",
|
|
1478
|
+
annotations: { title: "Screenshot", readOnlyHint: true },
|
|
1460
1479
|
description: `Display a screenshot to the user. This tool does NOT return the image to you (the AI).
|
|
1461
1480
|
|
|
1462
1481
|
⚠️ IMPORTANT: Do NOT use this tool to understand the screen state. The screenshot is ONLY displayed to the human user - you will NOT receive the image or any analysis.
|
|
@@ -1497,6 +1516,7 @@ Only use 'screenshot' when you explicitly want to show something to the human us
|
|
|
1497
1516
|
});
|
|
1498
1517
|
// Init - Initialize a new TestDriver project
|
|
1499
1518
|
server.registerTool("init", {
|
|
1519
|
+
annotations: { title: "Initialize Project", readOnlyHint: false, destructiveHint: true },
|
|
1500
1520
|
description: `Initialize a new TestDriver project with Vitest SDK examples.
|
|
1501
1521
|
|
|
1502
1522
|
This creates:
|
|
@@ -1576,6 +1596,7 @@ Learn more at https://docs.testdriver.ai/v7/getting-started/
|
|
|
1576
1596
|
// the caller's team by their OAuth token (hosted mode) or env API key.
|
|
1577
1597
|
// =============================================================================
|
|
1578
1598
|
server.registerTool("list_test_runs", {
|
|
1599
|
+
annotations: { title: "List Test Runs", readOnlyHint: true },
|
|
1579
1600
|
description: "List recent TestDriver test runs for the current team.",
|
|
1580
1601
|
inputSchema: z.object({
|
|
1581
1602
|
page: z.number().optional().describe("Page number (1-indexed)"),
|
|
@@ -1598,6 +1619,7 @@ Learn more at https://docs.testdriver.ai/v7/getting-started/
|
|
|
1598
1619
|
}
|
|
1599
1620
|
});
|
|
1600
1621
|
server.registerTool("get_test_run_detail", {
|
|
1622
|
+
annotations: { title: "Get Test Run Detail", readOnlyHint: true },
|
|
1601
1623
|
description: "Get details for a single TestDriver test run, including its test cases.",
|
|
1602
1624
|
inputSchema: z.object({
|
|
1603
1625
|
id: z.string().describe("The test run id"),
|
package/mcp-server/mcp-app.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<div class="screenshot-wrapper">
|
|
12
12
|
<div class="loading-overlay" id="loading-overlay">
|
|
13
13
|
<div class="loading-spinner"></div>
|
|
14
|
-
<span class="loading-text">
|
|
14
|
+
<span class="loading-text">Connecting to session...</span>
|
|
15
15
|
</div>
|
|
16
16
|
<div class="screenshot-container" id="screenshot-container" style="display: none;">
|
|
17
17
|
<img id="screenshot" alt="Screenshot" />
|
|
@@ -62,7 +62,7 @@ body {
|
|
|
62
62
|
width: 32px;
|
|
63
63
|
height: 32px;
|
|
64
64
|
border: 3px solid var(--color-border-primary, #e5e5e5);
|
|
65
|
-
border-top-color: #
|
|
65
|
+
border-top-color: #b3d334;
|
|
66
66
|
border-radius: 50%;
|
|
67
67
|
animation: spin 0.8s linear infinite;
|
|
68
68
|
}
|
|
@@ -99,8 +99,8 @@ body {
|
|
|
99
99
|
position: absolute;
|
|
100
100
|
top: 0;
|
|
101
101
|
left: 0;
|
|
102
|
-
width:
|
|
103
|
-
height:
|
|
102
|
+
width: 0;
|
|
103
|
+
height: 0;
|
|
104
104
|
pointer-events: none;
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -231,7 +231,6 @@ body {
|
|
|
231
231
|
align-items: center;
|
|
232
232
|
padding: 8px 12px;
|
|
233
233
|
background: var(--color-background-secondary, #f5f5f5);
|
|
234
|
-
border-top: 1px solid var(--color-border-primary, #e5e5e5);
|
|
235
234
|
font-size: var(--font-text-xs-size, 12px);
|
|
236
235
|
}
|
|
237
236
|
|
|
@@ -265,7 +264,6 @@ body {
|
|
|
265
264
|
.target-info {
|
|
266
265
|
padding: 8px 12px;
|
|
267
266
|
background: var(--color-background-secondary, #f5f5f5);
|
|
268
|
-
border-bottom: 1px solid var(--color-border-primary, #e5e5e5);
|
|
269
267
|
font-size: var(--font-text-sm-size, 14px);
|
|
270
268
|
color: var(--color-text-primary, #1a1a1a);
|
|
271
269
|
}
|
|
@@ -219,6 +219,12 @@ function addOverlays(data: ToolResultData) {
|
|
|
219
219
|
setTimeout(() => addOverlays(data), 50);
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
|
+
|
|
223
|
+
// Align overlay layer to the image box so coordinates stay accurate when centered
|
|
224
|
+
overlaysEl.style.left = `${screenshotEl.offsetLeft}px`;
|
|
225
|
+
overlaysEl.style.top = `${screenshotEl.offsetTop}px`;
|
|
226
|
+
overlaysEl.style.width = `${displayedWidth}px`;
|
|
227
|
+
overlaysEl.style.height = `${displayedHeight}px`;
|
|
222
228
|
|
|
223
229
|
// Track the focal point for zoom
|
|
224
230
|
let focalX: number | undefined;
|
|
@@ -384,15 +390,25 @@ function renderResult(data: ToolResultData) {
|
|
|
384
390
|
// Update target info for find/find_and_click actions
|
|
385
391
|
if (data.element && (data.action === "find" || data.action === "find_and_click")) {
|
|
386
392
|
const el = data.element;
|
|
387
|
-
|
|
393
|
+
targetInfoEl.replaceChildren();
|
|
394
|
+
|
|
395
|
+
const labelEl = document.createElement("strong");
|
|
396
|
+
labelEl.textContent = "Target:";
|
|
397
|
+
targetInfoEl.append(labelEl, ` ${el.description || "Element"}`);
|
|
398
|
+
|
|
388
399
|
if (el.centerX !== undefined && el.centerY !== undefined) {
|
|
389
|
-
|
|
400
|
+
const coordsEl = document.createElement("span");
|
|
401
|
+
coordsEl.className = "target-coords";
|
|
402
|
+
coordsEl.textContent = `(${Math.round(el.centerX)}, ${Math.round(el.centerY)})`;
|
|
403
|
+
targetInfoEl.append(" ", coordsEl);
|
|
390
404
|
}
|
|
391
405
|
if (el.confidence !== undefined) {
|
|
392
406
|
const confidencePercent = Math.round(el.confidence * 100);
|
|
393
|
-
|
|
407
|
+
const confidenceEl = document.createElement("span");
|
|
408
|
+
confidenceEl.className = `target-confidence ${confidencePercent >= 70 ? 'high' : confidencePercent >= 40 ? 'medium' : 'low'}`;
|
|
409
|
+
confidenceEl.textContent = `${confidencePercent}%`;
|
|
410
|
+
targetInfoEl.append(" ", confidenceEl);
|
|
394
411
|
}
|
|
395
|
-
targetInfoEl.innerHTML = targetHtml;
|
|
396
412
|
targetInfoEl.classList.remove("hidden");
|
|
397
413
|
} else {
|
|
398
414
|
targetInfoEl.classList.add("hidden");
|
|
@@ -413,7 +429,7 @@ function renderResult(data: ToolResultData) {
|
|
|
413
429
|
screenshotNaturalWidth = screenshotEl.naturalWidth;
|
|
414
430
|
screenshotNaturalHeight = screenshotEl.naturalHeight;
|
|
415
431
|
// Show the container and add overlays now that we know dimensions
|
|
416
|
-
containerEl.style.display = "
|
|
432
|
+
containerEl.style.display = "flex";
|
|
417
433
|
addOverlays(data);
|
|
418
434
|
// Hide loading state
|
|
419
435
|
hideLoading();
|
|
@@ -531,11 +547,16 @@ app.onerror = (error) => {
|
|
|
531
547
|
app.onhostcontextchanged = handleHostContextChanged;
|
|
532
548
|
|
|
533
549
|
// 3. Connect to host
|
|
550
|
+
showLoading("Connecting to session...");
|
|
534
551
|
app.connect().then(() => {
|
|
552
|
+
showLoading("Waiting for first action...");
|
|
535
553
|
const ctx = app.getHostContext();
|
|
536
554
|
if (ctx) {
|
|
537
555
|
handleHostContextChanged(ctx);
|
|
538
556
|
}
|
|
557
|
+
}).catch((error) => {
|
|
558
|
+
console.error("Failed to connect to host:", error);
|
|
559
|
+
showLoading("Connection failed");
|
|
539
560
|
});
|
|
540
561
|
|
|
541
562
|
// Insert target info element after screenshot wrapper
|
package/mcp-server/src/server.ts
CHANGED
|
@@ -672,6 +672,7 @@ registerAppTool(
|
|
|
672
672
|
"session_start",
|
|
673
673
|
{
|
|
674
674
|
title: "Session Start",
|
|
675
|
+
annotations: { title: "Session Start", readOnlyHint: false, destructiveHint: true },
|
|
675
676
|
description: `Start a new TestDriver session and provision a sandbox with browser or app.
|
|
676
677
|
|
|
677
678
|
⚠️ IMPORTANT - Test File Parameter:
|
|
@@ -825,6 +826,7 @@ IMPORTANT - If creating a new test project, use these EXACT dependencies in pack
|
|
|
825
826
|
server.registerTool(
|
|
826
827
|
"session_status",
|
|
827
828
|
{
|
|
829
|
+
annotations: { title: "Session Status", readOnlyHint: true },
|
|
828
830
|
description: "Check the current session status and time remaining",
|
|
829
831
|
inputSchema: z.object({}),
|
|
830
832
|
},
|
|
@@ -849,6 +851,7 @@ server.registerTool(
|
|
|
849
851
|
server.registerTool(
|
|
850
852
|
"session_extend",
|
|
851
853
|
{
|
|
854
|
+
annotations: { title: "Session Extend", readOnlyHint: false, destructiveHint: false },
|
|
852
855
|
description: "Extend the session keepAlive time",
|
|
853
856
|
inputSchema: z.object({
|
|
854
857
|
additionalMs: z.number().default(60000).describe("Additional time in ms"),
|
|
@@ -884,6 +887,7 @@ registerAppTool(
|
|
|
884
887
|
"find",
|
|
885
888
|
{
|
|
886
889
|
title: "Find Element",
|
|
890
|
+
annotations: { title: "Find Element", readOnlyHint: true },
|
|
887
891
|
description: "Find an element on screen by natural language description",
|
|
888
892
|
inputSchema: z.object({
|
|
889
893
|
description: z.string().describe("Natural language description of the element"),
|
|
@@ -930,6 +934,7 @@ registerAppTool(
|
|
|
930
934
|
"findall",
|
|
931
935
|
{
|
|
932
936
|
title: "Find All Elements",
|
|
937
|
+
annotations: { title: "Find All Elements", readOnlyHint: true },
|
|
933
938
|
description: "Find all elements on screen matching a natural language description. Returns an array of element references.",
|
|
934
939
|
inputSchema: z.object({
|
|
935
940
|
description: z.string().describe("Natural language description of the elements to find"),
|
|
@@ -976,6 +981,7 @@ registerAppTool(
|
|
|
976
981
|
"click",
|
|
977
982
|
{
|
|
978
983
|
title: "Click Element",
|
|
984
|
+
annotations: { title: "Click Element", readOnlyHint: false, destructiveHint: true },
|
|
979
985
|
description: "Click on a previously found element. Use 'find' first to locate the element.",
|
|
980
986
|
inputSchema: z.object({
|
|
981
987
|
elementRef: z.string().describe("Reference to previously found element (required). Get this from a 'find' call."),
|
|
@@ -1013,6 +1019,7 @@ registerAppTool(
|
|
|
1013
1019
|
"hover",
|
|
1014
1020
|
{
|
|
1015
1021
|
title: "Hover Element",
|
|
1022
|
+
annotations: { title: "Hover Element", readOnlyHint: true },
|
|
1016
1023
|
description: "Hover over a previously found element. Use 'find' first to locate the element.",
|
|
1017
1024
|
inputSchema: z.object({
|
|
1018
1025
|
elementRef: z.string().describe("Reference to previously found element (required). Get this from a 'find' call."),
|
|
@@ -1047,6 +1054,7 @@ registerAppTool(
|
|
|
1047
1054
|
server.registerTool(
|
|
1048
1055
|
"wait",
|
|
1049
1056
|
{
|
|
1057
|
+
annotations: { title: "Wait", readOnlyHint: true },
|
|
1050
1058
|
description: "Wait for a specified amount of time",
|
|
1051
1059
|
inputSchema: z.object({
|
|
1052
1060
|
timeout: z.number().default(3000).describe("Time to wait in milliseconds (default: 3000)"),
|
|
@@ -1080,6 +1088,7 @@ server.registerTool(
|
|
|
1080
1088
|
server.registerTool(
|
|
1081
1089
|
"focus_application",
|
|
1082
1090
|
{
|
|
1091
|
+
annotations: { title: "Focus Application", readOnlyHint: false, destructiveHint: true },
|
|
1083
1092
|
description: "Bring an application window to the foreground",
|
|
1084
1093
|
inputSchema: z.object({
|
|
1085
1094
|
name: z.string().describe("Name of the application to focus (e.g., 'Google Chrome', 'Visual Studio Code')"),
|
|
@@ -1115,6 +1124,7 @@ registerAppTool(
|
|
|
1115
1124
|
"find_and_click",
|
|
1116
1125
|
{
|
|
1117
1126
|
title: "Find and Click",
|
|
1127
|
+
annotations: { title: "Find and Click", readOnlyHint: false, destructiveHint: true },
|
|
1118
1128
|
description: "Find an element and click it in one action",
|
|
1119
1129
|
inputSchema: z.object({
|
|
1120
1130
|
description: z.string().describe("Natural language description of element"),
|
|
@@ -1159,6 +1169,7 @@ registerAppTool(
|
|
|
1159
1169
|
server.registerTool(
|
|
1160
1170
|
"type",
|
|
1161
1171
|
{
|
|
1172
|
+
annotations: { title: "Type Text", readOnlyHint: false, destructiveHint: true },
|
|
1162
1173
|
description: "Type text into the currently focused field",
|
|
1163
1174
|
inputSchema: z.object({
|
|
1164
1175
|
text: z.string().describe("Text to type"),
|
|
@@ -1194,6 +1205,7 @@ server.registerTool(
|
|
|
1194
1205
|
server.registerTool(
|
|
1195
1206
|
"press_keys",
|
|
1196
1207
|
{
|
|
1208
|
+
annotations: { title: "Press Keys", readOnlyHint: false, destructiveHint: true },
|
|
1197
1209
|
description: "Press keyboard keys or shortcuts",
|
|
1198
1210
|
inputSchema: z.object({
|
|
1199
1211
|
keys: z.array(z.string()).describe("Array of keys to press (e.g., ['ctrl', 'a'])"),
|
|
@@ -1227,6 +1239,7 @@ server.registerTool(
|
|
|
1227
1239
|
server.registerTool(
|
|
1228
1240
|
"scroll",
|
|
1229
1241
|
{
|
|
1242
|
+
annotations: { title: "Scroll", readOnlyHint: false, destructiveHint: true },
|
|
1230
1243
|
description: "Scroll the page or element",
|
|
1231
1244
|
inputSchema: z.object({
|
|
1232
1245
|
direction: z.enum(["up", "down", "left", "right"]).default("down"),
|
|
@@ -1261,6 +1274,7 @@ server.registerTool(
|
|
|
1261
1274
|
server.registerTool(
|
|
1262
1275
|
"assert",
|
|
1263
1276
|
{
|
|
1277
|
+
annotations: { title: "Assert", readOnlyHint: true },
|
|
1264
1278
|
description: `Make an AI-powered assertion about the current screen state. GENERATES CODE for the test file.
|
|
1265
1279
|
|
|
1266
1280
|
Use this when you want a verification step recorded in the generated test. This will add code like:
|
|
@@ -1302,6 +1316,7 @@ registerAppTool(
|
|
|
1302
1316
|
"check",
|
|
1303
1317
|
{
|
|
1304
1318
|
title: "Check Screen State",
|
|
1319
|
+
annotations: { title: "Check Screen State", readOnlyHint: true },
|
|
1305
1320
|
description: `👁️ THIS IS HOW YOU SEE THE SCREEN. Use this tool whenever you need to understand what's currently displayed.
|
|
1306
1321
|
|
|
1307
1322
|
This tool captures a screenshot and returns AI analysis to YOU. Use it to:
|
|
@@ -1398,6 +1413,7 @@ You can optionally provide a reference image URI to compare against a previous s
|
|
|
1398
1413
|
server.registerTool(
|
|
1399
1414
|
"exec",
|
|
1400
1415
|
{
|
|
1416
|
+
annotations: { title: "Execute Command", readOnlyHint: false, destructiveHint: true },
|
|
1401
1417
|
description: "Execute shell or PowerShell commands in the sandbox",
|
|
1402
1418
|
inputSchema: z.object({
|
|
1403
1419
|
language: z.enum(["sh", "pwsh"]).default("sh"),
|
|
@@ -1459,6 +1475,7 @@ function parseScreenshotFilename(filename: string): ParsedScreenshotInfo {
|
|
|
1459
1475
|
server.registerTool(
|
|
1460
1476
|
"list_local_screenshots",
|
|
1461
1477
|
{
|
|
1478
|
+
annotations: { title: "List Local Screenshots", readOnlyHint: true },
|
|
1462
1479
|
description: `List and filter screenshots saved in the .testdriver directory.
|
|
1463
1480
|
|
|
1464
1481
|
Screenshots from auto-screenshot feature use the format: <seq>-<action>-<phase>-L<line>-<description>.png
|
|
@@ -1691,6 +1708,7 @@ registerAppTool(
|
|
|
1691
1708
|
"view_local_screenshot",
|
|
1692
1709
|
{
|
|
1693
1710
|
title: "View Local Screenshot",
|
|
1711
|
+
annotations: { title: "View Local Screenshot", readOnlyHint: true },
|
|
1694
1712
|
description: `View a screenshot from the .testdriver directory.
|
|
1695
1713
|
|
|
1696
1714
|
Use 'list_local_screenshots' first to see available screenshots, then use this tool to view one.
|
|
@@ -1784,6 +1802,7 @@ registerAppTool(
|
|
|
1784
1802
|
"screenshot",
|
|
1785
1803
|
{
|
|
1786
1804
|
title: "Screenshot",
|
|
1805
|
+
annotations: { title: "Screenshot", readOnlyHint: true },
|
|
1787
1806
|
description: `Display a screenshot to the user. This tool does NOT return the image to you (the AI).
|
|
1788
1807
|
|
|
1789
1808
|
⚠️ IMPORTANT: Do NOT use this tool to understand the screen state. The screenshot is ONLY displayed to the human user - you will NOT receive the image or any analysis.
|
|
@@ -1832,6 +1851,7 @@ Only use 'screenshot' when you explicitly want to show something to the human us
|
|
|
1832
1851
|
server.registerTool(
|
|
1833
1852
|
"init",
|
|
1834
1853
|
{
|
|
1854
|
+
annotations: { title: "Initialize Project", readOnlyHint: false, destructiveHint: true },
|
|
1835
1855
|
description: `Initialize a new TestDriver project with Vitest SDK examples.
|
|
1836
1856
|
|
|
1837
1857
|
This creates:
|
|
@@ -1927,6 +1947,7 @@ Learn more at https://docs.testdriver.ai/v7/getting-started/
|
|
|
1927
1947
|
server.registerTool(
|
|
1928
1948
|
"list_test_runs",
|
|
1929
1949
|
{
|
|
1950
|
+
annotations: { title: "List Test Runs", readOnlyHint: true },
|
|
1930
1951
|
description: "List recent TestDriver test runs for the current team.",
|
|
1931
1952
|
inputSchema: z.object({
|
|
1932
1953
|
page: z.number().optional().describe("Page number (1-indexed)"),
|
|
@@ -1953,6 +1974,7 @@ server.registerTool(
|
|
|
1953
1974
|
server.registerTool(
|
|
1954
1975
|
"get_test_run_detail",
|
|
1955
1976
|
{
|
|
1977
|
+
annotations: { title: "Get Test Run Detail", readOnlyHint: true },
|
|
1956
1978
|
description: "Get details for a single TestDriver test run, including its test cases.",
|
|
1957
1979
|
inputSchema: z.object({
|
|
1958
1980
|
id: z.string().describe("The test run id"),
|