mocktail-mcp 3.1.4

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 (3) hide show
  1. package/README.md +91 -0
  2. package/index.js +196 -0
  3. package/package.json +23 -0
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # Mocktail MCP Server
2
+
3
+ An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that lets AI assistants manage [Mocktail](https://github.com/Huseyinnurbaki/mocktail) mock API endpoints through natural language.
4
+
5
+ ## Tools
6
+
7
+ | Tool | Description |
8
+ |------|-------------|
9
+ | `list_mocks` | List all configured mock endpoints |
10
+ | `create_mock` | Create a single mock endpoint |
11
+ | `update_mock` | Update an existing mock by ID |
12
+ | `delete_mock` | Delete a mock by ID |
13
+ | `import_mocks` | Bulk import multiple mock endpoints (skips duplicates) |
14
+
15
+ ## Environment Variables
16
+
17
+ | Variable | Required | Description |
18
+ |----------|----------|-------------|
19
+ | `MOCKTAIL_URL` | Yes | Base URL of your Mocktail instance (e.g. `http://localhost:4000`) |
20
+ | `MOCKTAIL_API_KEY` | No | API key, sent as `X-API-Key` header |
21
+
22
+ > **Note:** If you're running Mocktail behind a reverse proxy or custom domain (via `MOCKTAIL_BASE_URL`), use that host as `MOCKTAIL_URL` (e.g. `MOCKTAIL_URL=https://api.mycompany.com`).
23
+
24
+ ## Setup
25
+
26
+ ### npx (Recommended)
27
+
28
+ **Claude Code:**
29
+ ```bash
30
+ claude mcp add mocktail \
31
+ -e MOCKTAIL_URL=http://localhost:4000 \
32
+ -e MOCKTAIL_API_KEY=your-api-key \
33
+ -- npx mocktail-mcp
34
+ ```
35
+
36
+ **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "mocktail": {
41
+ "command": "npx",
42
+ "args": ["mocktail-mcp"],
43
+ "env": {
44
+ "MOCKTAIL_URL": "http://localhost:4000",
45
+ "MOCKTAIL_API_KEY": "your-api-key"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### From Source (Development)
53
+
54
+ If you cloned the repo and want to run the MCP server locally:
55
+
56
+ ```bash
57
+ cd mcp-server && npm install
58
+ ```
59
+
60
+ **Claude Code:**
61
+ ```bash
62
+ claude mcp add mocktail \
63
+ -e MOCKTAIL_URL=http://localhost:4000 \
64
+ -e MOCKTAIL_API_KEY=your-api-key \
65
+ -- node /absolute/path/to/mcp-server/index.js
66
+ ```
67
+
68
+ **Claude Desktop:**
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "mocktail": {
73
+ "command": "node",
74
+ "args": ["/absolute/path/to/mcp-server/index.js"],
75
+ "env": {
76
+ "MOCKTAIL_URL": "http://localhost:4000",
77
+ "MOCKTAIL_API_KEY": "your-api-key"
78
+ }
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Usage Examples
85
+
86
+ Once connected, you can use natural language:
87
+
88
+ - "List all my mock endpoints"
89
+ - "Create a GET /api/users mock that returns a list of 3 users"
90
+ - "Delete mock endpoint #5"
91
+ - "Import mock endpoints for a blog API with posts, comments, and authors"
package/index.js ADDED
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { z } from "zod";
6
+
7
+ const MOCKTAIL_URL = process.env.MOCKTAIL_URL;
8
+ const MOCKTAIL_API_KEY = process.env.MOCKTAIL_API_KEY || "";
9
+
10
+ if (!MOCKTAIL_URL) {
11
+ console.error("MOCKTAIL_URL environment variable is required");
12
+ process.exit(1);
13
+ }
14
+
15
+ async function mocktailRequest(path, options = {}) {
16
+ const url = `${MOCKTAIL_URL}${path}`;
17
+ const headers = { "Content-Type": "application/json" };
18
+ if (MOCKTAIL_API_KEY) {
19
+ headers["X-API-Key"] = MOCKTAIL_API_KEY;
20
+ }
21
+
22
+ const res = await fetch(url, { ...options, headers });
23
+ const body = await res.json();
24
+
25
+ if (!res.ok) {
26
+ throw new Error(body.message || `Request failed with status ${res.status}`);
27
+ }
28
+ return body;
29
+ }
30
+
31
+ const server = new McpServer({
32
+ name: "mocktail",
33
+ version: "3.1.4",
34
+ });
35
+
36
+ // list_mocks
37
+ server.tool(
38
+ "list_mocks",
39
+ "List all configured mock endpoints in Mocktail",
40
+ {},
41
+ async () => {
42
+ try {
43
+ const mocks = await mocktailRequest("/core/v1/apis");
44
+ return {
45
+ content: [{ type: "text", text: JSON.stringify(mocks, null, 2) + `\n\nMock endpoints are accessible at: ${MOCKTAIL_URL}/mocktail{Endpoint}` }],
46
+ };
47
+ } catch (err) {
48
+ return {
49
+ isError: true,
50
+ content: [{ type: "text", text: `Error: ${err.message}` }],
51
+ };
52
+ }
53
+ }
54
+ );
55
+
56
+ // create_mock
57
+ server.tool(
58
+ "create_mock",
59
+ "Create a new mock endpoint. Method must be GET, POST, PUT, PATCH, or DELETE. Response should be a JSON value (object, array, string, etc.). The endpoint path is relative — e.g. '/api/users' becomes accessible at MOCKTAIL_URL/mocktail/api/users.",
60
+ {
61
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
62
+ endpoint: z.string().describe("URL path starting with /, e.g. /api/users. Accessible at MOCKTAIL_URL/mocktail/api/users"),
63
+ response: z.string().describe("JSON string for the response body"),
64
+ statusCode: z.number().optional().describe("HTTP status code (default 200)"),
65
+ delay: z.number().optional().describe("Response delay in ms (0-30000, default 0)"),
66
+ },
67
+ async ({ method, endpoint, response, statusCode, delay }) => {
68
+ try {
69
+ const parsed = JSON.parse(response);
70
+ const result = await mocktailRequest("/core/v1/api", {
71
+ method: "POST",
72
+ body: JSON.stringify({
73
+ Method: method,
74
+ Endpoint: endpoint,
75
+ Response: parsed,
76
+ StatusCode: statusCode ?? 200,
77
+ Delay: delay ?? 0,
78
+ }),
79
+ });
80
+ const accessUrl = `${MOCKTAIL_URL}/mocktail${endpoint}`;
81
+ return {
82
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) + `\n\nAccessible at: ${method} ${accessUrl}` }],
83
+ };
84
+ } catch (err) {
85
+ return {
86
+ isError: true,
87
+ content: [{ type: "text", text: `Error: ${err.message}` }],
88
+ };
89
+ }
90
+ }
91
+ );
92
+
93
+ // update_mock
94
+ server.tool(
95
+ "update_mock",
96
+ "Update an existing mock endpoint by ID. All fields are required since the entire mock is replaced. The endpoint path is relative — e.g. '/api/users' becomes accessible at MOCKTAIL_URL/mocktail/api/users.",
97
+ {
98
+ id: z.number().describe("Mock endpoint ID"),
99
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
100
+ endpoint: z.string().describe("URL path starting with /, e.g. /api/users"),
101
+ response: z.string().describe("JSON string for the response body"),
102
+ statusCode: z.number().optional().describe("HTTP status code (default 200)"),
103
+ delay: z.number().optional().describe("Response delay in ms (0-30000, default 0)"),
104
+ },
105
+ async ({ id, method, endpoint, response, statusCode, delay }) => {
106
+ try {
107
+ const parsed = JSON.parse(response);
108
+ const result = await mocktailRequest(`/core/v1/api/${id}`, {
109
+ method: "PUT",
110
+ body: JSON.stringify({
111
+ Method: method,
112
+ Endpoint: endpoint,
113
+ Response: parsed,
114
+ StatusCode: statusCode ?? 200,
115
+ Delay: delay ?? 0,
116
+ }),
117
+ });
118
+ const accessUrl = `${MOCKTAIL_URL}/mocktail${endpoint}`;
119
+ return {
120
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) + `\n\nAccessible at: ${method} ${accessUrl}` }],
121
+ };
122
+ } catch (err) {
123
+ return {
124
+ isError: true,
125
+ content: [{ type: "text", text: `Error: ${err.message}` }],
126
+ };
127
+ }
128
+ }
129
+ );
130
+
131
+ // delete_mock
132
+ server.tool(
133
+ "delete_mock",
134
+ "Delete a mock endpoint by ID",
135
+ {
136
+ id: z.number().describe("Mock endpoint ID to delete"),
137
+ },
138
+ async ({ id }) => {
139
+ try {
140
+ const result = await mocktailRequest(`/core/v1/api/${id}`, {
141
+ method: "DELETE",
142
+ });
143
+ return {
144
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
145
+ };
146
+ } catch (err) {
147
+ return {
148
+ isError: true,
149
+ content: [{ type: "text", text: `Error: ${err.message}` }],
150
+ };
151
+ }
152
+ }
153
+ );
154
+
155
+ // import_mocks
156
+ server.tool(
157
+ "import_mocks",
158
+ "Bulk import multiple mock endpoints. Existing endpoints (same method+path) are skipped. Response fields should be JSON strings.",
159
+ {
160
+ mocks: z.array(
161
+ z.object({
162
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
163
+ endpoint: z.string().describe("URL path starting with /, e.g. /api/users"),
164
+ response: z.string().describe("JSON string for the response body"),
165
+ statusCode: z.number().optional().describe("HTTP status code (default 200)"),
166
+ delay: z.number().optional().describe("Response delay in ms (default 0)"),
167
+ })
168
+ ).describe("Array of mock endpoints to import"),
169
+ },
170
+ async ({ mocks }) => {
171
+ try {
172
+ const apis = mocks.map((m) => ({
173
+ Method: m.method,
174
+ Endpoint: m.endpoint,
175
+ Response: JSON.parse(m.response),
176
+ StatusCode: m.statusCode ?? 200,
177
+ Delay: m.delay ?? 0,
178
+ }));
179
+ const result = await mocktailRequest("/core/v1/import", {
180
+ method: "POST",
181
+ body: JSON.stringify({ Apis: apis }),
182
+ });
183
+ return {
184
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
185
+ };
186
+ } catch (err) {
187
+ return {
188
+ isError: true,
189
+ content: [{ type: "text", text: `Error: ${err.message}` }],
190
+ };
191
+ }
192
+ }
193
+ );
194
+
195
+ const transport = new StdioServerTransport();
196
+ await server.connect(transport);
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "mocktail-mcp",
3
+ "version": "3.1.4",
4
+ "description": "MCP server for managing Mocktail mock API endpoints",
5
+ "type": "module",
6
+ "bin": {
7
+ "mocktail-mcp": "./index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node index.js"
11
+ },
12
+ "keywords": [
13
+ "mocktail",
14
+ "mcp",
15
+ "mock",
16
+ "api"
17
+ ],
18
+ "license": "MIT",
19
+ "dependencies": {
20
+ "@modelcontextprotocol/sdk": "^1.12.1",
21
+ "zod": "^3.24.2"
22
+ }
23
+ }