@checkview/mcp-server 1.1.0

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.
Files changed (263) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/api-client.d.ts +44 -0
  4. package/dist/api-client.d.ts.map +1 -0
  5. package/dist/api-client.js +164 -0
  6. package/dist/api-client.js.map +1 -0
  7. package/dist/format.d.ts +35 -0
  8. package/dist/format.d.ts.map +1 -0
  9. package/dist/format.js +57 -0
  10. package/dist/format.js.map +1 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +142 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/polling.d.ts +13 -0
  16. package/dist/polling.d.ts.map +1 -0
  17. package/dist/polling.js +55 -0
  18. package/dist/polling.js.map +1 -0
  19. package/dist/tools/abort-test.d.ts +4 -0
  20. package/dist/tools/abort-test.d.ts.map +1 -0
  21. package/dist/tools/abort-test.js +136 -0
  22. package/dist/tools/abort-test.js.map +1 -0
  23. package/dist/tools/add-test-comment.d.ts +4 -0
  24. package/dist/tools/add-test-comment.d.ts.map +1 -0
  25. package/dist/tools/add-test-comment.js +77 -0
  26. package/dist/tools/add-test-comment.js.map +1 -0
  27. package/dist/tools/add-website.d.ts +4 -0
  28. package/dist/tools/add-website.d.ts.map +1 -0
  29. package/dist/tools/add-website.js +106 -0
  30. package/dist/tools/add-website.js.map +1 -0
  31. package/dist/tools/check-website-availability.d.ts +4 -0
  32. package/dist/tools/check-website-availability.d.ts.map +1 -0
  33. package/dist/tools/check-website-availability.js +45 -0
  34. package/dist/tools/check-website-availability.js.map +1 -0
  35. package/dist/tools/check-website-health.d.ts +4 -0
  36. package/dist/tools/check-website-health.d.ts.map +1 -0
  37. package/dist/tools/check-website-health.js +61 -0
  38. package/dist/tools/check-website-health.js.map +1 -0
  39. package/dist/tools/compare-test-runs.d.ts +4 -0
  40. package/dist/tools/compare-test-runs.d.ts.map +1 -0
  41. package/dist/tools/compare-test-runs.js +75 -0
  42. package/dist/tools/compare-test-runs.js.map +1 -0
  43. package/dist/tools/create-form-test-flow.d.ts +4 -0
  44. package/dist/tools/create-form-test-flow.d.ts.map +1 -0
  45. package/dist/tools/create-form-test-flow.js +228 -0
  46. package/dist/tools/create-form-test-flow.js.map +1 -0
  47. package/dist/tools/create-test-flow.d.ts +4 -0
  48. package/dist/tools/create-test-flow.d.ts.map +1 -0
  49. package/dist/tools/create-test-flow.js +536 -0
  50. package/dist/tools/create-test-flow.js.map +1 -0
  51. package/dist/tools/delete-invitation.d.ts +4 -0
  52. package/dist/tools/delete-invitation.d.ts.map +1 -0
  53. package/dist/tools/delete-invitation.js +67 -0
  54. package/dist/tools/delete-invitation.js.map +1 -0
  55. package/dist/tools/delete-test-comment.d.ts +4 -0
  56. package/dist/tools/delete-test-comment.d.ts.map +1 -0
  57. package/dist/tools/delete-test-comment.js +67 -0
  58. package/dist/tools/delete-test-comment.js.map +1 -0
  59. package/dist/tools/get-ai-summary.d.ts +4 -0
  60. package/dist/tools/get-ai-summary.d.ts.map +1 -0
  61. package/dist/tools/get-ai-summary.js +61 -0
  62. package/dist/tools/get-ai-summary.js.map +1 -0
  63. package/dist/tools/get-current-organization.d.ts +4 -0
  64. package/dist/tools/get-current-organization.d.ts.map +1 -0
  65. package/dist/tools/get-current-organization.js +41 -0
  66. package/dist/tools/get-current-organization.js.map +1 -0
  67. package/dist/tools/get-generation-status.d.ts +4 -0
  68. package/dist/tools/get-generation-status.d.ts.map +1 -0
  69. package/dist/tools/get-generation-status.js +45 -0
  70. package/dist/tools/get-generation-status.js.map +1 -0
  71. package/dist/tools/get-metrics.d.ts +4 -0
  72. package/dist/tools/get-metrics.d.ts.map +1 -0
  73. package/dist/tools/get-metrics.js +90 -0
  74. package/dist/tools/get-metrics.js.map +1 -0
  75. package/dist/tools/get-organization-stats.d.ts +4 -0
  76. package/dist/tools/get-organization-stats.d.ts.map +1 -0
  77. package/dist/tools/get-organization-stats.js +53 -0
  78. package/dist/tools/get-organization-stats.js.map +1 -0
  79. package/dist/tools/get-organization.d.ts +4 -0
  80. package/dist/tools/get-organization.d.ts.map +1 -0
  81. package/dist/tools/get-organization.js +71 -0
  82. package/dist/tools/get-organization.js.map +1 -0
  83. package/dist/tools/get-results.d.ts +4 -0
  84. package/dist/tools/get-results.d.ts.map +1 -0
  85. package/dist/tools/get-results.js +154 -0
  86. package/dist/tools/get-results.js.map +1 -0
  87. package/dist/tools/get-settings.d.ts +4 -0
  88. package/dist/tools/get-settings.d.ts.map +1 -0
  89. package/dist/tools/get-settings.js +100 -0
  90. package/dist/tools/get-settings.js.map +1 -0
  91. package/dist/tools/get-step-screenshot.d.ts +4 -0
  92. package/dist/tools/get-step-screenshot.d.ts.map +1 -0
  93. package/dist/tools/get-step-screenshot.js +47 -0
  94. package/dist/tools/get-step-screenshot.js.map +1 -0
  95. package/dist/tools/get-test-flow.d.ts +4 -0
  96. package/dist/tools/get-test-flow.d.ts.map +1 -0
  97. package/dist/tools/get-test-flow.js +90 -0
  98. package/dist/tools/get-test-flow.js.map +1 -0
  99. package/dist/tools/get-test-history.d.ts +4 -0
  100. package/dist/tools/get-test-history.d.ts.map +1 -0
  101. package/dist/tools/get-test-history.js +100 -0
  102. package/dist/tools/get-test-history.js.map +1 -0
  103. package/dist/tools/get-test-run-video.d.ts +4 -0
  104. package/dist/tools/get-test-run-video.d.ts.map +1 -0
  105. package/dist/tools/get-test-run-video.js +66 -0
  106. package/dist/tools/get-test-run-video.js.map +1 -0
  107. package/dist/tools/get-test-step-details.d.ts +4 -0
  108. package/dist/tools/get-test-step-details.d.ts.map +1 -0
  109. package/dist/tools/get-test-step-details.js +166 -0
  110. package/dist/tools/get-test-step-details.js.map +1 -0
  111. package/dist/tools/get-usage-reports.d.ts +4 -0
  112. package/dist/tools/get-usage-reports.d.ts.map +1 -0
  113. package/dist/tools/get-usage-reports.js +73 -0
  114. package/dist/tools/get-usage-reports.js.map +1 -0
  115. package/dist/tools/get-usage.d.ts +4 -0
  116. package/dist/tools/get-usage.d.ts.map +1 -0
  117. package/dist/tools/get-usage.js +32 -0
  118. package/dist/tools/get-usage.js.map +1 -0
  119. package/dist/tools/get-ux-audit-report.d.ts +4 -0
  120. package/dist/tools/get-ux-audit-report.d.ts.map +1 -0
  121. package/dist/tools/get-ux-audit-report.js +52 -0
  122. package/dist/tools/get-ux-audit-report.js.map +1 -0
  123. package/dist/tools/get-website-analytics.d.ts +4 -0
  124. package/dist/tools/get-website-analytics.d.ts.map +1 -0
  125. package/dist/tools/get-website-analytics.js +54 -0
  126. package/dist/tools/get-website-analytics.js.map +1 -0
  127. package/dist/tools/get-website-logs.d.ts +4 -0
  128. package/dist/tools/get-website-logs.d.ts.map +1 -0
  129. package/dist/tools/get-website-logs.js +53 -0
  130. package/dist/tools/get-website-logs.js.map +1 -0
  131. package/dist/tools/get-website-screenshot.d.ts +4 -0
  132. package/dist/tools/get-website-screenshot.d.ts.map +1 -0
  133. package/dist/tools/get-website-screenshot.js +59 -0
  134. package/dist/tools/get-website-screenshot.js.map +1 -0
  135. package/dist/tools/get-website-settings.d.ts +4 -0
  136. package/dist/tools/get-website-settings.d.ts.map +1 -0
  137. package/dist/tools/get-website-settings.js +97 -0
  138. package/dist/tools/get-website-settings.js.map +1 -0
  139. package/dist/tools/get-website.d.ts +4 -0
  140. package/dist/tools/get-website.d.ts.map +1 -0
  141. package/dist/tools/get-website.js +45 -0
  142. package/dist/tools/get-website.js.map +1 -0
  143. package/dist/tools/invite-team-member.d.ts +4 -0
  144. package/dist/tools/invite-team-member.d.ts.map +1 -0
  145. package/dist/tools/invite-team-member.js +100 -0
  146. package/dist/tools/invite-team-member.js.map +1 -0
  147. package/dist/tools/list-forms.d.ts +4 -0
  148. package/dist/tools/list-forms.d.ts.map +1 -0
  149. package/dist/tools/list-forms.js +65 -0
  150. package/dist/tools/list-forms.js.map +1 -0
  151. package/dist/tools/list-organizations.d.ts +4 -0
  152. package/dist/tools/list-organizations.d.ts.map +1 -0
  153. package/dist/tools/list-organizations.js +78 -0
  154. package/dist/tools/list-organizations.js.map +1 -0
  155. package/dist/tools/list-team-members.d.ts +4 -0
  156. package/dist/tools/list-team-members.d.ts.map +1 -0
  157. package/dist/tools/list-team-members.js +58 -0
  158. package/dist/tools/list-team-members.js.map +1 -0
  159. package/dist/tools/list-test-comments.d.ts +4 -0
  160. package/dist/tools/list-test-comments.d.ts.map +1 -0
  161. package/dist/tools/list-test-comments.js +55 -0
  162. package/dist/tools/list-test-comments.js.map +1 -0
  163. package/dist/tools/list-test-flow-steps.d.ts +4 -0
  164. package/dist/tools/list-test-flow-steps.d.ts.map +1 -0
  165. package/dist/tools/list-test-flow-steps.js +59 -0
  166. package/dist/tools/list-test-flow-steps.js.map +1 -0
  167. package/dist/tools/list-test-flows.d.ts +4 -0
  168. package/dist/tools/list-test-flows.d.ts.map +1 -0
  169. package/dist/tools/list-test-flows.js +90 -0
  170. package/dist/tools/list-test-flows.js.map +1 -0
  171. package/dist/tools/list-test-runs.d.ts +4 -0
  172. package/dist/tools/list-test-runs.d.ts.map +1 -0
  173. package/dist/tools/list-test-runs.js +94 -0
  174. package/dist/tools/list-test-runs.js.map +1 -0
  175. package/dist/tools/list-ux-audits.d.ts +4 -0
  176. package/dist/tools/list-ux-audits.d.ts.map +1 -0
  177. package/dist/tools/list-ux-audits.js +59 -0
  178. package/dist/tools/list-ux-audits.js.map +1 -0
  179. package/dist/tools/list-websites.d.ts +4 -0
  180. package/dist/tools/list-websites.d.ts.map +1 -0
  181. package/dist/tools/list-websites.js +80 -0
  182. package/dist/tools/list-websites.js.map +1 -0
  183. package/dist/tools/manage-notification-settings.d.ts +4 -0
  184. package/dist/tools/manage-notification-settings.d.ts.map +1 -0
  185. package/dist/tools/manage-notification-settings.js +311 -0
  186. package/dist/tools/manage-notification-settings.js.map +1 -0
  187. package/dist/tools/pause-website.d.ts +4 -0
  188. package/dist/tools/pause-website.d.ts.map +1 -0
  189. package/dist/tools/pause-website.js +58 -0
  190. package/dist/tools/pause-website.js.map +1 -0
  191. package/dist/tools/regenerate-test-steps.d.ts +4 -0
  192. package/dist/tools/regenerate-test-steps.d.ts.map +1 -0
  193. package/dist/tools/regenerate-test-steps.js +173 -0
  194. package/dist/tools/regenerate-test-steps.js.map +1 -0
  195. package/dist/tools/reinitialize-test-flow.d.ts +4 -0
  196. package/dist/tools/reinitialize-test-flow.d.ts.map +1 -0
  197. package/dist/tools/reinitialize-test-flow.js +79 -0
  198. package/dist/tools/reinitialize-test-flow.js.map +1 -0
  199. package/dist/tools/remove-team-member.d.ts +4 -0
  200. package/dist/tools/remove-team-member.d.ts.map +1 -0
  201. package/dist/tools/remove-team-member.js +68 -0
  202. package/dist/tools/remove-team-member.js.map +1 -0
  203. package/dist/tools/remove-test-flow.d.ts +4 -0
  204. package/dist/tools/remove-test-flow.d.ts.map +1 -0
  205. package/dist/tools/remove-test-flow.js +74 -0
  206. package/dist/tools/remove-test-flow.js.map +1 -0
  207. package/dist/tools/remove-website.d.ts +4 -0
  208. package/dist/tools/remove-website.d.ts.map +1 -0
  209. package/dist/tools/remove-website.js +74 -0
  210. package/dist/tools/remove-website.js.map +1 -0
  211. package/dist/tools/resume-website.d.ts +4 -0
  212. package/dist/tools/resume-website.d.ts.map +1 -0
  213. package/dist/tools/resume-website.js +58 -0
  214. package/dist/tools/resume-website.js.map +1 -0
  215. package/dist/tools/run-all-tests.d.ts +4 -0
  216. package/dist/tools/run-all-tests.d.ts.map +1 -0
  217. package/dist/tools/run-all-tests.js +165 -0
  218. package/dist/tools/run-all-tests.js.map +1 -0
  219. package/dist/tools/run-test.d.ts +4 -0
  220. package/dist/tools/run-test.d.ts.map +1 -0
  221. package/dist/tools/run-test.js +186 -0
  222. package/dist/tools/run-test.js.map +1 -0
  223. package/dist/tools/run-ux-audit.d.ts +4 -0
  224. package/dist/tools/run-ux-audit.d.ts.map +1 -0
  225. package/dist/tools/run-ux-audit.js +192 -0
  226. package/dist/tools/run-ux-audit.js.map +1 -0
  227. package/dist/tools/set-organization.d.ts +4 -0
  228. package/dist/tools/set-organization.d.ts.map +1 -0
  229. package/dist/tools/set-organization.js +129 -0
  230. package/dist/tools/set-organization.js.map +1 -0
  231. package/dist/tools/test-url.d.ts +4 -0
  232. package/dist/tools/test-url.d.ts.map +1 -0
  233. package/dist/tools/test-url.js +334 -0
  234. package/dist/tools/test-url.js.map +1 -0
  235. package/dist/tools/update-organization.d.ts +4 -0
  236. package/dist/tools/update-organization.d.ts.map +1 -0
  237. package/dist/tools/update-organization.js +90 -0
  238. package/dist/tools/update-organization.js.map +1 -0
  239. package/dist/tools/update-schedule.d.ts +4 -0
  240. package/dist/tools/update-schedule.d.ts.map +1 -0
  241. package/dist/tools/update-schedule.js +157 -0
  242. package/dist/tools/update-schedule.js.map +1 -0
  243. package/dist/tools/update-settings.d.ts +4 -0
  244. package/dist/tools/update-settings.d.ts.map +1 -0
  245. package/dist/tools/update-settings.js +97 -0
  246. package/dist/tools/update-settings.js.map +1 -0
  247. package/dist/tools/update-team-member.d.ts +4 -0
  248. package/dist/tools/update-team-member.d.ts.map +1 -0
  249. package/dist/tools/update-team-member.js +102 -0
  250. package/dist/tools/update-team-member.js.map +1 -0
  251. package/dist/tools/update-test-flow-steps.d.ts +4 -0
  252. package/dist/tools/update-test-flow-steps.d.ts.map +1 -0
  253. package/dist/tools/update-test-flow-steps.js +440 -0
  254. package/dist/tools/update-test-flow-steps.js.map +1 -0
  255. package/dist/tools/update-test-flow.d.ts +4 -0
  256. package/dist/tools/update-test-flow.d.ts.map +1 -0
  257. package/dist/tools/update-test-flow.js +172 -0
  258. package/dist/tools/update-test-flow.js.map +1 -0
  259. package/dist/tools/update-website.d.ts +4 -0
  260. package/dist/tools/update-website.d.ts.map +1 -0
  261. package/dist/tools/update-website.js +86 -0
  262. package/dist/tools/update-website.js.map +1 -0
  263. package/package.json +57 -0
@@ -0,0 +1,186 @@
1
+ import { z } from "zod";
2
+ import { ApiError, idempotencyKey } from "../api-client.js";
3
+ import { formatTestRun } from "../format.js";
4
+ import { pollUntil } from "../polling.js";
5
+ const TERMINAL_STATUSES = new Set([
6
+ "success",
7
+ "error",
8
+ "aborted",
9
+ "awaiting_email",
10
+ ]);
11
+ export function registerRunTestTool(server, client) {
12
+ server.registerTool("checkview_run_test", {
13
+ description: "Run an existing CheckView test flow and return results. Optionally provide one-time login credentials.",
14
+ inputSchema: {
15
+ test_flow_id: z.string().uuid().describe("The test flow ID to execute"),
16
+ wait_for_result: z
17
+ .boolean()
18
+ .optional()
19
+ .default(true)
20
+ .describe("Wait for test to complete and return results (default true)"),
21
+ credentials: z
22
+ .object({
23
+ username: z.string(),
24
+ password: z.string(),
25
+ })
26
+ .optional()
27
+ .describe("One-time login credentials (encrypted, auto-deleted after 5 min)"),
28
+ },
29
+ annotations: {
30
+ readOnlyHint: false,
31
+ destructiveHint: false,
32
+ idempotentHint: true,
33
+ },
34
+ }, async (args, extra) => {
35
+ try {
36
+ // Trigger execution
37
+ const idemKey = idempotencyKey(`${args.test_flow_id}:${Date.now()}`);
38
+ const body = { trigger: "api" };
39
+ if (args.credentials) {
40
+ body.credentials = args.credentials;
41
+ }
42
+ let execution;
43
+ try {
44
+ const result = await client.post(`/test-flows/${args.test_flow_id}/executions`, body, idemKey, extra.signal);
45
+ execution = result.body;
46
+ }
47
+ catch (error) {
48
+ if (error instanceof ApiError) {
49
+ // Handle idempotency in-progress (retry with backoff)
50
+ if (error.status === 409 &&
51
+ error.type ===
52
+ "https://api.checkview.io/errors/request-in-progress") {
53
+ return {
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: "A request is currently being processed. Please try again in a few seconds.",
58
+ },
59
+ ],
60
+ isError: true,
61
+ };
62
+ }
63
+ // Handle test already running
64
+ if (error.status === 409) {
65
+ return {
66
+ content: [
67
+ {
68
+ type: "text",
69
+ text: "A test is already running for this test flow. Please wait for it to complete.",
70
+ },
71
+ ],
72
+ isError: true,
73
+ };
74
+ }
75
+ // Handle monthly limit
76
+ if (error.status === 403) {
77
+ return {
78
+ content: [
79
+ {
80
+ type: "text",
81
+ text: "Monthly test limit reached. Please upgrade your plan or wait until next month.",
82
+ },
83
+ ],
84
+ isError: true,
85
+ };
86
+ }
87
+ // Handle paused/no steps
88
+ if (error.status === 400) {
89
+ return {
90
+ content: [{ type: "text", text: error.detail }],
91
+ isError: true,
92
+ };
93
+ }
94
+ // Cached error replay — retry with fresh key
95
+ if (error.isReplay && error.status >= 400) {
96
+ const freshKey = idempotencyKey(`${args.test_flow_id}:retry:${Date.now()}`);
97
+ const retryResult = await client.post(`/test-flows/${args.test_flow_id}/executions`, body, freshKey, extra.signal);
98
+ execution = retryResult.body;
99
+ }
100
+ else {
101
+ throw error;
102
+ }
103
+ }
104
+ else {
105
+ throw error;
106
+ }
107
+ }
108
+ const testRunId = execution.id;
109
+ if (!args.wait_for_result) {
110
+ return {
111
+ content: [
112
+ {
113
+ type: "text",
114
+ text: `Test triggered successfully.\n\nTest run ID: ${testRunId}\n\nUse checkview_get_results("${testRunId}") to check results later.`,
115
+ },
116
+ ],
117
+ };
118
+ }
119
+ // Poll for completion
120
+ await server.sendLoggingMessage({
121
+ level: "info",
122
+ data: `Test run ${testRunId} started. Polling for completion...`,
123
+ });
124
+ let lastResult = { id: testRunId, status: "started" };
125
+ let finalResult;
126
+ try {
127
+ finalResult = await pollUntil(async () => {
128
+ try {
129
+ const r = await client.get(`/test-runs/${testRunId}`, undefined, extra.signal);
130
+ lastResult = r.body;
131
+ return r.body;
132
+ }
133
+ catch (error) {
134
+ // Swallow transient server errors
135
+ if (error instanceof ApiError && error.status >= 500) {
136
+ return lastResult;
137
+ }
138
+ throw error;
139
+ }
140
+ }, (result) => TERMINAL_STATUSES.has(result.status), {
141
+ intervalMs: 10_000,
142
+ timeoutMs: 600_000, // 10 min
143
+ signal: extra.signal,
144
+ onProgress: (result) => {
145
+ server
146
+ .sendLoggingMessage({
147
+ level: "info",
148
+ data: `Test run ${testRunId}: status=${result.status}`,
149
+ })
150
+ .catch(() => { });
151
+ },
152
+ });
153
+ }
154
+ catch (error) {
155
+ const isTimeout = error instanceof Error &&
156
+ error.message.startsWith("Operation timed out");
157
+ if (isTimeout) {
158
+ return {
159
+ content: [
160
+ {
161
+ type: "text",
162
+ text: `Test run ${testRunId} is still ${lastResult.status} after 10 min. Use checkview_get_results("${testRunId}") to check later.`,
163
+ },
164
+ ],
165
+ };
166
+ }
167
+ throw error;
168
+ }
169
+ return {
170
+ content: [{ type: "text", text: formatTestRun(finalResult) }],
171
+ };
172
+ }
173
+ catch (error) {
174
+ return {
175
+ content: [
176
+ {
177
+ type: "text",
178
+ text: `Failed to run test: ${error instanceof Error ? error.message : String(error)}`,
179
+ },
180
+ ],
181
+ isError: true,
182
+ };
183
+ }
184
+ });
185
+ }
186
+ //# sourceMappingURL=run-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-test.js","sourceRoot":"","sources":["../../src/tools/run-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ApiClient } from "../api-client.js";
3
+ export declare function registerRunUxAuditTool(server: McpServer, client: ApiClient): void;
4
+ //# sourceMappingURL=run-ux-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-ux-audit.d.ts","sourceRoot":"","sources":["../../src/tools/run-ux-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiB5E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,GAChB,IAAI,CAiON"}
@@ -0,0 +1,192 @@
1
+ import { z } from "zod";
2
+ import { ApiError, idempotencyKey } from "../api-client.js";
3
+ import { pollUntil } from "../polling.js";
4
+ export function registerRunUxAuditTool(server, client) {
5
+ server.registerTool("checkview_run_ux_audit", {
6
+ description: "Run a UX audit on selected test flows for a website. Generates an AI-powered report analyzing screenshots.",
7
+ inputSchema: {
8
+ website_id: z.string().uuid().describe("The website ID"),
9
+ name: z
10
+ .string()
11
+ .min(1)
12
+ .max(255)
13
+ .describe("Name for the UX audit report"),
14
+ test_flow_ids: z
15
+ .array(z.string().uuid())
16
+ .min(1)
17
+ .max(20)
18
+ .describe("Test flow IDs to include in the audit (1-20)"),
19
+ wait_for_result: z
20
+ .boolean()
21
+ .optional()
22
+ .default(true)
23
+ .describe("Wait for audit to complete and return report (default true)"),
24
+ },
25
+ annotations: {
26
+ readOnlyHint: false,
27
+ destructiveHint: false,
28
+ idempotentHint: true,
29
+ },
30
+ }, async (args, extra) => {
31
+ try {
32
+ const sortedFlows = [...args.test_flow_ids].sort();
33
+ const idemKey = idempotencyKey(`${args.website_id}:${args.name}:${sortedFlows.join(",")}`);
34
+ let audit;
35
+ try {
36
+ const result = await client.post(`/websites/${args.website_id}/ux-audits`, { name: args.name, testFlowIds: args.test_flow_ids }, idemKey, extra.signal);
37
+ audit = result.body;
38
+ }
39
+ catch (error) {
40
+ if (error instanceof ApiError) {
41
+ if (error.status === 400) {
42
+ return {
43
+ content: [{ type: "text", text: error.detail }],
44
+ isError: true,
45
+ };
46
+ }
47
+ if (error.status === 403) {
48
+ return {
49
+ content: [
50
+ {
51
+ type: "text",
52
+ text: "Monthly UX audit limit reached. Please upgrade your plan or wait until next month.",
53
+ },
54
+ ],
55
+ isError: true,
56
+ };
57
+ }
58
+ if (error.status === 404) {
59
+ return {
60
+ content: [
61
+ { type: "text", text: "Website or test flows not found." },
62
+ ],
63
+ isError: true,
64
+ };
65
+ }
66
+ if (error.isReplay && error.status >= 400) {
67
+ const freshKey = idempotencyKey(`${args.website_id}:${args.name}:${sortedFlows.join(",")}:retry:${Date.now()}`);
68
+ const retryResult = await client.post(`/websites/${args.website_id}/ux-audits`, { name: args.name, testFlowIds: args.test_flow_ids }, freshKey, extra.signal);
69
+ audit = retryResult.body;
70
+ }
71
+ else {
72
+ throw error;
73
+ }
74
+ }
75
+ else {
76
+ throw error;
77
+ }
78
+ }
79
+ const auditId = audit.id;
80
+ if (!args.wait_for_result) {
81
+ return {
82
+ content: [
83
+ {
84
+ type: "text",
85
+ text: `UX audit "${args.name}" created.\n\nAudit ID: ${auditId}\n\nUse checkview_list_ux_audits to check status.`,
86
+ },
87
+ ],
88
+ };
89
+ }
90
+ // Poll for completion
91
+ await server.sendLoggingMessage({
92
+ level: "info",
93
+ data: `UX audit ${auditId} started. Polling for completion...`,
94
+ });
95
+ let lastStatus = audit;
96
+ // Outer try-catch to handle poll timeout gracefully
97
+ let finalAudit;
98
+ try {
99
+ finalAudit = await pollUntil(async () => {
100
+ try {
101
+ const r = await client.get(`/websites/${args.website_id}/ux-audits/${auditId}`, undefined, extra.signal);
102
+ lastStatus = r.body;
103
+ return r.body;
104
+ }
105
+ catch (error) {
106
+ // Swallow transient server errors
107
+ if (error instanceof ApiError && error.status >= 500) {
108
+ return lastStatus;
109
+ }
110
+ throw error;
111
+ }
112
+ }, (result) => result.status === "ready" || result.status === "error", {
113
+ intervalMs: 15_000,
114
+ timeoutMs: 600_000, // 10 min
115
+ signal: extra.signal,
116
+ onProgress: (result) => {
117
+ server
118
+ .sendLoggingMessage({
119
+ level: "info",
120
+ data: `UX audit ${auditId}: status=${result.status}`,
121
+ })
122
+ .catch(() => { });
123
+ },
124
+ });
125
+ }
126
+ catch (error) {
127
+ const isTimeout = error instanceof Error &&
128
+ error.message.startsWith("Operation timed out");
129
+ if (isTimeout) {
130
+ return {
131
+ content: [
132
+ {
133
+ type: "text",
134
+ text: `Audit ${auditId} is still ${lastStatus.status} after 10 min. Check back with checkview_list_ux_audits.`,
135
+ },
136
+ ],
137
+ };
138
+ }
139
+ throw error;
140
+ }
141
+ if (finalAudit.status === "error") {
142
+ return {
143
+ content: [
144
+ {
145
+ type: "text",
146
+ text: `UX audit "${args.name}" failed.\n\nAudit ID: ${auditId}`,
147
+ },
148
+ ],
149
+ isError: true,
150
+ };
151
+ }
152
+ // Fetch report
153
+ try {
154
+ const { body: report } = await client.get(`/websites/${args.website_id}/ux-audits/${auditId}/report`, undefined, extra.signal);
155
+ const reportText = typeof report.report_data === "string"
156
+ ? report.report_data
157
+ : JSON.stringify(report.report_data, null, 2);
158
+ return {
159
+ content: [
160
+ {
161
+ type: "text",
162
+ text: `## UX Audit: ${args.name}\n\nAudit ID: ${auditId}\n\n${reportText}`,
163
+ },
164
+ ],
165
+ };
166
+ }
167
+ catch {
168
+ // Report fetch failed (may have been deleted)
169
+ return {
170
+ content: [
171
+ {
172
+ type: "text",
173
+ text: `UX audit "${args.name}" completed but report could not be fetched.\n\nAudit ID: ${auditId}`,
174
+ },
175
+ ],
176
+ };
177
+ }
178
+ }
179
+ catch (error) {
180
+ return {
181
+ content: [
182
+ {
183
+ type: "text",
184
+ text: `Failed to run UX audit: ${error instanceof Error ? error.message : String(error)}`,
185
+ },
186
+ ],
187
+ isError: true,
188
+ };
189
+ }
190
+ });
191
+ }
192
+ //# sourceMappingURL=run-ux-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-ux-audit.js","sourceRoot":"","sources":["../../src/tools/run-ux-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ApiClient } from "../api-client.js";
3
+ export declare function registerSetOrganizationTool(server: McpServer, client: ApiClient): void;
4
+ //# sourceMappingURL=set-organization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-organization.d.ts","sourceRoot":"","sources":["../../src/tools/set-organization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQlD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,GAChB,IAAI,CA8IN"}
@@ -0,0 +1,129 @@
1
+ import { z } from "zod";
2
+ import { ApiError } from "../api-client.js";
3
+ export function registerSetOrganizationTool(server, client) {
4
+ server.registerTool("checkview_set_organization", {
5
+ description: "Switch to a different organization for all subsequent operations. " +
6
+ "Only super admins can switch to organizations other than their default. " +
7
+ "Use checkview_list_organizations to find organization IDs. " +
8
+ 'Pass "reset" as organization_id to return to your default organization.',
9
+ inputSchema: {
10
+ organization_id: z
11
+ .string()
12
+ .describe('The organization UUID to switch to, or "reset" to return to the default organization from your PAT'),
13
+ },
14
+ annotations: {
15
+ readOnlyHint: false,
16
+ destructiveHint: false,
17
+ },
18
+ }, async (args, extra) => {
19
+ try {
20
+ if (args.organization_id === "reset") {
21
+ client.clearOrganizationOverride();
22
+ return {
23
+ content: [
24
+ {
25
+ type: "text",
26
+ text: "Organization override cleared. Now using default organization from your access token.",
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ // Validate UUID format
32
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
33
+ if (!uuidRegex.test(args.organization_id)) {
34
+ return {
35
+ content: [
36
+ {
37
+ type: "text",
38
+ text: "Invalid organization ID format. Must be a UUID.",
39
+ },
40
+ ],
41
+ isError: true,
42
+ };
43
+ }
44
+ // Set the override and verify it works
45
+ client.setOrganizationOverride(args.organization_id);
46
+ try {
47
+ const { body: org } = await client.get("/organizations/me", undefined, extra.signal);
48
+ // Detect silent guard rejection: if the API returned a different org,
49
+ // the guard reset the tenant (user is not a super admin).
50
+ // Compare case-insensitively since UUIDs may differ in case.
51
+ if (org.id.toLowerCase() !== args.organization_id.toLowerCase()) {
52
+ client.clearOrganizationOverride();
53
+ return {
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: "Failed to switch organization. You may not have admin access to other organizations.",
58
+ },
59
+ ],
60
+ isError: true,
61
+ };
62
+ }
63
+ return {
64
+ content: [
65
+ {
66
+ type: "text",
67
+ text: `Switched to organization: **${org.name}** (${org.id})\n` +
68
+ "All subsequent commands will operate in this organization's context.\n" +
69
+ 'Use checkview_set_organization with "reset" to return to your default organization.',
70
+ },
71
+ ],
72
+ };
73
+ }
74
+ catch (verifyError) {
75
+ // Revert the override on any verification failure
76
+ client.clearOrganizationOverride();
77
+ if (verifyError instanceof ApiError) {
78
+ if (verifyError.status === 401) {
79
+ return {
80
+ content: [
81
+ {
82
+ type: "text",
83
+ text: "Authentication failed. Your API key may be expired or revoked.",
84
+ },
85
+ ],
86
+ isError: true,
87
+ };
88
+ }
89
+ if (verifyError.status === 403) {
90
+ return {
91
+ content: [
92
+ {
93
+ type: "text",
94
+ text: "Access denied. Only CheckView super admins can switch organizations.",
95
+ },
96
+ ],
97
+ isError: true,
98
+ };
99
+ }
100
+ if (verifyError.status === 404) {
101
+ return {
102
+ content: [
103
+ {
104
+ type: "text",
105
+ text: `Organization not found: ${args.organization_id}`,
106
+ },
107
+ ],
108
+ isError: true,
109
+ };
110
+ }
111
+ }
112
+ throw verifyError;
113
+ }
114
+ }
115
+ catch (error) {
116
+ client.clearOrganizationOverride();
117
+ return {
118
+ content: [
119
+ {
120
+ type: "text",
121
+ text: `Failed to switch organization: ${error instanceof Error ? error.message : String(error)}`,
122
+ },
123
+ ],
124
+ isError: true,
125
+ };
126
+ }
127
+ });
128
+ }
129
+ //# sourceMappingURL=set-organization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-organization.js","sourceRoot":"","sources":["../../src/tools/set-organization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ApiClient } from "../api-client.js";
3
+ export declare function registerTestUrlTool(server: McpServer, client: ApiClient): void;
4
+ //# sourceMappingURL=test-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-url.d.ts","sourceRoot":"","sources":["../../src/tools/test-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA8B5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,GAChB,IAAI,CAoYN"}