@cocaxcode/api-testing-mcp 0.4.2 → 0.5.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.
Files changed (2) hide show
  1. package/README.md +185 -80
  2. package/package.json +10 -2
package/README.md CHANGED
@@ -1,26 +1,26 @@
1
1
  <p align="center">
2
2
  <h1 align="center">@cocaxcode/api-testing-mcp</h1>
3
3
  <p align="center">
4
- A complete API testing toolkit built for AI coding agents.<br/>
4
+ <strong>A complete API testing toolkit built for AI coding agents.</strong><br/>
5
5
  Test, validate, mock, and load-test your APIs — all from natural language.
6
6
  </p>
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://www.npmjs.com/package/@cocaxcode/api-testing-mcp"><img src="https://img.shields.io/npm/v/@cocaxcode/api-testing-mcp.svg?style=flat-square&color=cb3837" alt="npm version" /></a>
11
- <a href="https://github.com/cocaxcode/api-testing-mcp/actions"><img src="https://img.shields.io/github/actions/workflow/status/cocaxcode/api-testing-mcp/ci.yml?style=flat-square&label=CI" alt="CI" /></a>
11
+ <a href="https://www.npmjs.com/package/@cocaxcode/api-testing-mcp"><img src="https://img.shields.io/npm/dm/@cocaxcode/api-testing-mcp.svg?style=flat-square" alt="npm downloads" /></a>
12
12
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License" /></a>
13
- <img src="https://img.shields.io/badge/tests-70%20passing-brightgreen?style=flat-square" alt="Tests" />
14
- <img src="https://img.shields.io/badge/tools-20-blueviolet?style=flat-square" alt="Tools" />
15
13
  <img src="https://img.shields.io/badge/node-%3E%3D20-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node" />
16
14
  </p>
17
15
 
18
16
  <p align="center">
19
- <a href="#installation">Installation</a>
20
- <a href="#just-talk-to-it">Just Talk to It</a>
21
- <a href="#features">Features</a>
22
- <a href="#tool-reference">Tool Reference</a>
23
- <a href="#storage">Storage</a>
17
+ <a href="#installation">Installation</a> &middot;
18
+ <a href="#just-talk-to-it">Just Talk to It</a> &middot;
19
+ <a href="#works-with-any-api">Any API</a> &middot;
20
+ <a href="#features">Features</a> &middot;
21
+ <a href="#tool-reference">Tool Reference</a> &middot;
22
+ <a href="#storage">Storage</a> &middot;
23
+ <a href="#limitations">Limitations</a> &middot;
24
24
  <a href="#contributing">Contributing</a>
25
25
  </p>
26
26
 
@@ -34,6 +34,73 @@ You describe what you need. The AI figures out the rest.
34
34
 
35
35
  No cloud accounts. No subscriptions. Everything runs locally and stores data as plain JSON files you can commit to git.
36
36
 
