@ltorrey/forgeqa-mcp 1.0.0 → 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.
package/LICENSE.md ADDED
@@ -0,0 +1,13 @@
1
+ # ForgeQA AI Commercial License
2
+
3
+ Copyright 2026 Lajuane Torrey. All rights reserved.
4
+
5
+ ForgeQA AI is commercial software. A valid license purchased through the official
6
+ ForgeQA AI Gumroad product page is required to use the software. The license key
7
+ may not be shared, published, resold, sublicensed, or used to provide unauthorized
8
+ access to the software.
9
+
10
+ The software is provided as decision-support and testing infrastructure without
11
+ warranties of uninterrupted operation, defect-free output, or suitability for a
12
+ particular purpose. Users are responsible for reviewing generated tests and for
13
+ testing only applications and environments they are authorized to access.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # ForgeQA AI
2
+
3
+ ForgeQA AI connects Claude Desktop or Cursor to a licensed, locally run
4
+ Playwright QA server. It opens supplied URLs in fresh headless Chromium sessions,
5
+ returns semantic accessibility snapshots, executes role-based actions and
6
+ assertions, and compiles reviewed flows into Playwright specifications.
7
+
8
+ ## Requirements
9
+
10
+ - Node.js 20 or newer
11
+ - A ForgeQA AI license purchased from the
12
+ [official Gumroad page](https://lajuanetorrey.gumroad.com/l/forgeqa-ai)
13
+ - Chromium for Playwright
14
+ - Internet access on first installation, at startup for Gumroad license
15
+ verification, and whenever the target application requires network access
16
+
17
+ Install the matching browser runtime once:
18
+
19
+ ```bash
20
+ npx -y playwright@1.63.0 install chromium
21
+ ```
22
+
23
+ ## Claude Desktop setup
24
+
25
+ Add this entry to `claude_desktop_config.json`, replacing the placeholder with
26
+ the license key from the Gumroad receipt:
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "ForgeQA": {
32
+ "command": "npx",
33
+ "args": ["-y", "@ltorrey/forgeqa-mcp@1.1.0"],
34
+ "env": {
35
+ "GUMROAD_LICENSE_KEY": "PASTE_YOUR_GUMROAD_LICENSE_KEY_HERE"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ Save the file, completely quit Claude Desktop, and reopen it.
43
+
44
+ ## Cursor setup
45
+
46
+ Use either of Cursor's documented configuration locations:
47
+
48
+ - Global: `~/.cursor/mcp.json`
49
+ - Project-specific: `<project-root>/.cursor/mcp.json`
50
+
51
+ Add the same configuration:
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "ForgeQA": {
57
+ "command": "npx",
58
+ "args": ["-y", "@ltorrey/forgeqa-mcp@1.1.0"],
59
+ "env": {
60
+ "GUMROAD_LICENSE_KEY": "PASTE_YOUR_GUMROAD_LICENSE_KEY_HERE"
61
+ }
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ Restart Cursor after saving the file. See the
68
+ [official Cursor MCP documentation](https://cursor.com/docs/mcp) for current
69
+ configuration options.
70
+
71
+ ## Tools
72
+
73
+ - `scan_dom_accessibility` opens a supplied URL in a fresh headless Chromium
74
+ session and returns its accessibility tree.
75
+ - `dry_run_qa_flow` executes role-based actions and outcome assertions, returning
76
+ a step-by-step pass/fail diagnostic.
77
+ - `compile_playwright_spec` writes reviewed actions and assertions to a reusable
78
+ Playwright specification in the local `tests/` directory.
79
+
80
+ Supported interactions are click, fill, check, select option, and key press.
81
+ Supported assertions cover visibility, hidden state, text, input value, checked
82
+ state, and URL outcomes.
83
+
84
+ Each scan or dry run starts in a fresh browser context. A complete login flow can
85
+ be tested within one dry run, but browser sessions are not shared between tool calls.
86
+
87
+ ## Running generated specifications
88
+
89
+ In the project where the specification was written:
90
+
91
+ ```bash
92
+ npm install --save-dev playwright@1.63.0
93
+ npx playwright@1.63.0 install chromium
94
+ npx playwright test tests/example.spec.ts
95
+ ```
96
+
97
+ Generated specifications never overwrite an existing file.
98
+
99
+ ## Privacy and safety
100
+
101
+ ForgeQA AI contains no product telemetry. At startup it sends the Gumroad product
102
+ ID and license key to Gumroad for validation. Test inputs and browser activity run
103
+ locally, while target websites receive ordinary browser requests. License keys are
104
+ never logged or persisted by ForgeQA AI.
105
+
106
+ `dry_run_qa_flow` performs real browser interactions. Use it only on applications
107
+ and environments you are authorized to test. Prefer staging systems and disposable
108
+ test data for flows that submit forms or change server-side state. Review generated
109
+ specifications before running them.
110
+
111
+ ## Licensing, updates, support, and refunds
112
+
113
+ - Each purchase delivers a unique license key. Do not share or publish it.
114
+ - Examples pin a package version so updates cannot silently change behavior.
115
+ - Review release notes and update the version in the MCP configuration deliberately.
116
+ - For support, reply to the Gumroad receipt or use the creator contact on the
117
+ product page. Never send a full license key in a support message.
118
+ - Sales are final. Refunds are not offered except where required by applicable law
119
+ or Gumroad's mandatory policies.
120
+
121
+ Copyright 2026 Lajuane Torrey. All rights reserved.
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- /**
2
- * Verifies a Gumroad license without ever logging or persisting the key.
3
- */
1
+ /** Verifies a Gumroad license without logging or persisting the key. */
4
2
  export declare function verifyGumroadLicense(licenseKey: string, productId: string): Promise<boolean>;
package/dist/auth.js CHANGED
@@ -1,23 +1,25 @@
1
1
  import fetch from "node-fetch";
2
- /**
3
- * Verifies a Gumroad license without ever logging or persisting the key.
4
- */
2
+ /** Verifies a Gumroad license without logging or persisting the key. */
5
3
  export async function verifyGumroadLicense(licenseKey, productId) {
6
- if (licenseKey === "FORGEQA_DEV") {
7
- return true;
8
- }
9
4
  const body = new URLSearchParams({
10
5
  product_id: productId,
11
6
  license_key: licenseKey,
7
+ increment_uses_count: "false",
12
8
  });
13
9
  const response = await fetch("https://api.gumroad.com/v2/licenses/verify", {
14
10
  method: "POST",
15
- headers: {
16
- "Content-Type": "application/x-www-form-urlencoded",
17
- },
11
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
18
12
  body,
13
+ signal: AbortSignal.timeout(15_000),
19
14
  });
15
+ if (!response.ok) {
16
+ return false;
17
+ }
20
18
  const data = (await response.json());
21
- return data.success === true && data.purchase?.refunded !== true;
19
+ return (data.success === true &&
20
+ data.purchase !== undefined &&
21
+ data.purchase.refunded !== true &&
22
+ data.purchase.disputed !== true &&
23
+ data.purchase.chargebacked !== true);
22
24
  }
23
25
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAS/B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,SAAiB;IAEjB,IAAI,UAAU,KAAK,aAAa,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,UAAU;KACxB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;QACzE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,mCAAmC;SACpD;QACD,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;IAE/D,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAW/B,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,SAAiB;IAEjB,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,UAAU;QACvB,oBAAoB,EAAE,OAAO;KAC9B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;QACzE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI;QACJ,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;IAC/D,OAAO,CACL,IAAI,CAAC,OAAO,KAAK,IAAI;QACrB,IAAI,CAAC,QAAQ,KAAK,SAAS;QAC3B,IAAI,CAAC,QAAQ,CAAC,QAAQ,KAAK,IAAI;QAC/B,IAAI,CAAC,QAAQ,CAAC,QAAQ,KAAK,IAAI;QAC/B,IAAI,CAAC,QAAQ,CAAC,YAAY,KAAK,IAAI,CACpC,CAAC;AACJ,CAAC"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ import type { Page } from "playwright";
2
+ import { z } from "zod";
3
+ export declare const webUrlSchema: z.ZodString;
4
+ export declare const qaActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5
+ role: z.ZodString;
6
+ name: z.ZodString;
7
+ type: z.ZodLiteral<"click">;
8
+ }, z.core.$strip>, z.ZodObject<{
9
+ role: z.ZodString;
10
+ name: z.ZodString;
11
+ type: z.ZodLiteral<"fill">;
12
+ value: z.ZodString;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ role: z.ZodString;
15
+ name: z.ZodString;
16
+ type: z.ZodLiteral<"check">;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ role: z.ZodString;
19
+ name: z.ZodString;
20
+ type: z.ZodLiteral<"select_option">;
21
+ value: z.ZodString;
22
+ }, z.core.$strip>, z.ZodObject<{
23
+ role: z.ZodString;
24
+ name: z.ZodString;
25
+ type: z.ZodLiteral<"press">;
26
+ key: z.ZodString;
27
+ }, z.core.$strip>, z.ZodObject<{
28
+ role: z.ZodString;
29
+ name: z.ZodString;
30
+ type: z.ZodLiteral<"expect_visible">;
31
+ }, z.core.$strip>, z.ZodObject<{
32
+ role: z.ZodString;
33
+ name: z.ZodString;
34
+ type: z.ZodLiteral<"expect_hidden">;
35
+ }, z.core.$strip>, z.ZodObject<{
36
+ role: z.ZodString;
37
+ name: z.ZodString;
38
+ type: z.ZodLiteral<"expect_text">;
39
+ expected: z.ZodString;
40
+ match: z.ZodDefault<z.ZodEnum<{
41
+ contains: "contains";
42
+ equals: "equals";
43
+ }>>;
44
+ }, z.core.$strip>, z.ZodObject<{
45
+ role: z.ZodString;
46
+ name: z.ZodString;
47
+ type: z.ZodLiteral<"expect_value">;
48
+ expected: z.ZodString;
49
+ }, z.core.$strip>, z.ZodObject<{
50
+ role: z.ZodString;
51
+ name: z.ZodString;
52
+ type: z.ZodLiteral<"expect_checked">;
53
+ }, z.core.$strip>, z.ZodObject<{
54
+ type: z.ZodLiteral<"expect_url">;
55
+ expected: z.ZodString;
56
+ match: z.ZodDefault<z.ZodEnum<{
57
+ contains: "contains";
58
+ equals: "equals";
59
+ }>>;
60
+ }, z.core.$strip>], "type">;
61
+ export type QaAction = z.infer<typeof qaActionSchema>;
62
+ export declare function executeAction(page: Page, action: QaAction): Promise<void>;
63
+ export declare function actionDescription(action: QaAction): string;
64
+ export declare function compileAction(action: QaAction): string;
65
+ export declare function safeSpecName(testName: string): string;
66
+ export declare function compileSpecSource(testName: string, targetUrl: string, actions: QaAction[]): string;
package/dist/core.js ADDED
@@ -0,0 +1,164 @@
1
+ import { z } from "zod";
2
+ export const webUrlSchema = z
3
+ .string()
4
+ .url()
5
+ .refine((value) => ["http:", "https:"].includes(new URL(value).protocol), {
6
+ message: "URL must use http or https",
7
+ });
8
+ const locatorFields = {
9
+ role: z.string().min(1).describe("ARIA role, such as button or textbox"),
10
+ name: z.string().min(1).describe("Accessible name of the target element"),
11
+ };
12
+ const matchMode = z.enum(["contains", "equals"]).default("contains");
13
+ export const qaActionSchema = z.discriminatedUnion("type", [
14
+ z.object({ type: z.literal("click"), ...locatorFields }),
15
+ z.object({ type: z.literal("fill"), ...locatorFields, value: z.string() }),
16
+ z.object({ type: z.literal("check"), ...locatorFields }),
17
+ z.object({
18
+ type: z.literal("select_option"),
19
+ ...locatorFields,
20
+ value: z.string(),
21
+ }),
22
+ z.object({
23
+ type: z.literal("press"),
24
+ ...locatorFields,
25
+ key: z.string().min(1),
26
+ }),
27
+ z.object({ type: z.literal("expect_visible"), ...locatorFields }),
28
+ z.object({ type: z.literal("expect_hidden"), ...locatorFields }),
29
+ z.object({
30
+ type: z.literal("expect_text"),
31
+ ...locatorFields,
32
+ expected: z.string(),
33
+ match: matchMode,
34
+ }),
35
+ z.object({
36
+ type: z.literal("expect_value"),
37
+ ...locatorFields,
38
+ expected: z.string(),
39
+ }),
40
+ z.object({ type: z.literal("expect_checked"), ...locatorFields }),
41
+ z.object({
42
+ type: z.literal("expect_url"),
43
+ expected: webUrlSchema,
44
+ match: matchMode,
45
+ }),
46
+ ]);
47
+ function locatorFor(page, action) {
48
+ return page.getByRole(action.role, { name: action.name });
49
+ }
50
+ function assertEqual(actual, expected, label) {
51
+ if (actual !== expected) {
52
+ throw new Error(`${label} mismatch: expected ${JSON.stringify(expected)}, received ${JSON.stringify(actual)}`);
53
+ }
54
+ }
55
+ function assertContains(actual, expected, label) {
56
+ if (!actual.includes(expected)) {
57
+ throw new Error(`${label} mismatch: expected ${JSON.stringify(actual)} to contain ${JSON.stringify(expected)}`);
58
+ }
59
+ }
60
+ export async function executeAction(page, action) {
61
+ if (action.type === "expect_url") {
62
+ const actual = page.url();
63
+ if (action.match === "equals")
64
+ assertEqual(actual, action.expected, "URL");
65
+ else
66
+ assertContains(actual, action.expected, "URL");
67
+ return;
68
+ }
69
+ const locator = locatorFor(page, action);
70
+ switch (action.type) {
71
+ case "click":
72
+ await locator.click();
73
+ return;
74
+ case "fill":
75
+ await locator.fill(action.value);
76
+ return;
77
+ case "check":
78
+ await locator.check();
79
+ return;
80
+ case "select_option":
81
+ await locator.selectOption(action.value);
82
+ return;
83
+ case "press":
84
+ await locator.press(action.key);
85
+ return;
86
+ case "expect_visible":
87
+ await locator.waitFor({ state: "visible" });
88
+ return;
89
+ case "expect_hidden":
90
+ await locator.waitFor({ state: "hidden" });
91
+ return;
92
+ case "expect_text": {
93
+ const actual = (await locator.textContent()) ?? "";
94
+ if (action.match === "equals")
95
+ assertEqual(actual, action.expected, "Text");
96
+ else
97
+ assertContains(actual, action.expected, "Text");
98
+ return;
99
+ }
100
+ case "expect_value":
101
+ assertEqual(await locator.inputValue(), action.expected, "Value");
102
+ return;
103
+ case "expect_checked":
104
+ if (!(await locator.isChecked()))
105
+ throw new Error("Expected element to be checked");
106
+ return;
107
+ }
108
+ }
109
+ export function actionDescription(action) {
110
+ if (action.type === "expect_url") {
111
+ return `${action.type} ${action.match} ${JSON.stringify(action.expected)}`;
112
+ }
113
+ return `${action.type} ${action.role} ${JSON.stringify(action.name)}`;
114
+ }
115
+ function compiledLocator(action) {
116
+ return `page.getByRole(${JSON.stringify(action.role)} as any, { name: ${JSON.stringify(action.name)} })`;
117
+ }
118
+ export function compileAction(action) {
119
+ if (action.type === "expect_url") {
120
+ return action.match === "equals"
121
+ ? ` expect(page.url()).toBe(${JSON.stringify(action.expected)});`
122
+ : ` expect(page.url()).toContain(${JSON.stringify(action.expected)});`;
123
+ }
124
+ const locator = compiledLocator(action);
125
+ switch (action.type) {
126
+ case "click":
127
+ return ` await ${locator}.click();`;
128
+ case "fill":
129
+ return ` await ${locator}.fill(${JSON.stringify(action.value)});`;
130
+ case "check":
131
+ return ` await ${locator}.check();`;
132
+ case "select_option":
133
+ return ` await ${locator}.selectOption(${JSON.stringify(action.value)});`;
134
+ case "press":
135
+ return ` await ${locator}.press(${JSON.stringify(action.key)});`;
136
+ case "expect_visible":
137
+ return ` await expect(${locator}).toBeVisible();`;
138
+ case "expect_hidden":
139
+ return ` await expect(${locator}).toBeHidden();`;
140
+ case "expect_text":
141
+ return action.match === "equals"
142
+ ? ` await expect(${locator}).toHaveText(${JSON.stringify(action.expected)});`
143
+ : ` await expect(${locator}).toContainText(${JSON.stringify(action.expected)});`;
144
+ case "expect_value":
145
+ return ` await expect(${locator}).toHaveValue(${JSON.stringify(action.expected)});`;
146
+ case "expect_checked":
147
+ return ` await expect(${locator}).toBeChecked();`;
148
+ }
149
+ }
150
+ export function safeSpecName(testName) {
151
+ const slug = testName
152
+ .normalize("NFKD")
153
+ .replace(/[\u0300-\u036f]/g, "")
154
+ .toLowerCase()
155
+ .replace(/[^a-z0-9]+/g, "-")
156
+ .replace(/^-+|-+$/g, "")
157
+ .slice(0, 80);
158
+ return slug || "forgeqa-generated";
159
+ }
160
+ export function compileSpecSource(testName, targetUrl, actions) {
161
+ const actionLines = actions.map(compileAction).join("\n");
162
+ return `import { expect, test } from "playwright/test";\n\ntest(${JSON.stringify(testName)}, async ({ page }) => {\n await page.goto(${JSON.stringify(targetUrl)});\n${actionLines}\n});\n`;
163
+ }
164
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6,124 +6,26 @@ import path from "node:path";
6
6
  import { chromium } from "playwright";
7
7
  import { z } from "zod";
8
8
  import { verifyGumroadLicense } from "./auth.js";
9
+ import { actionDescription, compileSpecSource, executeAction, qaActionSchema, safeSpecName, webUrlSchema, } from "./core.js";
9
10
  const GUMROAD_PRODUCT_ID = "ZFFt_s2vgLi2UF_E3t3o6A==";
10
11
  const NAVIGATION_TIMEOUT_MS = 30_000;
11
- const webUrlSchema = z
12
- .string()
13
- .url()
14
- .refine((value) => ["http:", "https:"].includes(new URL(value).protocol), {
15
- message: "URL must use http or https",
16
- });
17
- const locatorFields = {
18
- role: z.string().min(1).describe("ARIA role, such as button or textbox"),
19
- name: z.string().min(1).describe("Accessible name of the target element"),
20
- };
21
- const qaActionSchema = z.discriminatedUnion("type", [
22
- z.object({
23
- type: z.literal("click"),
24
- ...locatorFields,
25
- }),
26
- z.object({
27
- type: z.literal("fill"),
28
- ...locatorFields,
29
- value: z.string(),
30
- }),
31
- z.object({
32
- type: z.literal("check"),
33
- ...locatorFields,
34
- }),
35
- z.object({
36
- type: z.literal("select_option"),
37
- ...locatorFields,
38
- value: z.string(),
39
- }),
40
- z.object({
41
- type: z.literal("press"),
42
- ...locatorFields,
43
- key: z.string().min(1),
44
- }),
45
- ]);
46
- const server = new McpServer({
47
- name: "ForgeQA-MCP",
48
- version: "1.0.0",
49
- });
12
+ const server = new McpServer({ name: "ForgeQA-MCP", version: "1.1.0" });
50
13
  function errorMessage(error) {
51
14
  return error instanceof Error ? error.message : String(error);
52
15
  }
53
- function locatorFor(page, action) {
54
- return page.getByRole(action.role, { name: action.name });
55
- }
56
- async function executeAction(page, action) {
57
- const locator = locatorFor(page, action);
58
- switch (action.type) {
59
- case "click":
60
- await locator.click();
61
- return;
62
- case "fill":
63
- await locator.fill(action.value);
64
- return;
65
- case "check":
66
- await locator.check();
67
- return;
68
- case "select_option":
69
- await locator.selectOption(action.value);
70
- return;
71
- case "press":
72
- await locator.press(action.key);
73
- return;
74
- }
75
- }
76
16
  async function captureAccessibilitySnapshot(page) {
77
- // Playwright <=1.49 exposed page.accessibility.snapshot(). Use it when a
78
- // compatible runtime provides it, then fall back to the current structured API.
79
17
  const legacyPage = page;
80
18
  if (legacyPage.accessibility?.snapshot) {
81
19
  return legacyPage.accessibility.snapshot();
82
20
  }
83
21
  return page.ariaSnapshotJSON({ mode: "ai" });
84
22
  }
85
- function actionDescription(action) {
86
- return `${action.type} ${action.role} \"${action.name}\"`;
87
- }
88
- function compileAction(action) {
89
- const locator = `page.getByRole(${JSON.stringify(action.role)} as any, { name: ${JSON.stringify(action.name)} })`;
90
- switch (action.type) {
91
- case "click":
92
- return ` await ${locator}.click();`;
93
- case "fill":
94
- return ` await ${locator}.fill(${JSON.stringify(action.value)});`;
95
- case "check":
96
- return ` await ${locator}.check();`;
97
- case "select_option":
98
- return ` await ${locator}.selectOption(${JSON.stringify(action.value)});`;
99
- case "press":
100
- return ` await ${locator}.press(${JSON.stringify(action.key)});`;
101
- }
102
- }
103
- function safeSpecName(testName) {
104
- const slug = testName
105
- .normalize("NFKD")
106
- .replace(/[\u0300-\u036f]/g, "")
107
- .toLowerCase()
108
- .replace(/[^a-z0-9]+/g, "-")
109
- .replace(/^-+|-+$/g, "")
110
- .slice(0, 80);
111
- return slug || "forgeqa-generated";
112
- }
113
23
  server.registerTool("scan_dom_accessibility", {
114
24
  title: "Scan DOM accessibility",
115
- description: "Navigate to a page and return its accessibility tree as structured content.",
116
- inputSchema: {
117
- url: webUrlSchema.describe("Page URL to scan"),
118
- },
119
- outputSchema: {
120
- url: z.string(),
121
- snapshot: z.unknown(),
122
- },
123
- annotations: {
124
- readOnlyHint: true,
125
- openWorldHint: true,
126
- },
25
+ description: "Open a supplied URL in a fresh headless Chromium session and return its accessibility tree as structured content.",
26
+ inputSchema: { url: webUrlSchema.describe("Page URL to scan") },
27
+ outputSchema: { url: z.string(), snapshot: z.unknown() },
28
+ annotations: { readOnlyHint: true, openWorldHint: true },
127
29
  }, async ({ url }) => {
128
30
  const browser = await chromium.launch({ headless: true });
129
31
  try {
@@ -134,24 +36,14 @@ server.registerTool("scan_dom_accessibility", {
134
36
  });
135
37
  const snapshot = await captureAccessibilitySnapshot(page);
136
38
  return {
137
- content: [
138
- {
139
- type: "text",
140
- text: `Accessibility snapshot captured for ${url}.`,
141
- },
142
- ],
39
+ content: [{ type: "text", text: `Accessibility snapshot captured for ${url}.` }],
143
40
  structuredContent: { url, snapshot },
144
41
  };
145
42
  }
146
43
  catch (error) {
147
44
  return {
148
45
  isError: true,
149
- content: [
150
- {
151
- type: "text",
152
- text: `Accessibility scan failed: ${errorMessage(error)}`,
153
- },
154
- ],
46
+ content: [{ type: "text", text: `Accessibility scan failed: ${errorMessage(error)}` }],
155
47
  };
156
48
  }
157
49
  finally {
@@ -160,7 +52,7 @@ server.registerTool("scan_dom_accessibility", {
160
52
  });
161
53
  server.registerTool("dry_run_qa_flow", {
162
54
  title: "Dry-run QA flow",
163
- description: "Run role-based browser actions and return a step-by-step pass/fail report.",
55
+ description: "Run role-based browser actions and assertions in a fresh headless Chromium session and return a step-by-step pass/fail report.",
164
56
  inputSchema: {
165
57
  url: webUrlSchema.describe("Starting page URL"),
166
58
  actions: z.array(qaActionSchema).min(1),
@@ -175,10 +67,7 @@ server.registerTool("dry_run_qa_flow", {
175
67
  message: z.string(),
176
68
  })),
177
69
  },
178
- annotations: {
179
- readOnlyHint: false,
180
- openWorldHint: true,
181
- },
70
+ annotations: { readOnlyHint: false, openWorldHint: true },
182
71
  }, async ({ url, actions }) => {
183
72
  const browser = await chromium.launch({ headless: true });
184
73
  const logs = [];
@@ -220,7 +109,7 @@ server.registerTool("dry_run_qa_flow", {
220
109
  action: actionDescription(action),
221
110
  status: "passed",
222
111
  duration_ms: Date.now() - started,
223
- message: "Action completed",
112
+ message: "Action or assertion completed",
224
113
  });
225
114
  }
226
115
  catch (error) {
@@ -232,35 +121,20 @@ server.registerTool("dry_run_qa_flow", {
232
121
  message: errorMessage(error),
233
122
  });
234
123
  return {
235
- content: [
236
- {
237
- type: "text",
238
- text: `QA flow failed at step ${index + 1}.`,
239
- },
240
- ],
124
+ content: [{ type: "text", text: `QA flow failed at step ${index + 1}.` }],
241
125
  structuredContent: { passed: false, logs },
242
126
  };
243
127
  }
244
128
  }
245
129
  return {
246
- content: [
247
- {
248
- type: "text",
249
- text: `QA flow passed ${actions.length} action(s).`,
250
- },
251
- ],
130
+ content: [{ type: "text", text: `QA flow passed ${actions.length} step(s).` }],
252
131
  structuredContent: { passed: true, logs },
253
132
  };
254
133
  }
255
134
  catch (error) {
256
135
  return {
257
136
  isError: true,
258
- content: [
259
- {
260
- type: "text",
261
- text: `QA flow could not run: ${errorMessage(error)}`,
262
- },
263
- ],
137
+ content: [{ type: "text", text: `QA flow could not run: ${errorMessage(error)}` }],
264
138
  };
265
139
  }
266
140
  finally {
@@ -269,7 +143,7 @@ server.registerTool("dry_run_qa_flow", {
269
143
  });
270
144
  server.registerTool("compile_playwright_spec", {
271
145
  title: "Compile Playwright spec",
272
- description: "Write validated role-based actions to a Playwright spec in the local tests directory.",
146
+ description: "Write validated role-based browser actions and assertions to a Playwright spec in the local tests directory.",
273
147
  inputSchema: {
274
148
  test_name: z.string().min(1),
275
149
  target_url: webUrlSchema,
@@ -283,24 +157,18 @@ server.registerTool("compile_playwright_spec", {
283
157
  annotations: {
284
158
  readOnlyHint: false,
285
159
  destructiveHint: false,
286
- idempotentHint: true,
160
+ idempotentHint: false,
287
161
  openWorldHint: false,
288
162
  },
289
163
  }, async ({ test_name, target_url, validated_actions }) => {
290
164
  try {
291
165
  const testsDirectory = path.resolve(process.cwd(), "tests");
292
166
  const filePath = path.join(testsDirectory, `${safeSpecName(test_name)}.spec.ts`);
293
- const actionLines = validated_actions.map(compileAction).join("\n");
294
- const source = `import { test } from "playwright/test";\n\ntest(${JSON.stringify(test_name)}, async ({ page }) => {\n await page.goto(${JSON.stringify(target_url)});\n${actionLines}\n});\n`;
167
+ const source = compileSpecSource(test_name, target_url, validated_actions);
295
168
  await mkdir(testsDirectory, { recursive: true });
296
- await writeFile(filePath, source, "utf8");
169
+ await writeFile(filePath, source, { encoding: "utf8", flag: "wx" });
297
170
  return {
298
- content: [
299
- {
300
- type: "text",
301
- text: `Created Playwright spec at ${filePath}.`,
302
- },
303
- ],
171
+ content: [{ type: "text", text: `Created Playwright spec at ${filePath}.` }],
304
172
  structuredContent: {
305
173
  success: true,
306
174
  file_path: filePath,
@@ -311,24 +179,17 @@ server.registerTool("compile_playwright_spec", {
311
179
  catch (error) {
312
180
  return {
313
181
  isError: true,
314
- content: [
315
- {
316
- type: "text",
317
- text: `Could not create Playwright spec: ${errorMessage(error)}`,
318
- },
319
- ],
182
+ content: [{ type: "text", text: `Could not create Playwright spec: ${errorMessage(error)}` }],
320
183
  };
321
184
  }
322
185
  });
323
186
  async function main() {
324
187
  const licenseKey = process.env.GUMROAD_LICENSE_KEY;
325
- if (!licenseKey) {
188
+ if (!licenseKey)
326
189
  throw new Error("GUMROAD_LICENSE_KEY is required");
327
- }
328
190
  const licensed = await verifyGumroadLicense(licenseKey, GUMROAD_PRODUCT_ID);
329
- if (!licensed) {
191
+ if (!licensed)
330
192
  throw new Error("Gumroad license verification failed");
331
- }
332
193
  const transport = new StdioServerTransport();
333
194
  await server.connect(transport);
334
195
  console.error("ForgeQA-MCP is running on stdio");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAa,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AACtD,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAExE,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,IAAU;IACpD,MAAM,UAAU,GAAG,IAElB,CAAC;IACF,IAAI,UAAU,CAAC,aAAa,EAAE,QAAQ,EAAE,CAAC;QACvC,OAAO,UAAU,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;IACE,KAAK,EAAE,wBAAwB;IAC/B,WAAW,EACT,mHAAmH;IACrH,WAAW,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;IAC/D,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE;IACxD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;CACzD,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IAChB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACnB,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,IAAI,CAAC,CAAC;QAC1D,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uCAAuC,GAAG,GAAG,EAAE,CAAC;YAChF,iBAAiB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;SACrC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;SACvF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;IACE,KAAK,EAAE,iBAAiB;IACxB,WAAW,EACT,gIAAgI;IAClI,WAAW,EAAE;QACX,GAAG,EAAE,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC/C,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;KACxC;IACD,YAAY,EAAE;QACZ,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,KAAK,CACX,CAAC,CAAC,MAAM,CAAC;YACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;YACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;SACpB,CAAC,CACH;KACF;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;CAC1D,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;IACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,IAAI,GAML,EAAE,CAAC;IAER,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBACnB,SAAS,EAAE,kBAAkB;gBAC7B,OAAO,EAAE,qBAAqB;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB;gBAC3C,OAAO,EAAE,gBAAgB,GAAG,EAAE;aAC/B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB;gBAC3C,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAC;YACH,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,mCAAmC,EAAE,CAAC;gBAC/E,iBAAiB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;aAC3C,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,KAAK,GAAG,CAAC;oBACf,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC;oBACjC,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;oBACjC,OAAO,EAAE,+BAA+B;iBACzC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,KAAK,GAAG,CAAC;oBACf,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC;oBACjC,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;oBACjC,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC;iBAC7B,CAAC,CAAC;gBACH,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,0BAA0B,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC;oBAClF,iBAAiB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;iBAC3C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,kBAAkB,OAAO,CAAC,MAAM,WAAW,EAAE,CAAC;YACvF,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;SAC1C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,0BAA0B,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;SAC5F,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;IACE,KAAK,EAAE,yBAAyB;IAChC,WAAW,EACT,8GAA8G;IAChH,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5B,UAAU,EAAE,YAAY;QACxB,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;KAClD;IACD,YAAY,EAAE;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;QACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;KACzB;IACD,WAAW,EAAE;QACX,YAAY,EAAE,KAAK;QACnB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,KAAK;QACrB,aAAa,EAAE,KAAK;KACrB;CACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,EAAE;IACrD,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACjF,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAC3E,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,QAAQ,GAAG,EAAE,CAAC;YAC5E,iBAAiB,EAAE;gBACjB,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,QAAQ;gBACnB,YAAY,EAAE,iBAAiB,CAAC,MAAM;aACvC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qCAAqC,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;SAC9F,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACnD,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAEpE,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IAC5E,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEtE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,+BAA+B,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ltorrey/forgeqa-mcp",
3
- "version": "1.0.0",
4
- "description": "Commercial MCP server for local Playwright QA automation",
3
+ "version": "1.1.0",
4
+ "description": "Licensed local MCP server for semantic Playwright E2E testing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -9,23 +9,39 @@
9
9
  },
10
10
  "files": [
11
11
  "dist",
12
- "smithery.yaml"
12
+ "smithery.yaml",
13
+ "README.md",
14
+ "LICENSE.md"
13
15
  ],
14
16
  "scripts": {
15
- "build": "tsc"
17
+ "build": "tsc",
18
+ "typecheck": "tsc --noEmit",
19
+ "test": "npm run build && node --test test/*.test.mjs",
20
+ "prepack": "npm test"
16
21
  },
17
- "keywords": [],
18
- "author": "",
19
- "license": "UNLICENSED",
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "keywords": [
26
+ "mcp",
27
+ "playwright",
28
+ "qa",
29
+ "e2e-testing",
30
+ "accessibility-tree",
31
+ "claude",
32
+ "cursor"
33
+ ],
34
+ "author": "Lajuane Torrey",
35
+ "homepage": "https://lajuanetorrey.gumroad.com/l/forgeqa-ai",
36
+ "license": "SEE LICENSE IN LICENSE.md",
20
37
  "dependencies": {
21
- "@modelcontextprotocol/sdk": "^1.30.0",
22
- "node-fetch": "^3.3.2",
23
- "playwright": "^1.63.0",
24
- "zod": "^4.6.4"
38
+ "@modelcontextprotocol/sdk": "1.30.0",
39
+ "node-fetch": "3.3.2",
40
+ "playwright": "1.63.0",
41
+ "zod": "4.6.4"
25
42
  },
26
43
  "devDependencies": {
27
- "@types/node": "^22.20.2",
28
- "tsx": "^4.23.13",
29
- "typescript": "^7.0.2"
44
+ "@types/node": "22.20.2",
45
+ "typescript": "7.0.2"
30
46
  }
31
47
  }
package/smithery.yaml CHANGED
@@ -7,7 +7,7 @@ startCommand:
7
7
  properties:
8
8
  GUMROAD_LICENSE_KEY:
9
9
  type: string
10
- description: Gumroad license key for ForgeQA-MCP
10
+ description: Gumroad license key for ForgeQA AI
11
11
  commandFunction: |-
12
12
  (config) => ({
13
13
  command: 'node',