@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.
@@ -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"),
@@ -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">Waiting for screenshot...</span>
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: #3b82f6;
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: 100%;
103
- height: 100%;
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
- let targetHtml = `<strong>Target:</strong> "${el.description || "Element"}"`;
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
- targetHtml += ` <span class="target-coords">(${Math.round(el.centerX)}, ${Math.round(el.centerY)})</span>`;
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
- targetHtml += ` <span class="target-confidence ${confidencePercent >= 70 ? 'high' : confidencePercent >= 40 ? 'medium' : 'low'}">${confidencePercent}%</span>`;
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 = "block";
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
@@ -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"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testdriverai/mcp",
3
- "version": "7.11.177-test",
3
+ "version": "7.11.178-test",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",