pictmcp 0.2.0 → 0.3.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/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # PictMCP
2
2
 
3
- Pairwise Independent Combinatorial Testings for MCP
4
-
5
3
  ## 🚧 Work in Progress 🚧
6
4
 
7
5
  > [!WARNING]
@@ -10,32 +8,27 @@ Pairwise Independent Combinatorial Testings for MCP
10
8
  >
11
9
  > Use in production environments is **not recommended** at this time.
12
10
 
11
+ ## Project overview
12
+
13
+ PictMCP is an MCP (Model Context Protocol) server that provides pairwise combinatorial testing capabilities to AI assistants. It wraps the PICT (Pairwise Independent Combinatorial Testing) algorithm via WebAssembly, enabling AI clients to generate optimized test case combinations.
14
+
13
15
  ## Install
14
16
 
15
17
  ### Prerequisites
16
18
 
17
- - [Node.js](https://nodejs.org/) (v22 or higher)
19
+ - [Node.js](https://nodejs.org/) (v24 or higher)
18
20
  - [pnpm](https://pnpm.io/) (v10 or higher)
19
21
 
20
22
  ### Commands
21
23
 
22
- In your terminal
23
-
24
- ```sh
25
- git clone https://github.com/takeyaqa/PictMCP.git
26
- cd PictMCP
27
- pnpm install
28
- pnpm build
29
- ```
30
-
31
24
  In your MCP client
32
25
 
33
26
  ```json
34
27
  {
35
28
  "mcpServers": {
36
29
  "PictMCP": {
37
- "command": "node",
38
- "args": ["/ABSOLUTE/PATH/TO/PARENT/FOLDER/PictMCP/dist/index.js"]
30
+ "command": "pnpx",
31
+ "args": ["pictmcp"]
39
32
  }
40
33
  }
41
34
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- declare const server: McpServer;
3
- export { server };
1
+ export {};
package/dist/index.js CHANGED
@@ -1,50 +1,15 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
1
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { z } from "zod";
4
- import { PictRunner } from "@takeyaqa/pict-wasm";
5
- // Create server instance
6
- const server = new McpServer({
7
- name: "PictMCP",
8
- version: "0.2.0",
9
- });
10
- // Register pict tools
11
- server.registerTool("generate-test-cases", {
12
- description: "Generates test cases using pairwise combination algorithm",
13
- inputSchema: {
14
- parameters: z
15
- .object({ name: z.string(), values: z.string() })
16
- .array()
17
- .describe("Parameters for the test case generation"),
18
- constraints: z
19
- .string()
20
- .optional()
21
- .describe("Constraints for the test case generation"),
22
- },
23
- }, async ({ parameters, constraints }) => {
24
- const pictRunner = new PictRunner();
25
- await pictRunner.init();
26
- const output = pictRunner.run(parameters, { constraintsText: constraints });
27
- const formattedOutput = output.body.map((row) => row.map((cell) => cell.trim()).join(", "));
28
- const formattedHeader = output.header.map((cell) => cell.trim()).join(", ");
29
- const formattedBody = formattedOutput.join("\n");
30
- const formattedOutputText = `Header: ${formattedHeader}\nBody:\n${formattedBody}`;
31
- return {
32
- content: [
33
- {
34
- type: "text",
35
- text: formattedOutputText,
36
- },
37
- ],
38
- };
39
- });
40
- // export for testing purposes
41
- export { server };
2
+ import { PictMcpServer } from "./server.js";
42
3
  async function main() {
4
+ const server = new PictMcpServer();
43
5
  const transport = new StdioServerTransport();
44
6
  await server.connect(transport);
45
7
  console.error("PictMCP Server running on stdio");
46
8
  }
47
- main().catch((error) => {
9
+ try {
10
+ await main();
11
+ }
12
+ catch (error) {
48
13
  console.error("Fatal error in main():", error);
49
14
  process.exit(1);
50
- });
15
+ }
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare class PictMcpServer extends McpServer {
3
+ constructor();
4
+ }
package/dist/server.js ADDED
@@ -0,0 +1,86 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { PictRunner } from "@takeyaqa/pict-wasm";
4
+ export class PictMcpServer extends McpServer {
5
+ constructor() {
6
+ super({
7
+ name: "io.github.takeyaqa/PictMCP",
8
+ title: "PictMCP",
9
+ version: "0.3.0",
10
+ description: "Provides pairwise combinatorial testing capabilities to AI assistants.",
11
+ websiteUrl: "https://github.com/takeyaqa/PictMCP#readme",
12
+ icons: [
13
+ {
14
+ src: "https://raw.githubusercontent.com/takeyaqa/PictMCP/main/assets/PictMCP_icon@64x64.png",
15
+ mimeType: "image/png",
16
+ sizes: ["64x64"],
17
+ },
18
+ {
19
+ src: "https://raw.githubusercontent.com/takeyaqa/PictMCP/main/assets/PictMCP_icon.svg",
20
+ mimeType: "image/svg+xml",
21
+ sizes: ["any"],
22
+ },
23
+ ],
24
+ });
25
+ // Register pict tools
26
+ this.registerTool("generate-test-cases", {
27
+ title: "Generate test cases",
28
+ description: "Executes PICT with the given parameters and options to generate test cases.",
29
+ inputSchema: {
30
+ parameters: z
31
+ .object({
32
+ name: z.string().describe("The name of the parameter."),
33
+ values: z
34
+ .string()
35
+ .describe("A comma-separated string of possible values for this parameter."),
36
+ })
37
+ .array()
38
+ .describe("Represents a parameter definition for PICT test case generation."),
39
+ constraintsText: z
40
+ .string()
41
+ .optional()
42
+ .describe("PICT constraint expressions to filter invalid combinations."),
43
+ },
44
+ outputSchema: {
45
+ result: z
46
+ .object({
47
+ header: z
48
+ .string()
49
+ .array()
50
+ .describe("An array of parameter names representing the column headers."),
51
+ body: z
52
+ .string()
53
+ .array()
54
+ .array()
55
+ .describe("A two-dimensional array where each inner array represents a test case, with values corresponding to the header columns."),
56
+ })
57
+ .describe("Represents the parsed result of PICT test case generation."),
58
+ modelFile: z
59
+ .string()
60
+ .describe("The complete model file content that was passed to PICT."),
61
+ message: z
62
+ .string()
63
+ .optional()
64
+ .describe("Optional message output from PICT, typically containing information."),
65
+ },
66
+ }, async ({ parameters, constraintsText }) => {
67
+ const pictRunner = await PictRunner.create();
68
+ const output = pictRunner.run(parameters, {
69
+ constraintsText,
70
+ });
71
+ return {
72
+ structuredContent: {
73
+ result: output.result,
74
+ modelFile: output.modelFile,
75
+ message: output.message,
76
+ },
77
+ content: [
78
+ {
79
+ type: "text",
80
+ text: JSON.stringify(output),
81
+ },
82
+ ],
83
+ };
84
+ });
85
+ }
86
+ }
package/package.json CHANGED
@@ -1,9 +1,20 @@
1
1
  {
2
2
  "name": "pictmcp",
3
3
  "mcpName": "io.github.takeyaqa/PictMCP",
4
- "version": "0.2.0",
5
- "description": "Pairwise Testing for the AI",
6
- "keywords": [],
4
+ "version": "0.3.0",
5
+ "description": "MCP (Model Context Protocol) server that provides pairwise combinatorial testing capabilities to AI assistants.",
6
+ "keywords": [
7
+ "mcp",
8
+ "mcp-server",
9
+ "ai",
10
+ "pict",
11
+ "testing",
12
+ "testing-tools",
13
+ "test-case-generation",
14
+ "combinatorial-testing",
15
+ "pairwise",
16
+ "pairwise-testing"
17
+ ],
7
18
  "homepage": "https://github.com/takeyaqa/PictMCP#readme",
8
19
  "bugs": {
9
20
  "url": "https://github.com/takeyaqa/PictMCP/issues"
@@ -23,21 +34,25 @@
23
34
  },
24
35
  "dependencies": {
25
36
  "@modelcontextprotocol/sdk": "^1.25.2",
26
- "@takeyaqa/pict-wasm": "3.7.4-wasm.11",
37
+ "@takeyaqa/pict-wasm": "3.7.4-wasm.12",
27
38
  "zod": "^4.3.5"
28
39
  },
29
40
  "devDependencies": {
30
41
  "@eslint/js": "^9.39.2",
42
+ "@tsconfig/node-ts": "^23.6.2",
31
43
  "@tsconfig/node24": "^24.0.4",
32
44
  "@types/node": "^25.0.9",
45
+ "@vitest/eslint-plugin": "^1.6.6",
33
46
  "eslint": "^9.39.2",
34
47
  "eslint-config-prettier": "^10.1.8",
35
- "globals": "^17.0.0",
36
48
  "prettier": "^3.8.0",
37
49
  "typescript": "~5.9.3",
38
- "typescript-eslint": "^8.53.0",
50
+ "typescript-eslint": "^8.54.0",
39
51
  "vitest": "^4.0.17"
40
52
  },
53
+ "engines": {
54
+ "node": ">=24"
55
+ },
41
56
  "devEngines": {
42
57
  "runtime": {
43
58
  "name": "node",
@@ -53,10 +68,12 @@
53
68
  "scripts": {
54
69
  "build": "tsc && chmod 755 dist/index.js",
55
70
  "clean": "rm -rf dist",
56
- "typecheck": "tsc --noEmit",
71
+ "fmt": "prettier --write .",
72
+ "fmt:check": "prettier --check .",
57
73
  "lint": "eslint .",
58
- "format": "prettier --check .",
74
+ "lint:fix": "eslint --fix .",
75
+ "typecheck": "tsc --project tsconfig.typecheck.json",
59
76
  "test": "vitest",
60
- "test:no-watch": "vitest run"
77
+ "test:run": "vitest run"
61
78
  }
62
79
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,25 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
- import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
4
- import packageJson from "../package.json" with { type: "json" };
5
- import serverJson from "../server.json" with { type: "json" };
6
- import { server } from "./index.js";
7
- describe("PictMCP Server", () => {
8
- let client;
9
- beforeEach(async () => {
10
- const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
11
- client = new Client({ name: "test-client", version: "1.0.0" });
12
- await server.connect(serverTransport);
13
- await client.connect(clientTransport);
14
- });
15
- afterEach(async () => {
16
- await client.close();
17
- await server.close();
18
- });
19
- it("should return version matching package configuration", async () => {
20
- const serverVersion = client.getServerVersion();
21
- expect(serverVersion?.version).toBe(packageJson.version);
22
- expect(serverVersion?.version).toBe(serverJson.version);
23
- expect(serverVersion?.version).toBe(serverJson.packages[0].version);
24
- });
25
- });