@yumdee/mcp-studio-bench 0.1.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/LICENSE +23 -0
- package/README.md +22 -0
- package/dist/__tests__/bench.test.d.ts +2 -0
- package/dist/__tests__/bench.test.d.ts.map +1 -0
- package/dist/__tests__/bench.test.js +92 -0
- package/dist/__tests__/bench.test.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +188 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2024 yumdee-Mcp-studio Contributors
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @yumdee/mcp-studio-bench
|
|
2
|
+
|
|
3
|
+
Compliance & reliability scoring for MCP servers.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Spec compliance checks (handshake format, error format, type consistency)
|
|
8
|
+
- Reliability metrics (success rate, latency percentiles)
|
|
9
|
+
- Replay-based scoring (no live network calls)
|
|
10
|
+
- CI-gatable pass/fail gates (`bench check --min-score 80`)
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
mcp-studio-bench <server-name>
|
|
16
|
+
mcp-studio-bench <session-id> --replay # Replay a recorded session
|
|
17
|
+
mcp-studio-bench check --min-score 80 # CI gate
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Development
|
|
21
|
+
|
|
22
|
+
See [../../CONTRIBUTING.md](../../CONTRIBUTING.md)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bench.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { createBenchmark } from "../index.js";
|
|
3
|
+
describe("Benchmark & Compliance Scoring", () => {
|
|
4
|
+
const sampleSession = {
|
|
5
|
+
id: "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
|
|
6
|
+
serverInfo: {
|
|
7
|
+
name: "math-server",
|
|
8
|
+
version: "0.1.0",
|
|
9
|
+
transport: "stdio",
|
|
10
|
+
},
|
|
11
|
+
clientInfo: {
|
|
12
|
+
name: "yumdee-mcp-studio",
|
|
13
|
+
version: "0.1.0",
|
|
14
|
+
},
|
|
15
|
+
startedAt: new Date().toISOString(),
|
|
16
|
+
events: [
|
|
17
|
+
{
|
|
18
|
+
type: "request",
|
|
19
|
+
timestamp: new Date().toISOString(),
|
|
20
|
+
id: 1,
|
|
21
|
+
method: "initialize",
|
|
22
|
+
sentAtMs: 0,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: "response",
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
id: 1,
|
|
28
|
+
result: { capabilities: {} },
|
|
29
|
+
receivedAtMs: 15,
|
|
30
|
+
latencyMs: 15,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "request",
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
id: 2,
|
|
36
|
+
method: "tools/call",
|
|
37
|
+
sentAtMs: 20,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: "response",
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
id: 2,
|
|
43
|
+
result: { content: [{ type: "text", text: "result" }] },
|
|
44
|
+
receivedAtMs: 45,
|
|
45
|
+
latencyMs: 25,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
it("should score a compliant session highly", () => {
|
|
50
|
+
const bench = createBenchmark({ minScore: 80 });
|
|
51
|
+
const score = bench.scoreSession(sampleSession);
|
|
52
|
+
expect(score.overall).toBeGreaterThanOrEqual(80);
|
|
53
|
+
expect(score.breakdown.specCompliance).toBeGreaterThanOrEqual(80);
|
|
54
|
+
expect(score.breakdown.successRate).toBe(1.0);
|
|
55
|
+
expect(score.breakdown.errorCount).toBe(0);
|
|
56
|
+
expect(score.breakdown.latencyPercentile50).toBeGreaterThan(0);
|
|
57
|
+
const report = bench.generateReport(score);
|
|
58
|
+
expect(report).toContain("MCP Studio Compliance Report");
|
|
59
|
+
expect(report).toContain("PASSED");
|
|
60
|
+
});
|
|
61
|
+
it("should detect regressions when errors or latencies increase", () => {
|
|
62
|
+
const degradedSession = {
|
|
63
|
+
...sampleSession,
|
|
64
|
+
id: "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f",
|
|
65
|
+
events: [
|
|
66
|
+
...sampleSession.events,
|
|
67
|
+
{
|
|
68
|
+
type: "request",
|
|
69
|
+
timestamp: new Date().toISOString(),
|
|
70
|
+
id: 3,
|
|
71
|
+
method: "tools/call",
|
|
72
|
+
sentAtMs: 50,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "response",
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
id: 3,
|
|
78
|
+
error: { code: -32603, message: "Internal failure" },
|
|
79
|
+
receivedAtMs: 350,
|
|
80
|
+
latencyMs: 300,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
const bench = createBenchmark();
|
|
85
|
+
const regressions = bench.detectRegressions(sampleSession, degradedSession);
|
|
86
|
+
expect(regressions.length).toBeGreaterThan(0);
|
|
87
|
+
const errorRegression = regressions.find((r) => r.field === "errorCount");
|
|
88
|
+
expect(errorRegression).toBeDefined();
|
|
89
|
+
expect(errorRegression?.severity).toBe("error");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=bench.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.test.js","sourceRoot":"","sources":["../../src/__tests__/bench.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Studio Bench CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* mcp-studio-bench <path-to-session.json> [--min-score 80]
|
|
7
|
+
*/
|
|
8
|
+
import { promises as fs } from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
import { createBenchmark } from "./index.js";
|
|
11
|
+
import { parseSession } from "@yumdee/mcp-studio-core";
|
|
12
|
+
async function main() {
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const sessionPath = args[0];
|
|
15
|
+
if (!sessionPath || sessionPath === "--help" || sessionPath === "-h") {
|
|
16
|
+
console.log("MCP Studio Bench - Compliance Scoring & CI Gating");
|
|
17
|
+
console.log("\nUsage:");
|
|
18
|
+
console.log(" mcp-studio-bench <path-to-session.json> [--min-score 80]\n");
|
|
19
|
+
process.exit(sessionPath ? 0 : 1);
|
|
20
|
+
}
|
|
21
|
+
let minScore = 80;
|
|
22
|
+
const minScoreIdx = args.indexOf("--min-score");
|
|
23
|
+
if (minScoreIdx !== -1 && args[minScoreIdx + 1]) {
|
|
24
|
+
minScore = parseInt(args[minScoreIdx + 1], 10) || 80;
|
|
25
|
+
}
|
|
26
|
+
const resolved = path.resolve(sessionPath);
|
|
27
|
+
const content = await fs.readFile(resolved, "utf8");
|
|
28
|
+
const session = parseSession(JSON.parse(content));
|
|
29
|
+
const bench = createBenchmark({ minScore });
|
|
30
|
+
const score = bench.scoreSession(session);
|
|
31
|
+
console.log(bench.generateReport(score));
|
|
32
|
+
if (score.overall < minScore) {
|
|
33
|
+
console.error(`\n❌ CI Check Failed: Score ${score.overall} is below threshold ${minScore}.`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`\n✅ CI Check Passed: Score ${score.overall} meets or exceeds threshold ${minScore}.`);
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
main().catch((err) => {
|
|
42
|
+
console.error("Bench execution failed:", err);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5B,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;QAChD,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAElD,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzC,IAAI,KAAK,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,CAAC,OAAO,uBAAuB,QAAQ,GAAG,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,CAAC,OAAO,+BAA+B,QAAQ,GAAG,CAAC,CAAC;QACnG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-bench
|
|
3
|
+
*
|
|
4
|
+
* Compliance scoring and reliability testing for MCP servers.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Spec compliance validation (handshake, JSON-RPC 2.0 error format, etc.)
|
|
8
|
+
* - Latency percentile analysis (P50, P95, min, max)
|
|
9
|
+
* - Tool success rate scoring
|
|
10
|
+
* - Regression detection via replay
|
|
11
|
+
* - CI/CD integration (fail if score < threshold)
|
|
12
|
+
*/
|
|
13
|
+
import { McpSession } from "@yumdee/mcp-studio-core";
|
|
14
|
+
/**
|
|
15
|
+
* Compliance score breakdown by metric
|
|
16
|
+
*/
|
|
17
|
+
export interface ComplianceScore {
|
|
18
|
+
overall: number;
|
|
19
|
+
breakdown: {
|
|
20
|
+
specCompliance: number;
|
|
21
|
+
latencyPercentile50: number;
|
|
22
|
+
latencyPercentile95: number;
|
|
23
|
+
successRate: number;
|
|
24
|
+
errorCount: number;
|
|
25
|
+
};
|
|
26
|
+
timestamp: string;
|
|
27
|
+
sessionId: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Benchmark configuration
|
|
31
|
+
*/
|
|
32
|
+
export interface BenchConfig {
|
|
33
|
+
minScore?: number;
|
|
34
|
+
iterations?: number;
|
|
35
|
+
timeout?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface RegressionFinding {
|
|
38
|
+
field: string;
|
|
39
|
+
change: number;
|
|
40
|
+
severity: "info" | "warning" | "error";
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Compliance benchmark runner
|
|
45
|
+
*/
|
|
46
|
+
export declare class Benchmark {
|
|
47
|
+
private config;
|
|
48
|
+
constructor(config?: BenchConfig);
|
|
49
|
+
/**
|
|
50
|
+
* Score a recorded session (deterministic, no network calls)
|
|
51
|
+
*/
|
|
52
|
+
scoreSession(session: McpSession): ComplianceScore;
|
|
53
|
+
/**
|
|
54
|
+
* Detect regressions between two sessions (baseline vs current)
|
|
55
|
+
*/
|
|
56
|
+
detectRegressions(baseline: McpSession, current: McpSession): RegressionFinding[];
|
|
57
|
+
/**
|
|
58
|
+
* Generate a human-readable report
|
|
59
|
+
*/
|
|
60
|
+
generateReport(score: ComplianceScore): string;
|
|
61
|
+
}
|
|
62
|
+
export declare function createBenchmark(config?: BenchConfig): Benchmark;
|
|
63
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAoB,MAAM,yBAAyB,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE;QACT,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,GAAE,WAAgB;IAQpC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,eAAe;IA0FlD;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,UAAU,GAClB,iBAAiB,EAAE;IA8DtB;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM;CAsB/C;AAED,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAE/D"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-bench
|
|
3
|
+
*
|
|
4
|
+
* Compliance scoring and reliability testing for MCP servers.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Spec compliance validation (handshake, JSON-RPC 2.0 error format, etc.)
|
|
8
|
+
* - Latency percentile analysis (P50, P95, min, max)
|
|
9
|
+
* - Tool success rate scoring
|
|
10
|
+
* - Regression detection via replay
|
|
11
|
+
* - CI/CD integration (fail if score < threshold)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Compliance benchmark runner
|
|
15
|
+
*/
|
|
16
|
+
export class Benchmark {
|
|
17
|
+
constructor(config = {}) {
|
|
18
|
+
this.config = {
|
|
19
|
+
minScore: config.minScore || 80,
|
|
20
|
+
iterations: config.iterations || 5,
|
|
21
|
+
timeout: config.timeout || 5000,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Score a recorded session (deterministic, no network calls)
|
|
26
|
+
*/
|
|
27
|
+
scoreSession(session) {
|
|
28
|
+
const events = session.events || [];
|
|
29
|
+
const requestEvents = events.filter((e) => e.type === "request");
|
|
30
|
+
const responseEvents = events.filter((e) => e.type === "response");
|
|
31
|
+
const errorEvents = events.filter((e) => e.type === "error");
|
|
32
|
+
// 1. Spec Compliance Evaluation (0 - 100)
|
|
33
|
+
let specCompliance = 0;
|
|
34
|
+
// A. Handshake Check: First request must be "initialize"
|
|
35
|
+
const hasInitialize = requestEvents.length > 0 && requestEvents[0].method === "initialize";
|
|
36
|
+
if (hasInitialize) {
|
|
37
|
+
specCompliance += 30;
|
|
38
|
+
}
|
|
39
|
+
// B. Response ID Matching: Every response matches a known request
|
|
40
|
+
const requestIds = new Set(requestEvents.map((r) => r.id));
|
|
41
|
+
let matchingIds = 0;
|
|
42
|
+
for (const res of responseEvents) {
|
|
43
|
+
if (requestIds.has(res.id)) {
|
|
44
|
+
matchingIds++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const matchingRatio = responseEvents.length > 0 ? matchingIds / responseEvents.length : 1;
|
|
48
|
+
specCompliance += Math.round(matchingRatio * 30);
|
|
49
|
+
// C. Server Info Check
|
|
50
|
+
if (session.serverInfo && session.serverInfo.name && session.serverInfo.version) {
|
|
51
|
+
specCompliance += 20;
|
|
52
|
+
}
|
|
53
|
+
// D. Error Format Conformance (Standard JSON-RPC 2.0 error codes)
|
|
54
|
+
const errResponses = responseEvents.filter((r) => r.error);
|
|
55
|
+
let validErrorCodes = 0;
|
|
56
|
+
for (const r of errResponses) {
|
|
57
|
+
if (typeof r.error?.code === "number" && typeof r.error?.message === "string") {
|
|
58
|
+
validErrorCodes++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const errFormatRatio = errResponses.length > 0 ? validErrorCodes / errResponses.length : 1;
|
|
62
|
+
specCompliance += Math.round(errFormatRatio * 20);
|
|
63
|
+
specCompliance = Math.min(100, Math.max(0, specCompliance));
|
|
64
|
+
// 2. Latency Percentiles (P50, P95)
|
|
65
|
+
const latencies = responseEvents
|
|
66
|
+
.map((r) => r.latencyMs)
|
|
67
|
+
.filter((l) => typeof l === "number" && l >= 0)
|
|
68
|
+
.sort((a, b) => a - b);
|
|
69
|
+
let p50 = 0;
|
|
70
|
+
let p95 = 0;
|
|
71
|
+
if (latencies.length > 0) {
|
|
72
|
+
p50 = latencies[Math.floor(latencies.length * 0.5)];
|
|
73
|
+
p95 = latencies[Math.min(latencies.length - 1, Math.floor(latencies.length * 0.95))];
|
|
74
|
+
}
|
|
75
|
+
// Latency Score (0 - 100): Fast < 100ms is 100, > 1000ms scales down
|
|
76
|
+
let latencyScore = 100;
|
|
77
|
+
if (p50 > 100) {
|
|
78
|
+
latencyScore = Math.max(10, Math.round(100 - (p50 - 100) * 0.1));
|
|
79
|
+
}
|
|
80
|
+
// 3. Success Rate (0.0 - 1.0)
|
|
81
|
+
const totalCalls = responseEvents.length;
|
|
82
|
+
const errorCount = errorEvents.length + errResponses.length;
|
|
83
|
+
const successfulCalls = responseEvents.filter((r) => !r.error).length;
|
|
84
|
+
const successRate = totalCalls > 0 ? successfulCalls / totalCalls : 1.0;
|
|
85
|
+
// 4. Overall Weighted Score (0 - 100)
|
|
86
|
+
const overall = Math.round(specCompliance * 0.4 +
|
|
87
|
+
successRate * 100 * 0.35 +
|
|
88
|
+
latencyScore * 0.25);
|
|
89
|
+
return {
|
|
90
|
+
overall: Math.min(100, Math.max(0, overall)),
|
|
91
|
+
breakdown: {
|
|
92
|
+
specCompliance,
|
|
93
|
+
latencyPercentile50: p50,
|
|
94
|
+
latencyPercentile95: p95,
|
|
95
|
+
successRate: Number(successRate.toFixed(3)),
|
|
96
|
+
errorCount,
|
|
97
|
+
},
|
|
98
|
+
timestamp: new Date().toISOString(),
|
|
99
|
+
sessionId: session.id,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Detect regressions between two sessions (baseline vs current)
|
|
104
|
+
*/
|
|
105
|
+
detectRegressions(baseline, current) {
|
|
106
|
+
const findings = [];
|
|
107
|
+
const baselineScore = this.scoreSession(baseline);
|
|
108
|
+
const currentScore = this.scoreSession(current);
|
|
109
|
+
// Score degradation
|
|
110
|
+
const overallDiff = currentScore.overall - baselineScore.overall;
|
|
111
|
+
if (overallDiff < -10) {
|
|
112
|
+
findings.push({
|
|
113
|
+
field: "overallScore",
|
|
114
|
+
change: overallDiff,
|
|
115
|
+
severity: "error",
|
|
116
|
+
message: `Overall compliance score dropped by ${Math.abs(overallDiff)} points (${baselineScore.overall} -> ${currentScore.overall})`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else if (overallDiff < 0) {
|
|
120
|
+
findings.push({
|
|
121
|
+
field: "overallScore",
|
|
122
|
+
change: overallDiff,
|
|
123
|
+
severity: "warning",
|
|
124
|
+
message: `Overall compliance score decreased slightly by ${Math.abs(overallDiff)} points`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Latency regression
|
|
128
|
+
const p95Diff = currentScore.breakdown.latencyPercentile95 - baselineScore.breakdown.latencyPercentile95;
|
|
129
|
+
if (baselineScore.breakdown.latencyPercentile95 > 0 && p95Diff > 50) {
|
|
130
|
+
const pctIncrease = Math.round((p95Diff / baselineScore.breakdown.latencyPercentile95) * 100);
|
|
131
|
+
findings.push({
|
|
132
|
+
field: "latencyP95",
|
|
133
|
+
change: p95Diff,
|
|
134
|
+
severity: pctIncrease > 50 ? "error" : "warning",
|
|
135
|
+
message: `P95 latency increased by ${p95Diff}ms (+${pctIncrease}%)`,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// New errors
|
|
139
|
+
const errorDiff = currentScore.breakdown.errorCount - baselineScore.breakdown.errorCount;
|
|
140
|
+
if (errorDiff > 0) {
|
|
141
|
+
findings.push({
|
|
142
|
+
field: "errorCount",
|
|
143
|
+
change: errorDiff,
|
|
144
|
+
severity: "error",
|
|
145
|
+
message: `Current session introduced ${errorDiff} new error(s)`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Success rate drop
|
|
149
|
+
const successDiff = Number((currentScore.breakdown.successRate - baselineScore.breakdown.successRate).toFixed(3));
|
|
150
|
+
if (successDiff < 0) {
|
|
151
|
+
findings.push({
|
|
152
|
+
field: "successRate",
|
|
153
|
+
change: successDiff,
|
|
154
|
+
severity: "error",
|
|
155
|
+
message: `Success rate dropped from ${(baselineScore.breakdown.successRate * 100).toFixed(1)}% to ${(currentScore.breakdown.successRate * 100).toFixed(1)}%`,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return findings;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Generate a human-readable report
|
|
162
|
+
*/
|
|
163
|
+
generateReport(score) {
|
|
164
|
+
const passed = score.overall >= (this.config.minScore || 80);
|
|
165
|
+
const badge = passed ? "✅ PASSED" : "❌ FAILED";
|
|
166
|
+
return `
|
|
167
|
+
=============================================================
|
|
168
|
+
MCP Studio Compliance Report
|
|
169
|
+
=============================================================
|
|
170
|
+
Overall Score: ${score.overall}/100 [${badge} (Min required: ${this.config.minScore || 80})]
|
|
171
|
+
|
|
172
|
+
Breakdown:
|
|
173
|
+
• Spec Compliance: ${score.breakdown.specCompliance}/100
|
|
174
|
+
• P50 Latency: ${score.breakdown.latencyPercentile50} ms
|
|
175
|
+
• P95 Latency: ${score.breakdown.latencyPercentile95} ms
|
|
176
|
+
• Success Rate: ${(score.breakdown.successRate * 100).toFixed(1)}%
|
|
177
|
+
• Total Errors: ${score.breakdown.errorCount}
|
|
178
|
+
|
|
179
|
+
Session ID: ${score.sessionId}
|
|
180
|
+
Generated: ${score.timestamp}
|
|
181
|
+
=============================================================
|
|
182
|
+
`.trim();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export function createBenchmark(config) {
|
|
186
|
+
return new Benchmark(config);
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoCH;;GAEG;AACH,MAAM,OAAO,SAAS;IAGpB,YAAY,SAAsB,EAAE;QAClC,IAAI,CAAC,MAAM,GAAG;YACZ,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;YAC/B,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC;YAClC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;SAChC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,OAAmB;QAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAuB,CAAC;QACzF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAE7D,0CAA0C;QAC1C,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,yDAAyD;QACzD,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC;QAC3F,IAAI,aAAa,EAAE,CAAC;YAClB,cAAc,IAAI,EAAE,CAAC;QACvB,CAAC;QAED,kEAAkE;QAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3B,WAAW,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;QAEjD,uBAAuB;QACvB,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YAChF,cAAc,IAAI,EAAE,CAAC;QACvB,CAAC;QAED,kEAAkE;QAClE,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC3D,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7B,IAAI,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC9E,eAAe,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;QACD,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3F,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAElD,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAE5D,oCAAoC;QACpC,MAAM,SAAS,GAAG,cAAc;aAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;aACvB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,CAAC;aAC3D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;YACpD,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACvF,CAAC;QAED,qEAAqE;QACrE,IAAI,YAAY,GAAG,GAAG,CAAC;QACvB,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;YACd,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,8BAA8B;QAC9B,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC;QACzC,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;QAC5D,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QACtE,MAAM,WAAW,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;QAExE,sCAAsC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,cAAc,GAAG,GAAG;YACpB,WAAW,GAAG,GAAG,GAAG,IAAI;YACxB,YAAY,GAAG,IAAI,CACpB,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5C,SAAS,EAAE;gBACT,cAAc;gBACd,mBAAmB,EAAE,GAAG;gBACxB,mBAAmB,EAAE,GAAG;gBACxB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC3C,UAAU;aACX;YACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,OAAO,CAAC,EAAE;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iBAAiB,CACf,QAAoB,EACpB,OAAmB;QAEnB,MAAM,QAAQ,GAAwB,EAAE,CAAC;QACzC,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAEhD,oBAAoB;QACpB,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;QACjE,IAAI,WAAW,GAAG,CAAC,EAAE,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,uCAAuC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,YAAY,aAAa,CAAC,OAAO,OAAO,YAAY,CAAC,OAAO,GAAG;aACrI,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,kDAAkD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS;aAC1F,CAAC,CAAC;QACL,CAAC;QAED,qBAAqB;QACrB,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,mBAAmB,GAAG,aAAa,CAAC,SAAS,CAAC,mBAAmB,CAAC;QACzG,IAAI,aAAa,CAAC,SAAS,CAAC,mBAAmB,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;YACpE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9F,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;gBAChD,OAAO,EAAE,4BAA4B,OAAO,QAAQ,WAAW,IAAI;aACpE,CAAC,CAAC;QACL,CAAC;QAED,aAAa;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC;QACzF,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,8BAA8B,SAAS,eAAe;aAChE,CAAC,CAAC;QACL,CAAC;QAED,oBAAoB;QACpB,MAAM,WAAW,GAAG,MAAM,CACxB,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACtF,CAAC;QACF,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,6BAA6B,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;aAC7J,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,KAAsB;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE/C,OAAO;;;;iBAIM,KAAK,CAAC,OAAO,UAAU,KAAK,mBAAmB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;;;yBAGjE,KAAK,CAAC,SAAS,CAAC,cAAc;yBAC9B,KAAK,CAAC,SAAS,CAAC,mBAAmB;yBACnC,KAAK,CAAC,SAAS,CAAC,mBAAmB;yBACnC,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;yBAC9C,KAAK,CAAC,SAAS,CAAC,UAAU;;cAErC,KAAK,CAAC,SAAS;cACf,KAAK,CAAC,SAAS;;CAE5B,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yumdee/mcp-studio-bench",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Compliance & reliability scoring for MCP servers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp-studio-bench": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/maheshsingh20/YumDee-MCP-Studio.git",
|
|
21
|
+
"directory": "packages/bench"
|
|
22
|
+
},
|
|
23
|
+
"author": "Mahesh Singh <maheshsingh20>",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@yumdee/mcp-studio-core": "0.1.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"typescript": "^5.3.0",
|
|
31
|
+
"vitest": "^1.0.0"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "tsc --watch --incremental",
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"lint": "eslint src/",
|
|
38
|
+
"test": "vitest run"
|
|
39
|
+
}
|
|
40
|
+
}
|