37
+ **Requires** an MCP-compatible client such as [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Claude Desktop](https://claude.ai/download), or [Cursor](https://cursor.sh). This is not a standalone CLI tool — it extends your AI assistant with API testing capabilities.
38
+
39
+ ---
40
+
41
+ ## Installation
42
+
43
+ ### Claude Code
44
+
45
+ ```bash
46
+ claude mcp add api-testing -- npx -y @cocaxcode/api-testing-mcp
47
+ ```
48
+
49
+ ### Claude Desktop
50
+
51
+ Add to your config file:
52
+
53
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
54
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
55
+
56
+ ```json
57
+ {
58
+ "mcpServers": {
59
+ "api-testing": {
60
+ "command": "npx",
61
+ "args": ["-y", "@cocaxcode/api-testing-mcp"]
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ ### Cursor
68
+
69
+ Add to `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` for global):
70
+
71
+ ```json
72
+ {
73
+ "mcpServers": {
74
+ "api-testing": {
75
+ "command": "npx",
76
+ "args": ["-y", "@cocaxcode/api-testing-mcp"]
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Quick start
83
+
84
+ Once installed, set up an environment so the tool knows where your API lives:
85
+
86
+ ```
87
+ "Create an environment called dev with BASE_URL http://localhost:3000"
88
+ ```
89
+
90
+ From here, relative paths work automatically. `/api/users` becomes `http://localhost:3000/api/users`.
91
+
92
+ If your API has Swagger/OpenAPI, import the spec:
93
+
94
+ ```
95
+ "Import my API spec from http://localhost:3000/api-docs-json"
96
+ ```
97
+
98
+ Now the AI knows every endpoint, parameter, and schema in your API. You're ready to go.
99
+
100
+ To verify the installation is working, try: *"List my environments"* — it should show the one you just created.
101
+
102
+ Available on [npm](https://www.npmjs.com/package/@cocaxcode/api-testing-mcp).
103
+
37
104
  ---
38
105
 
39
106
  ## Just Talk to It
@@ -61,46 +128,57 @@ This tool is designed to be used through natural language. You don't need to mem
61
128
 
62
129
  ---
63
130
 
64
- ## Installation
131
+ ## Works with Any API
65
132
 
66
- ### Claude Code
133
+ This isn't limited to your own backend. You can test **any API** — public, third-party, or internal — and manage them all simultaneously through environments.
134
+
135
+ ### Managing multiple APIs
136
+
137
+ Set up one environment per API and switch between them instantly:
67
138
 
68
- ```bash
69
- claude mcp add api-testing -- npx -y @cocaxcode/api-testing-mcp
70
139
  ```
140
+ "Create an environment called github with BASE_URL https://api.github.com"
141
+ "Create an environment called cloudflare with BASE_URL https://api.cloudflare.com/client/v4"
142
+ "Create an environment called dokploy with BASE_URL https://my-server:3000/api"
143
+ "Create an environment called my-backend with BASE_URL http://localhost:3000"
144
+ ```
145
+
146
+ Add authentication variables to each one:
71
147
 
72
- ### Claude Desktop / Cursor / Any MCP Client
148
+ ```
149
+ "Set GITHUB_TOKEN in the github environment"
150
+ "Set API_KEY in cloudflare"
151
+ "Set TOKEN in dokploy"
152
+ ```
73
153
 
74
- Add to your MCP configuration file:
154
+ Then just switch context and start working:
75
155
 
76
- ```json
77
- {
78
- "mcpServers": {
79
- "api-testing": {
80
- "command": "npx",
81
- "args": ["-y", "@cocaxcode/api-testing-mcp"]
82
- }
83
- }
84
- }
85
156
  ```
157
+ "Switch to github"
158
+ "Get my repos" → GET /user/repos with Bearer token
86
159
 
87
- ### First steps
160
+ "Switch to cloudflare"
161
+ "List all DNS zones" → GET /zones with API key auth
88
162
 
89
- Set up an environment so the tool knows where your API lives:
163
+ "Switch to dokploy"
164
+ "Show me all running projects" → GET /project with token
90
165
 
166
+ "Switch to my-backend"
167
+ "Create a user with random data" → POST /users with mock body from spec
91
168
  ```
92
- "Create an environment called dev with BASE_URL http://localhost:3000"
93
- ```
94
-
95
- From here, relative paths work automatically. `/api/users` becomes `http://localhost:3000/api/users`.
96
169
 
97
- If your API has Swagger/OpenAPI, import the spec:
170
+ ### Real-world example: testing a third-party API
98
171
 
99
172
  ```
100
- "Import my API spec from http://localhost:3000/api-docs-json"
173
+ You: "Set up Cloudflare with my API key"
174
+ You: "List my DNS zones"
175
+ You: "Show me all DNS records for cocaxcode.dev"
176
+ You: "Verify that the A record for api.cocaxcode.dev exists"
177
+ You: "How fast is the zones endpoint under load?"
178
+ You: "Save this request as cf-list-zones with tag cloudflare"
101
179
  ```
102
180
 
103
- Now the AI knows every endpoint, parameter, and schema in your API. You're ready to go.
181
+ Every request, collection, and spec is isolated per environment. Your Cloudflare tests don't mix with your local backend tests.
104
182
 
105
183
  ---
106
184
 
@@ -108,7 +186,14 @@ Now the AI knows every endpoint, parameter, and schema in your API. You're ready
108
186
 
109
187
  ### HTTP Requests
110
188
 
111
- Execute any HTTP method with headers, body, query params, and built-in auth. Relative URLs resolve from the active environment. Variables like `{{TOKEN}}` are replaced from environment values.
189
+ Send any request by describing what you need. The AI resolves relative URLs, injects environment variables, and handles authentication automatically.
190
+
191
+ ```
192
+ "POST to /api/users with name Jane and email jane@company.com using my bearer token"
193
+ ```
194
+
195
+ <details>
196
+ <summary>What the tool executes</summary>
112
197
 
113
198
  ```
114
199
  request({
@@ -118,39 +203,39 @@ request({
118
203
  auth: { type: "bearer", token: "{{TOKEN}}" }
119
204
  })
120
205
  ```
206
+ </details>
121
207
 
122
- **Supports:** GET · POST · PUT · PATCH · DELETE · HEAD · OPTIONS — Headers · Query params · JSON body · Bearer / API Key / Basic auth · Timeout · `{{variable}}` interpolation
208
+ **Supports:** GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS — Headers, query params, JSON body, Bearer / API Key / Basic auth, timeout, `{{variable}}` interpolation.
123
209
 
124
210
  ### Assertions
125
211
 
126
- Run a request and validate the response against a set of rules in one step. Get structured pass/fail results.
212
+ Validate API responses against a set of rules in one step. Get structured pass/fail results.
127
213
 
128
214
  ```
129
- assert({
130
- method: "GET",
131
- url: "/api/health",
132
- assertions: [
133
- { path: "status", operator: "eq", expected: 200 },
134
- { path: "body.status", operator: "eq", expected: "ok" },
135
- { path: "timing.total_ms", operator: "lt", expected: 500 }
136
- ]
137
- })
215
+ "Verify that GET /api/health returns 200, body.status is ok, and responds in under 500ms"
138
216
  ```
139
217
 
140
218
  ```
141
- PASS — 3/3 assertions passed
219
+ PASS — 3/3 assertions passed
142
220
  GET /api/health → 200 OK (42ms)
143
221
 
144
- status === 200
145
- body.status === "ok"
146
- timing.total_ms < 500
222
+ status === 200
223
+ body.status === "ok"
224
+ timing.total_ms < 500
147
225
  ```
148
226
 
149
- **Operators:** `eq` · `neq` · `gt` · `gte` · `lt` · `lte` · `contains` · `not_contains` · `exists` · `type`
227
+ **Operators:** `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `exists`, `type`
150
228
 
151
229
  ### Request Flows
152
230
 
153
- Chain multiple requests together. Extract values from one response and inject them into the next step using `{{variables}}`. Perfect for auth flows, CRUD sequences, and multi-step testing.
231
+ Chain multiple requests together. Extract values from one response and inject them into the next step. Perfect for auth flows, CRUD sequences, and multi-step testing.
232
+
233
+ ```
234
+ "Login as admin@test.com, extract the access token, then use it to fetch all users"
235
+ ```
236
+
237
+ <details>
238
+ <summary>What the tool executes</summary>
154
239
 
155
240
  ```
156
241
  flow_run({
@@ -159,7 +244,7 @@ flow_run({
159
244
  name: "login",
160
245
  method: "POST",
161
246
  url: "/auth/login",
162
- body: { email: "admin@test.com", password: "123456" },
247
+ body: { email: "admin@test.com", password: "SecurePass#99" },
163
248
  extract: { "TOKEN": "body.access_token" }
164
249
  },
165
250
  {
@@ -171,23 +256,24 @@ flow_run({
171
256
  ]
172
257
  })
173
258
  ```
259
+ </details>
174
260
 
175
261
  ### OpenAPI Import
176
262
 
177
263
  Import your Swagger/OpenAPI spec from a URL or local file. Once imported, the AI understands every endpoint, parameter, and schema — no guessing, no memorizing.
178
264
 
179
265
  ```
180
- api_import({ name: "my-backend", source: "http://localhost:3000/api-docs-json" })
181
- api_endpoints({ name: "my-backend", tag: "users" })
182
- api_endpoint_detail({ name: "my-backend", method: "POST", path: "/users" })
266
+ "Import my API spec from http://localhost:3000/api-docs-json"
267
+ "Show me all user endpoints"
268
+ "What parameters does POST /users expect?"
183
269
  ```
184
270
 
185
271
  ### Mock Data Generation
186
272
 
187
- Generate realistic fake data from your OpenAPI spec. Respects types, formats (`email`, `uuid`, `date-time`), enums, and required fields. Use `count` for arrays.
273
+ Generate realistic fake data from your OpenAPI spec. Respects types, formats (`email`, `uuid`, `date-time`), enums, and required fields.
188
274
 
189
275
  ```
190
- mock({ name: "my-backend", method: "POST", path: "/users", target: "request" })
276
+ "Generate mock data for creating a user"
191
277
  ```
192
278
 
193
279
  ```json
@@ -204,17 +290,17 @@ mock({ name: "my-backend", method: "POST", path: "/users", target: "request" })
204
290
  Fire N concurrent requests and get performance metrics: min, avg, percentiles (p50/p95/p99), max, and requests per second.
205
291
 
206
292
  ```
207
- load_test({ method: "GET", url: "/api/health", concurrent: 50 })
293
+ "How fast is the health endpoint with 50 concurrent requests?"
208
294
  ```
209
295
 
210
296
  ```
211
- 📊 LOAD TEST — GET /api/health
297
+ LOAD TEST — GET /api/health
212
298
 
213
299
  Requests: 50 concurrent
214
300
  Successful: 50 | Failed: 0
215
301
  Requests/sec: 23.31
216
302
 
217
- ⏱️ Response times:
303
+ Response times:
218
304
  Min: 45ms | Avg: 187ms
219
305
  p50: 156ms | p95: 412ms
220
306
  p99: 523ms | Max: 567ms
@@ -222,13 +308,10 @@ Requests/sec: 23.31
222
308
 
223
309
  ### Response Diffing
224
310
 
225
- Execute two requests and compare their responses field by field. Detect regressions or compare environments (dev vs prod).
311
+ Execute two requests and compare their responses field by field. Detect regressions or compare environments.
226
312
 
227
313
  ```
228
- diff_responses({
229
- request_a: { label: "dev", method: "GET", url: "http://dev.api.com/users" },
230
- request_b: { label: "prod", method: "GET", url: "http://prod.api.com/users" }
231
- })
314
+ "Compare the users endpoint between dev and prod"
232
315
  ```
233
316
 
234
317
  ### Bulk Testing
@@ -236,21 +319,25 @@ diff_responses({
236
319
  Run every saved request in your collection (or filter by tag) and get a pass/fail summary.
237
320
 
238
321
  ```
239
- bulk_test({ tag: "smoke" })
322
+ "Run all my saved smoke tests"
240
323
  ```
241
324
 
242
325
  ```
243
- BULK TEST — 8/8 passed | 1.2s total
326
+ BULK TEST — 8/8 passed | 1.2s total
244
327
 
245
- health — GET /health → 200 (45ms)
246
- list-users — GET /users → 200 (123ms)
247
- create-post — POST /blog → 201 (89ms)
248
- login — POST /auth/login → 200 (156ms)
328
+ health — GET /health → 200 (45ms)
329
+ list-users — GET /users → 200 (123ms)
330
+ create-post — POST /blog → 201 (89ms)
331
+ login — POST /auth/login → 200 (156ms)
249
332
  ```
250
333
 
251
334
  ### cURL Export
252
335
 
253
- Convert any saved request into a cURL command with resolved variables.
336
+ Convert any saved request into a ready-to-paste cURL command with resolved variables.
337
+
338
+ ```
339
+ "Export the create-user request as curl"
340
+ ```
254
341
 
255
342
  ```bash
256
343
  curl -X POST \
@@ -260,7 +347,7 @@ curl -X POST \
260
347
  -d '{"name":"Jane","email":"jane@company.com"}'
261
348
  ```
262
349
 
263
- ### Collections & Environments
350
+ ### Collections and Environments
264
351
 
265
352
  Save requests for reuse (with tags), manage variables across environments (dev/staging/prod), and switch contexts instantly.
266
353
 
@@ -275,11 +362,13 @@ Save requests for reuse (with tags), manage variables across environments (dev/s
275
362
  | **Requests** | `request` | 1 |
276
363
  | **Testing** | `assert` | 1 |
277
364
  | **Flows** | `flow_run` | 1 |
278
- | **Collections** | `collection_save` · `collection_list` · `collection_get` · `collection_delete` | 4 |
279
- | **Environments** | `env_create` · `env_list` · `env_set` · `env_get` · `env_switch` | 5 |
280
- | **API Specs** | `api_import` · `api_endpoints` · `api_endpoint_detail` | 3 |
365
+ | **Collections** | `collection_save` `collection_list` `collection_get` `collection_delete` | 4 |
366
+ | **Environments** | `env_create` `env_list` `env_set` `env_get` `env_switch` | 5 |
367
+ | **API Specs** | `api_import` `api_endpoints` `api_endpoint_detail` | 3 |
281
368
  | **Mock** | `mock` | 1 |
282
- | **Utilities** | `load_test` · `export_curl` · `diff_responses` · `bulk_test` | 4 |
369
+ | **Utilities** | `load_test` `export_curl` `diff_responses` `bulk_test` | 4 |
370
+
371
+ You don't need to call these tools directly. Just describe what you want and the AI picks the right one.
283
372
 
284
373
  ---
285
374
 
@@ -295,7 +384,7 @@ All data lives in `.api-testing/` as plain JSON — no database, no cloud sync:
295
384
  └── specs/ # Imported OpenAPI specs
296
385
  ```
297
386
 
298
- Override the default directory:
387
+ Override the default directory in your MCP config:
299
388
 
300
389
  ```json
301
390
  {
@@ -303,7 +392,17 @@ Override the default directory:
303
392
  }
304
393
  ```
305
394
 
306
- Commit these files to git to share across your team.
395
+ Commit these files to git to share API configurations across your team.
396
+
397
+ ---
398
+
399
+ ## Limitations
400
+
401
+ - **Auth**: Supports Bearer token, API Key, and Basic auth. OAuth 2.0 flows (authorization code, PKCE) are not supported — use a pre-obtained token instead.
402
+ - **Protocols**: HTTP/HTTPS only. No WebSocket, gRPC, or GraphQL-specific support (though GraphQL over HTTP works fine).
403
+ - **Load testing**: Recommended maximum of 100 concurrent requests. This is a testing tool, not a benchmarking framework.
404
+ - **Specs**: OpenAPI 3.x only. OpenAPI 2.0 (Swagger) is partially supported. AsyncAPI is not supported.
405
+ - **Storage**: Local JSON files only. No built-in cloud sync or team collaboration server.
307
406
 
308
407
  ---
309
408
 
@@ -324,7 +423,13 @@ npm run typecheck # Strict TypeScript
324
423
  npx @modelcontextprotocol/inspector node dist/index.js
325
424
  ```
326
425
 
327
- **Stack:** TypeScript · MCP SDK 1.27 · Zod · Vitest · tsup
426
+ **Stack:** TypeScript &middot; MCP SDK 1.27 &middot; Zod &middot; Vitest &middot; tsup
427
+
428
+ ### How to contribute
429
+
430
+ - **Bug reports**: [Open an issue](https://github.com/cocaxcode/api-testing-mcp/issues) with steps to reproduce, expected vs actual behavior, and your Node.js version.
431
+ - **Feature requests**: Open an issue describing the use case. Include examples of how you'd use it in natural language.
432
+ - **Pull requests**: Fork, create a branch, make your changes, ensure `npm test` and `npm run typecheck` pass, then open a PR.
328
433
 
329
434
  ---
330
435
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocaxcode/api-testing-mcp",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "MCP server for API testing. 20 tools: HTTP requests, assertions, flows, OpenAPI import, mock data, load testing. Zero cloud dependencies.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,12 +27,20 @@
27
27
  },
28
28
  "keywords": [
29
29
  "mcp",
30
+ "mcp-server",
30
31
  "api-testing",
31
32
  "http",
32
33
  "rest",
33
34
  "model-context-protocol",
34
35
  "claude",
35
- "ai-tools"
36
+ "claude-desktop",
37
+ "cursor",
38
+ "ai-tools",
39
+ "openapi",
40
+ "swagger",
41
+ "load-testing",
42
+ "mock-data",
43
+ "postman-alternative"
36
44
  ],
37
45
  "author": "cocaxcode",
38
46
  "license": "MIT",