wopee-mcp 1.27.0 → 1.28.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.
@@ -10,11 +10,15 @@ import { wopeeFetchRecentExecutions } from "./wopee_fetch_recent_executions/inde
10
10
  import { wopeeSendChatMessage } from "./wopee_send_chat_message/index.js";
11
11
  import { wopeeReadChatHistory } from "./wopee_read_chat_history/index.js";
12
12
  import { wopeeCreateGithubIssue } from "./wopee_create_github_issue/index.js";
13
+ import { wopeeFetchVariables } from "./wopee_fetch_variables/index.js";
14
+ import { wopeeUpdateVariables } from "./wopee_update_variables/index.js";
13
15
  export const TOOLS = [
14
16
  wopeeCreateBlankSuite,
15
17
  wopeeFetchAnalysisSuites,
16
18
  wopeeFetchExecutedTestCases,
17
19
  wopeeFetchRecentExecutions,
20
+ wopeeFetchVariables,
21
+ wopeeUpdateVariables,
18
22
  wopeeDispatchAnalysis,
19
23
  wopeeDispatchAgent,
20
24
  wopeeFetchArtifact,
@@ -13,6 +13,26 @@ export const UpdateArtifact = `
13
13
  updateArtifact(input: $input)
14
14
  }
15
15
  `;
16
+ export const FetchProjectVariables = `
17
+ query FetchProjectVariables($projectUuid: ID!) {
18
+ fetchProjectVariables(projectUuid: $projectUuid)
19
+ }
20
+ `;
21
+ export const FetchSuiteVariables = `
22
+ query FetchSuiteVariables($suiteUuid: ID!) {
23
+ fetchSuiteVariables(suiteUuid: $suiteUuid)
24
+ }
25
+ `;
26
+ export const UpdateProjectVariables = `
27
+ mutation UpdateProjectVariables($input: UpdateProjectVariablesInput!) {
28
+ updateProjectVariables(input: $input)
29
+ }
30
+ `;
31
+ export const UpdateSuiteVariables = `
32
+ mutation UpdateSuiteVariables($suiteUuid: ID!, $additionalVariables: String!) {
33
+ updateSuiteVariables(suiteUuid: $suiteUuid, additionalVariables: $additionalVariables)
34
+ }
35
+ `;
16
36
  export const DispatchAgent = `
17
37
  mutation DispatchAgent(
18
38
  $input: TestCasesInput!
@@ -14,6 +14,18 @@ export const SuiteAnalysisConfigSchema = z.object({
14
14
  additionalInstructions: z.string().nullable().default(null),
15
15
  additionalVariables: z.string().nullable().default(null),
16
16
  });
17
+ // Shared by wopee_dispatch_analysis and wopee_update_variables. Keys must be
18
+ // uppercase (server enforces the same EnvVarKeyRegex on write).
19
+ export const AdditionalVariableSchema = z.object({
20
+ key: z
21
+ .string({
22
+ description: "Variable name. Must be uppercase with underscores only (e.g. MY_VAR, BASE_URL).",
23
+ })
24
+ .regex(/^[A-Z_][A-Z0-9_]*$/, "Key must be uppercase alphanumeric with underscores, starting with a letter or underscore"),
25
+ value: z
26
+ .string({ description: "Variable value. Must be a non-empty string." })
27
+ .min(1, "Value must be a non-empty string"),
28
+ });
17
29
  export const GenerateAIDataHandlerInputSchema = z.object({
18
30
  type: z.nativeEnum(GenerateArtifactType, {
19
31
  description: "Type of test artifact to generate. One of: APP_CONTEXT, GENERAL_USER_STORIES, USER_STORIES_WITH_TEST_CASES, TEST_CASES, TEST_CASE_STEPS, REUSABLE_TEST_CASES, REUSABLE_TEST_CASE_STEPS. Start with APP_CONTEXT, then generate stories and test cases from it.",
@@ -12,7 +12,14 @@ export var ToolName;
12
12
  ToolName["WOPEE_SEND_CHAT_MESSAGE"] = "wopee_send_chat_message";
13
13
  ToolName["WOPEE_READ_CHAT_HISTORY"] = "wopee_read_chat_history";
14
14
  ToolName["WOPEE_CREATE_GITHUB_ISSUE"] = "wopee_create_github_issue";
15
+ ToolName["WOPEE_FETCH_VARIABLES"] = "wopee_fetch_variables";
16
+ ToolName["WOPEE_UPDATE_VARIABLES"] = "wopee_update_variables";
15
17
  })(ToolName || (ToolName = {}));
18
+ export var VariableLevel;
19
+ (function (VariableLevel) {
20
+ VariableLevel["PROJECT"] = "PROJECT";
21
+ VariableLevel["ANALYSIS"] = "ANALYSIS";
22
+ })(VariableLevel || (VariableLevel = {}));
16
23
  export var GenerateArtifactType;
17
24
  (function (GenerateArtifactType) {
18
25
  GenerateArtifactType["APP_CONTEXT"] = "APP_CONTEXT";
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { SuiteAnalysisConfigSchema } from "../shared/schemas.js";
2
+ import { SuiteAnalysisConfigSchema, AdditionalVariableSchema, } from "../shared/schemas.js";
3
3
  var RerunMode;
4
4
  (function (RerunMode) {
5
5
  RerunMode["FULL"] = "FULL";
@@ -15,16 +15,6 @@ export const DispatchAnalysisInputSchema = z.object({
15
15
  suiteAnalysisConfig: SuiteAnalysisConfigSchema,
16
16
  rerun: RerunOptionsSchema.nullable().default(null),
17
17
  });
18
- const AdditionalVariableSchema = z.object({
19
- key: z
20
- .string({
21
- description: "Variable name. Must be uppercase with underscores only (e.g. MY_VAR, BASE_URL).",
22
- })
23
- .regex(/^[A-Z_][A-Z0-9_]*$/, "Key must be uppercase alphanumeric with underscores, starting with a letter or underscore"),
24
- value: z
25
- .string({ description: "Variable value. Must be a non-empty string." })
26
- .min(1, "Value must be a non-empty string"),
27
- });
28
18
  const WopeeRerunOptionsSchema = z.object({
29
19
  suiteUuid: z
30
20
  .string({
@@ -0,0 +1,36 @@
1
+ import { getConfig } from "../../utils/getConfig.js";
2
+ import { requestClient } from "../../utils/requestClient.js";
3
+ import { _parseError } from "../shared/helpers.js";
4
+ import { ToolName, VariableLevel } from "../shared/types.js";
5
+ import { FetchProjectVariables, FetchSuiteVariables, } from "../shared/gql-queries.js";
6
+ import { WopeeFetchVariablesInputSchema, } from "./schema.js";
7
+ const textResult = (text) => ({
8
+ content: [{ type: "text", text }],
9
+ });
10
+ export const wopeeFetchVariables = {
11
+ name: ToolName.WOPEE_FETCH_VARIABLES,
12
+ config: {
13
+ title: "Fetch run-time variables",
14
+ description: "Read the run-time variables (additionalVariables) that drive analysis/agent runs, at either level. level: PROJECT returns the project-level variables (uses WOPEE_PROJECT_UUID from the environment); level: ANALYSIS returns a specific analysis suite's variables and requires suiteUuid. Read-only. Returns a JSON string array of { key, value, sourceType } entries, or [] when none are set. Use wopee_fetch_analysis_suites to discover suite UUIDs.",
15
+ inputSchema: WopeeFetchVariablesInputSchema.shape,
16
+ },
17
+ handler: async (input) => {
18
+ try {
19
+ const { level, suiteUuid } = input;
20
+ if (level === VariableLevel.ANALYSIS) {
21
+ if (!suiteUuid)
22
+ return textResult("suiteUuid is required when level is ANALYSIS");
23
+ const result = await requestClient(FetchSuiteVariables, { suiteUuid });
24
+ return textResult(result?.fetchSuiteVariables ?? "[]");
25
+ }
26
+ const { WOPEE_PROJECT_UUID } = getConfig();
27
+ if (!WOPEE_PROJECT_UUID)
28
+ return textResult("WOPEE_PROJECT_UUID is not set");
29
+ const result = await requestClient(FetchProjectVariables, { projectUuid: WOPEE_PROJECT_UUID });
30
+ return textResult(result?.fetchProjectVariables ?? "[]");
31
+ }
32
+ catch (error) {
33
+ return _parseError(error);
34
+ }
35
+ },
36
+ };
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ import { VariableLevel } from "../shared/types.js";
3
+ export const WopeeFetchVariablesInputSchema = z.object({
4
+ level: z.nativeEnum(VariableLevel, {
5
+ description: "Which variable set to read. PROJECT reads the project-level variables (uses WOPEE_PROJECT_UUID from the environment). ANALYSIS reads a specific analysis suite's variables and requires suiteUuid.",
6
+ }),
7
+ suiteUuid: z
8
+ .string({
9
+ description: "UUID of the analysis suite to read variables from. Required when level is ANALYSIS; ignored when level is PROJECT.",
10
+ })
11
+ .nullish(),
12
+ });
@@ -0,0 +1,24 @@
1
+ import { getConfig } from "../../utils/getConfig.js";
2
+ /**
3
+ * Wire payload for the updateSuiteVariables mutation. The handler guarantees
4
+ * suiteUuid is present before calling this (ANALYSIS level).
5
+ */
6
+ export const createUpdateSuiteVariablesInput = (input) => ({
7
+ suiteUuid: input.suiteUuid,
8
+ additionalVariables: JSON.stringify(input.variables),
9
+ });
10
+ /**
11
+ * Wire payload for the updateProjectVariables mutation, injecting
12
+ * WOPEE_PROJECT_UUID from the environment (PROJECT level).
13
+ */
14
+ export const createUpdateProjectVariablesInput = (input) => {
15
+ const { WOPEE_PROJECT_UUID } = getConfig();
16
+ if (!WOPEE_PROJECT_UUID)
17
+ throw new Error("WOPEE_PROJECT_UUID is not set");
18
+ return {
19
+ input: {
20
+ projectUuid: WOPEE_PROJECT_UUID,
21
+ additionalVariables: JSON.stringify(input.variables),
22
+ },
23
+ };
24
+ };
@@ -0,0 +1,38 @@
1
+ import { requestClient } from "../../utils/requestClient.js";
2
+ import { withRetry } from "../../utils/withRetry.js";
3
+ import { _parseError } from "../shared/helpers.js";
4
+ import { ToolName, VariableLevel } from "../shared/types.js";
5
+ import { UpdateProjectVariables, UpdateSuiteVariables, } from "../shared/gql-queries.js";
6
+ import { createUpdateProjectVariablesInput, createUpdateSuiteVariablesInput, } from "./factory.js";
7
+ import { WopeeUpdateVariablesInputSchema, } from "./schema.js";
8
+ const textResult = (text) => ({
9
+ content: [{ type: "text", text }],
10
+ });
11
+ export const wopeeUpdateVariables = {
12
+ name: ToolName.WOPEE_UPDATE_VARIABLES,
13
+ config: {
14
+ title: "Update run-time variables",
15
+ description: "Upsert the run-time variables (additionalVariables) that drive analysis/agent runs, at either level. level: PROJECT writes the project-level variables (uses WOPEE_PROJECT_UUID from the environment); level: ANALYSIS writes a specific analysis suite's variables and requires suiteUuid. Merge semantics: keys in variables[] are added or overwritten, existing keys not listed are preserved. Keys must be uppercase (e.g. BASE_URL); the server re-sanitizes and drops invalid keys. Returns a confirmation on success.",
16
+ inputSchema: WopeeUpdateVariablesInputSchema.shape,
17
+ },
18
+ handler: async (input) => {
19
+ try {
20
+ const { level, suiteUuid } = input;
21
+ if (level === VariableLevel.ANALYSIS) {
22
+ if (!suiteUuid)
23
+ return textResult("suiteUuid is required when level is ANALYSIS");
24
+ const result = await withRetry(() => requestClient(UpdateSuiteVariables, createUpdateSuiteVariablesInput(input)));
25
+ if (!result?.updateSuiteVariables)
26
+ return textResult("Failed to update suite variables");
27
+ return textResult("Suite variables updated successfully");
28
+ }
29
+ const result = await withRetry(() => requestClient(UpdateProjectVariables, createUpdateProjectVariablesInput(input)));
30
+ if (!result?.updateProjectVariables)
31
+ return textResult("Failed to update project variables");
32
+ return textResult("Project variables updated successfully");
33
+ }
34
+ catch (error) {
35
+ return _parseError(error);
36
+ }
37
+ },
38
+ };
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import { VariableLevel } from "../shared/types.js";
3
+ import { AdditionalVariableSchema } from "../shared/schemas.js";
4
+ export const WopeeUpdateVariablesInputSchema = z.object({
5
+ level: z.nativeEnum(VariableLevel, {
6
+ description: "Which variable set to write. PROJECT writes the project-level variables (uses WOPEE_PROJECT_UUID from the environment). ANALYSIS writes a specific analysis suite's variables and requires suiteUuid.",
7
+ }),
8
+ suiteUuid: z
9
+ .string({
10
+ description: "UUID of the analysis suite to write variables to. Required when level is ANALYSIS; ignored when level is PROJECT.",
11
+ })
12
+ .nullish(),
13
+ variables: z.array(AdditionalVariableSchema, {
14
+ description: "Variables to upsert. Each needs an uppercase key (e.g. BASE_URL) and a non-empty value. Merge semantics: keys listed here are added or overwritten; existing keys not listed here are preserved.",
15
+ }),
16
+ });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "bin": {
5
5
  "wopee-mcp": "./build/index.js"
6
6
  },
7
- "version": "1.27.0",
7
+ "version": "1.28.0",
8
8
  "mcpName": "io.github.Wopee-io/wopee-mcp",
9
9
  "description": "Wopee.io MCP server for autonomous testing platform",
10
10
  "main": "./build/index.js",