mcp-stress 0.1.2
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/LICENSE +21 -0
- package/README.md +127 -0
- package/mcp-stress.js +46 -0
- package/package.json +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Samuel El-Borai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# mcp-stress
|
|
2
|
+
|
|
3
|
+
Stress testing tool for MCP (Model Context Protocol) servers.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# npm
|
|
9
|
+
npx mcp-stress <command>
|
|
10
|
+
npm install -g mcp-stress
|
|
11
|
+
|
|
12
|
+
# JSR / Deno
|
|
13
|
+
deno install -g -A --name mcp-stress jsr:@dgellow/mcp-stress/cli
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
### run
|
|
19
|
+
|
|
20
|
+
Execute a stress test against an MCP server.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Stdio transport (spawns the server)
|
|
24
|
+
mcp-stress run -d 30 -c 10 --tool echo -- node my-server.js
|
|
25
|
+
|
|
26
|
+
# HTTP transport
|
|
27
|
+
mcp-stress run -d 30 -c 10 --url http://localhost:3000/mcp
|
|
28
|
+
|
|
29
|
+
# Find max throughput (auto-scales concurrency)
|
|
30
|
+
mcp-stress run -p find-ceiling -d 120 -c 50 -- node my-server.js
|
|
31
|
+
|
|
32
|
+
# CI mode: JSON output + assertions
|
|
33
|
+
mcp-stress run --json --assert "p99 < 500ms" --assert "error_rate < 1%" -- node my-server.js
|
|
34
|
+
|
|
35
|
+
# Live browser dashboard
|
|
36
|
+
mcp-stress run --live -d 60 -c 10 -o results.ndjson -- node my-server.js
|
|
37
|
+
|
|
38
|
+
# Send exactly N requests (useful for debugging)
|
|
39
|
+
mcp-stress run -n 5 -v -- node my-server.js
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Options:**
|
|
43
|
+
|
|
44
|
+
| Flag | Description |
|
|
45
|
+
| ------------------- | --------------------------------------------------------------------------------- |
|
|
46
|
+
| `-p, --profile` | Workload profile (default: `tool-flood`) |
|
|
47
|
+
| `-d, --duration` | Test duration in seconds (default: 10) |
|
|
48
|
+
| `-n, --requests` | Stop after N requests (overrides duration) |
|
|
49
|
+
| `-c, --concurrency` | Peak concurrent workers (default: 1) |
|
|
50
|
+
| `-t, --timeout` | Request timeout in ms (default: 30000) |
|
|
51
|
+
| `--tool` | Target a specific tool by name |
|
|
52
|
+
| `--shape` | Load shape: `constant`, `linear-ramp`, `exponential`, `step`, `spike`, `sawtooth` |
|
|
53
|
+
| `-o, --output` | NDJSON output file path |
|
|
54
|
+
| `--live` | Open real-time browser dashboard |
|
|
55
|
+
| `--json` | Output JSON summary to stdout |
|
|
56
|
+
| `--assert` | Threshold assertion, repeatable (e.g. `"p99 < 500ms"`) |
|
|
57
|
+
| `--seed` | PRNG seed for reproducibility |
|
|
58
|
+
| `--sse` | Use legacy HTTP+SSE transport (default: streamable-http) |
|
|
59
|
+
| `-v, --verbose` | Log every request/response |
|
|
60
|
+
|
|
61
|
+
### chart
|
|
62
|
+
|
|
63
|
+
Generate an interactive HTML report from a previous run.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mcp-stress chart results.ndjson --open
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### compare
|
|
70
|
+
|
|
71
|
+
Compare two test runs and detect regressions.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
mcp-stress compare baseline.ndjson current.ndjson --open
|
|
75
|
+
mcp-stress compare baseline.ndjson current.ndjson --json --assert "p99_delta < 10%"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### diagnose
|
|
79
|
+
|
|
80
|
+
Probe server connectivity and protocol compliance.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
mcp-stress diagnose -- node my-server.js
|
|
84
|
+
mcp-stress diagnose --url http://localhost:3000/mcp
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### discover
|
|
88
|
+
|
|
89
|
+
Enumerate server capabilities (tools, resources, prompts).
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
mcp-stress discover -- node my-server.js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### profiles / shapes
|
|
96
|
+
|
|
97
|
+
List available workload profiles and load shapes.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
mcp-stress profiles
|
|
101
|
+
mcp-stress shapes
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Transports
|
|
105
|
+
|
|
106
|
+
- **stdio** (default): Spawns the server as a subprocess. Use
|
|
107
|
+
`-- command [args]`.
|
|
108
|
+
- **Streamable HTTP**: Connect to a running server. Use `--url`.
|
|
109
|
+
- **SSE** (legacy): Use `--url` with `--sse`.
|
|
110
|
+
|
|
111
|
+
## Output
|
|
112
|
+
|
|
113
|
+
All test data is written as NDJSON (newline-delimited JSON) with three event
|
|
114
|
+
types:
|
|
115
|
+
|
|
116
|
+
- `meta` — run parameters and configuration
|
|
117
|
+
- `request` — individual request results (method, latency, ok/error)
|
|
118
|
+
- `summary` — aggregate statistics
|
|
119
|
+
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
./scripts/lint # Format check + type check
|
|
124
|
+
./scripts/test # Run tests
|
|
125
|
+
./scripts/build # Compile binary + npm packages
|
|
126
|
+
./scripts/start # Run the CLI
|
|
127
|
+
```
|
package/mcp-stress.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawn } = require("child_process");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const PLATFORMS = {
|
|
8
|
+
"linux-x64": "linux-x64",
|
|
9
|
+
"linux-arm64": "linux-arm64",
|
|
10
|
+
"darwin-x64": "darwin-x64",
|
|
11
|
+
"darwin-arm64": "darwin-arm64",
|
|
12
|
+
"win32-x64": "win32-x64",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const key = `${process.platform}-${process.arch}`;
|
|
16
|
+
const pkgSuffix = PLATFORMS[key];
|
|
17
|
+
|
|
18
|
+
if (!pkgSuffix) {
|
|
19
|
+
console.error(`Unsupported platform: ${key}`);
|
|
20
|
+
console.error("Use Deno instead: deno install -g -A --name mcp-stress jsr:@dgellow/mcp-stress/cli");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const binName = process.platform === "win32" ? "mcp-stress.exe" : "mcp-stress";
|
|
25
|
+
let binPath;
|
|
26
|
+
|
|
27
|
+
for (const loc of [
|
|
28
|
+
path.join(__dirname, "..", pkgSuffix, "bin", binName),
|
|
29
|
+
path.join(__dirname, "..", "..", pkgSuffix, "bin", binName),
|
|
30
|
+
]) {
|
|
31
|
+
if (fs.existsSync(loc)) { binPath = loc; break; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!binPath) {
|
|
35
|
+
try {
|
|
36
|
+
binPath = path.join(path.dirname(require.resolve(`@mcp-stress/${pkgSuffix}/package.json`)), "bin", binName);
|
|
37
|
+
} catch {
|
|
38
|
+
console.error(`Binary not found for ${key}. Try: npm install mcp-stress`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const child = spawn(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
44
|
+
child.on("error", (err) => { console.error(`Failed to start mcp-stress: ${err.message}`); process.exit(1); });
|
|
45
|
+
for (const sig of Object.keys(os.constants.signals)) { try { process.on(sig, () => child.kill(sig)); } catch {} }
|
|
46
|
+
child.on("exit", (code, signal) => { if (signal) process.kill(process.pid, signal); else process.exit(code ?? 0); });
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-stress",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Stress testing tool for MCP servers",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/dgellow/mcp-stress.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/dgellow/mcp-stress/issues"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/dgellow/mcp-stress#readme",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"mcp",
|
|
16
|
+
"stress-test",
|
|
17
|
+
"load-test",
|
|
18
|
+
"benchmark",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"cli"
|
|
21
|
+
],
|
|
22
|
+
"bin": {
|
|
23
|
+
"mcp-stress": "./mcp-stress.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"mcp-stress.js"
|
|
27
|
+
],
|
|
28
|
+
"optionalDependencies": {
|
|
29
|
+
"@mcp-stress/linux-x64": "0.1.2",
|
|
30
|
+
"@mcp-stress/linux-arm64": "0.1.2",
|
|
31
|
+
"@mcp-stress/darwin-x64": "0.1.2",
|
|
32
|
+
"@mcp-stress/darwin-arm64": "0.1.2",
|
|
33
|
+
"@mcp-stress/win32-x64": "0.1.2"
|
|
34
|
+
}
|
|
35
|
+
}
|