mock-mcp 0.1.0 → 0.2.1

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
@@ -4,9 +4,10 @@
4
4
  [![npm](https://img.shields.io/npm/v/mock-mcp.svg)](https://www.npmjs.com/package/mock-mcp)
5
5
  ![license](https://img.shields.io/npm/l/mock-mcp)
6
6
 
7
- Mock MCP orchestrates AI-generated mock data via the Model Context Protocol (MCP). The project pairs a WebSocket batch bridge with MCP tooling so Cursor, Claude Desktop, or any compatible client can fulfill intercepted requests in real time.
7
+ Mock MCP Server - AI-generated mock data. The project pairs a WebSocket batch bridge with MCP tooling so Cursor, Claude Desktop, or any compatible client can fulfill intercepted requests in real time.
8
8
 
9
9
  ## Table of Contents
10
+
10
11
  - [Quick Start](#quick-start)
11
12
  - [Why Mock MCP](#why-mock-mcp)
12
13
  - [What Mock MCP Does](#what-mock-mcp-does)
@@ -44,7 +45,7 @@ Mock MCP orchestrates AI-generated mock data via the Model Context Protocol (MCP
44
45
  ```ts
45
46
  import { render, screen, fireEvent } from "@testing-library/react";
46
47
  import { connect } from "mock-mcp";
47
-
48
+
48
49
  const userSchema = {
49
50
  summary: "Fetch the current user",
50
51
  response: {
@@ -52,23 +53,23 @@ Mock MCP orchestrates AI-generated mock data via the Model Context Protocol (MCP
52
53
  required: ["id", "name"],
53
54
  properties: {
54
55
  id: { type: "number" },
55
- name: { type: "string" }
56
- }
57
- }
56
+ name: { type: "string" },
57
+ },
58
+ },
58
59
  };
59
-
60
+
60
61
  it("example", async () => {
61
62
  const mockClient = await connect();
62
63
  const metadata = {
63
64
  schemaUrl: "https://example.com/openapi.json#/paths/~1user/get",
64
65
  schema: userSchema,
65
- instructions: "Respond with a single user described by the schema."
66
+ instructions: "Respond with a single user described by the schema.",
66
67
  };
67
-
68
+
68
69
  fetchMock.get("/user", () =>
69
70
  mockClient.requestMock("/user", "GET", { metadata })
70
71
  );
71
-
72
+
72
73
  const result = await fetch("/user");
73
74
  const data = await result.json();
74
75
  expect(data).toEqual({ id: 1, name: "Jane" });
@@ -98,13 +99,13 @@ const mockUsers = [
98
99
 
99
100
  **Common Pain Points:**
100
101
 
101
- | Challenge | Traditional Solutions | Limitations |
102
- |-----------|----------------------|-------------|
103
- | **Creating Realistic Data** | Manual JSON files or faker.js | ❌ Time-consuming, lacks business logic |
104
- | **Complex Scenarios** | Hardcoded edge cases | ❌ Difficult to maintain, brittle |
105
- | **Evolving Requirements** | Update fixtures manually | ❌ High maintenance cost |
106
- | **Learning Curve** | New team members write fixtures | ❌ Steep learning curve for complex domains |
107
- | **CI/CD Integration** | Static fixtures only | ❌ Can't adapt to new scenarios |
102
+ | Challenge | Traditional Solutions | Limitations |
103
+ | --------------------------- | ------------------------------- | ------------------------------------------- |
104
+ | **Creating Realistic Data** | Manual JSON files or faker.js | ❌ Time-consuming, lacks business logic |
105
+ | **Complex Scenarios** | Hardcoded edge cases | ❌ Difficult to maintain, brittle |
106
+ | **Evolving Requirements** | Update fixtures manually | ❌ High maintenance cost |
107
+ | **Learning Curve** | New team members write fixtures | ❌ Steep learning curve for complex domains |
108
+ | **CI/CD Integration** | Static fixtures only | ❌ Can't adapt to new scenarios |
108
109
 
109
110
  ### The Mock MCP Innovation
110
111
 
@@ -133,10 +134,10 @@ Mock MCP pairs a WebSocket batch bridge with MCP tooling to move intercepted req
133
134
 
134
135
  CLI flags keep the WebSocket bridge and the MCP transports aligned. Use them to adapt the server to your local ports while the Environment Variables section covers per-process overrides:
135
136
 
136
- | Option | Description | Default |
137
- | ----------------- | ------------------------------------------------------------------ | ------- |
138
- | `--port`, `-p` | WebSocket port for test runners | `3002` |
139
- | `--no-stdio` | Disable the MCP stdio transport (useful for local debugging/tests) | enabled |
137
+ | Option | Description | Default |
138
+ | -------------- | ------------------------------------------------------------------ | ------- |
139
+ | `--port`, `-p` | WebSocket port for test runners | `3002` |
140
+ | `--no-stdio` | Disable the MCP stdio transport (useful for local debugging/tests) | enabled |
140
141
 
141
142
  The CLI installs a SIGINT/SIGTERM handler so `Ctrl+C` shuts everything down cleanly.
142
143
 
@@ -205,21 +206,22 @@ const listProductsSchema = {
205
206
  properties: {
206
207
  id: { type: "string" },
207
208
  name: { type: "string" },
208
- price: { type: "number" }
209
- }
210
- }
211
- }
209
+ price: { type: "number" },
210
+ },
211
+ },
212
+ },
212
213
  };
213
214
 
214
215
  await mockClient.requestMock("/api/products", "GET", {
215
216
  metadata: {
216
217
  // Link or embed the authoritative contract for the AI to follow.
217
- schemaUrl: "https://shop.example.com/openapi.json#/paths/~1api~1products/get",
218
+ schemaUrl:
219
+ "https://shop.example.com/openapi.json#/paths/~1api~1products/get",
218
220
  schema: listProductsSchema,
219
221
  instructions:
220
222
  "Return 3 popular products with stable ids so the UI can snapshot them.",
221
- testFile: expect.getState().testPath
222
- }
223
+ testFile: expect.getState().testPath,
224
+ },
223
225
  });
224
226
  ```
225
227
 
@@ -265,20 +267,20 @@ Each class accepts logger overrides, timeout tweaks, and other ergonomics surfac
265
267
 
266
268
  ## Environment Variables
267
269
 
268
- | Variable | Description | Default |
269
- | ----------------- | --------------------------------------------------------------------------- | ------- |
270
- | `MCP_SERVER_PORT` | Overrides the WebSocket port used by both the CLI and any spawned MCP host. | `3002` |
270
+ | Variable | Description | Default |
271
+ | ----------------- | ---------------------------------------------------------------------------- | ------- |
272
+ | `MCP_SERVER_PORT` | Overrides the WebSocket port used by both the CLI and any spawned MCP host. | `3002` |
271
273
  | `MOCK_MCP` | Enables the test runner hook so intercepted requests are routed to mock-mcp. | unset |
272
274
 
273
275
  ## How It Works
274
276
 
275
277
  Three collaborating processes share responsibilities while staying loosely coupled:
276
278
 
277
- | Process | Responsibility | Technology | Communication |
278
- | ---------------- | ------------------------------------------------------- | -------------------------------------------- | ------------------------------------------ |
279
- | **Test Process** | Executes test cases and intercepts HTTP requests | Playwright/Puppeteer + WebSocket client | WebSocket → MCP Server |
280
- | **MCP Server** | Coordinates batches and forwards data between parties | Node.js + WebSocket server + MCP SDK | stdio ↔ MCP Client · WebSocket ↔ Test Flow |
281
- | **MCP Client** | Uses AI to produce mock data via MCP tools | Cursor / Claude Desktop / custom clients | MCP protocol → MCP Server |
279
+ | Process | Responsibility | Technology | Communication |
280
+ | ---------------- | ----------------------------------------------------- | ---------------------------------------- | ------------------------------------------ |
281
+ | **Test Process** | Executes test cases and intercepts HTTP requests | Playwright/Puppeteer + WebSocket client | WebSocket → MCP Server |
282
+ | **MCP Server** | Coordinates batches and forwards data between parties | Node.js + WebSocket server + MCP SDK | stdio ↔ MCP Client · WebSocket ↔ Test Flow |
283
+ | **MCP Client** | Uses AI to produce mock data via MCP tools | Cursor / Claude Desktop / custom clients | MCP protocol → MCP Server |
282
284
 
283
285
  ### Data flow sequence clarifies message order
284
286
 
@@ -27,9 +27,9 @@ async function runCli() {
27
27
  enableMcpTransport,
28
28
  });
29
29
  await server.start();
30
- console.log(`🎯 Test Mock MCP server ready on ws://localhost:${server.port ?? port}`);
30
+ console.error(`🎯 Test Mock MCP server ready on ws://localhost:${server.port ?? port}`);
31
31
  const shutdown = async () => {
32
- console.log("👋 Shutting down Test Mock MCP server...");
32
+ console.error("👋 Shutting down Test Mock MCP server...");
33
33
  await server.stop();
34
34
  process.exit(0);
35
35
  };
@@ -130,7 +130,7 @@ export class TestMockMCPServer {
130
130
  };
131
131
  batch.ws.send(JSON.stringify(payload));
132
132
  this.pendingBatches.delete(batchId);
133
- this.logger.log(`✅ Delivered ${mocks.length} mock(s) to test process for ${batchId}`);
133
+ this.logger.error(`✅ Delivered ${mocks.length} mock(s) to test process for ${batchId}`);
134
134
  return this.buildToolResponse(JSON.stringify({
135
135
  success: true,
136
136
  message: `Provided mock data for ${batchId}`,
@@ -147,7 +147,7 @@ export class TestMockMCPServer {
147
147
  wss.once("listening", () => {
148
148
  const address = wss.address();
149
149
  this.actualPort = address?.port ?? desiredPort;
150
- this.logger.log(`🚀 WebSocket server listening on ws://localhost:${this.actualPort}`);
150
+ this.logger.error(`🚀 WebSocket server listening on ws://localhost:${this.actualPort}`);
151
151
  resolve();
152
152
  });
153
153
  wss.once("error", (error) => {
@@ -228,7 +228,7 @@ export class TestMockMCPServer {
228
228
  this.mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
229
229
  const toolName = request.params.name;
230
230
  if (toolName === "get_pending_batches") {
231
- this.logger.log("📋 MCP client inspected pending batches");
231
+ this.logger.error("📋 MCP client inspected pending batches");
232
232
  return this.buildToolResponse(JSON.stringify(this.getPendingBatches(), null, 2));
233
233
  }
234
234
  if (toolName === "provide_batch_mock_data") {
@@ -243,14 +243,14 @@ export class TestMockMCPServer {
243
243
  this.transport =
244
244
  this.options.transportFactory?.() ?? new StdioServerTransport();
245
245
  await this.mcpServer.connect(this.transport);
246
- this.logger.log("✅ MCP server is ready (stdio transport)");
246
+ this.logger.error("✅ MCP server is ready (stdio transport)");
247
247
  }
248
248
  handleConnection(ws) {
249
- this.logger.log("🔌 Test process connected");
249
+ this.logger.error("🔌 Test process connected");
250
250
  this.clients.add(ws);
251
251
  ws.on("message", (data) => this.handleClientMessage(ws, data));
252
252
  ws.on("close", () => {
253
- this.logger.log("🔌 Test process disconnected");
253
+ this.logger.error("🔌 Test process disconnected");
254
254
  this.clients.delete(ws);
255
255
  this.dropBatchesForClient(ws);
256
256
  });
@@ -292,11 +292,11 @@ export class TestMockMCPServer {
292
292
  ws,
293
293
  expiresAt,
294
294
  });
295
- this.logger.log([
295
+ this.logger.error([
296
296
  `📥 Received ${requests.length} request(s) (${batchId})`,
297
297
  ...requests.map((req, index) => ` ${index + 1}. ${req.method} ${req.endpoint} (${req.requestId})`),
298
298
  ].join("\n"));
299
- this.logger.log("⏳ Awaiting mock data from MCP client...");
299
+ this.logger.error("⏳ Awaiting mock data from MCP client...");
300
300
  }
301
301
  dropBatchesForClient(ws) {
302
302
  for (const [batchId, batch] of this.pendingBatches) {
@@ -325,7 +325,7 @@ export class TestMockMCPServer {
325
325
  const entry = this.buildLogEntry(batch, mocks);
326
326
  const filePath = path.join(directory, `mock-${batch.batchId}.json`);
327
327
  await writeFile(filePath, JSON.stringify(entry, null, 2), "utf8");
328
- this.logger.log(`📝 Saved mock batch ${batch.batchId} to ${filePath}`);
328
+ this.logger.error(`📝 Saved mock batch ${batch.batchId} to ${filePath}`);
329
329
  }
330
330
  buildLogEntry(batch, mocks) {
331
331
  const mockMap = new Map(mocks.map((mock) => [mock.requestId, mock]));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mock-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "An MCP server enabling LLMs to write integration tests through live test environment interaction",
5
5
  "main": "./dist/connect.cjs",
6
6
  "type": "module",
package/dist/package.json DELETED
@@ -1,73 +0,0 @@
1
- {
2
- "name": "mock-mcp",
3
- "version": "0.1.0",
4
- "description": "An MCP server enabling LLMs to write integration tests through live test environment interaction",
5
- "main": "./dist/connect.cjs",
6
- "type": "module",
7
- "bin": {
8
- "mock-mcp": "dist/index.js"
9
- },
10
- "files": [
11
- "dist"
12
- ],
13
- "publishConfig": {
14
- "access": "public"
15
- },
16
- "engines": {
17
- "node": ">=18.0.0"
18
- },
19
- "scripts": {
20
- "build": "tsc && tsup src/client/connect.ts --dts",
21
- "start": "node dist/index.js",
22
- "dev": "tsx src/index.ts",
23
- "lint": "eslint . --ext .ts",
24
- "test": "vitest run",
25
- "test:watch": "vitest --watch",
26
- "prepublishOnly": "npm run build",
27
- "link": "npm link",
28
- "unlink": "npm unlink",
29
- "commit": "yarn git-cz"
30
- },
31
- "keywords": [
32
- "mcp",
33
- "model-context-protocol",
34
- "mock",
35
- "mock-mcp"
36
- ],
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/mcpland/mock-mcp.git"
40
- },
41
- "author": "unadlib",
42
- "license": "MIT",
43
- "dependencies": {
44
- "@cfworker/json-schema": "^4.1.1",
45
- "@modelcontextprotocol/sdk": "^1.20.2",
46
- "ts-morph": "^27.0.2",
47
- "ws": "^8.18.3",
48
- "zod": "^4.1.12"
49
- },
50
- "devDependencies": {
51
- "@types/node": "^24.0.15",
52
- "@types/ws": "^8.18.1",
53
- "@typescript-eslint/eslint-plugin": "^8.38.0",
54
- "@typescript-eslint/parser": "^8.38.0",
55
- "@vitest/coverage-v8": "^3.2.4",
56
- "commitizen": "^4.3.1",
57
- "eslint": "^9.31.0",
58
- "node-fetch": "^3.3.2",
59
- "tsup": "^8.5.0",
60
- "tsx": "^4.20.3",
61
- "typescript": "^5.8.3",
62
- "vite": "^7.0.5",
63
- "vitest": "^3.2.4"
64
- },
65
- "resolutions": {
66
- "rollup": "4.52.5"
67
- },
68
- "config": {
69
- "commitizen": {
70
- "path": "cz-conventional-changelog"
71
- }
72
- }
73
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes