@yawlabs/mcp-compliance 0.9.2 → 0.11.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/README.md +77 -3
- package/dist/{chunk-FKTEFLK5.js → chunk-DGGPE3ZM.js} +133 -4
- package/dist/index.js +733 -182
- package/dist/mcp/server.js +1 -1
- package/dist/runner.d.ts +21 -2
- package/dist/runner.js +5 -3
- package/package.json +4 -1
- package/schemas/report.v1.json +165 -0
package/dist/mcp/server.js
CHANGED
package/dist/runner.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ interface TestResult {
|
|
|
12
12
|
type Grade = "A" | "B" | "C" | "D" | "F";
|
|
13
13
|
type Overall = "pass" | "partial" | "fail";
|
|
14
14
|
interface ComplianceReport {
|
|
15
|
+
/** Stable report-format version. See REPORT_SCHEMA_VERSION. */
|
|
16
|
+
schemaVersion: string;
|
|
15
17
|
specVersion: string;
|
|
16
18
|
toolVersion: string;
|
|
17
19
|
url: string;
|
|
@@ -96,6 +98,16 @@ declare function computeScore(tests: TestResult[]): {
|
|
|
96
98
|
}>;
|
|
97
99
|
};
|
|
98
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Generate a short, deterministic hash of a URL for badge paths.
|
|
103
|
+
* SHA-256 truncated to 24 hex chars (96 bits of entropy) — matches the
|
|
104
|
+
* server-side hash width used by mcp.hosting for `/compliance/ext/<hash>`.
|
|
105
|
+
*
|
|
106
|
+
* Exported so mcp.hosting (and other consumers) can compute matching
|
|
107
|
+
* hashes when looking up reports/badges by URL. The hash is the canonical
|
|
108
|
+
* key for `/compliance/ext/<hash>` and `/api/compliance/ext/<hash>/badge`.
|
|
109
|
+
*/
|
|
110
|
+
declare function urlHash(url: string): string;
|
|
99
111
|
/**
|
|
100
112
|
* Generate badge URLs and markdown for a compliance report.
|
|
101
113
|
* Badge images are served by mcp.hosting.
|
|
@@ -135,8 +147,15 @@ interface PreviewOptions {
|
|
|
135
147
|
*/
|
|
136
148
|
declare function previewTests(opts?: PreviewOptions): TestDefinition[];
|
|
137
149
|
interface RunOptions {
|
|
138
|
-
/** Optional callback for progress updates */
|
|
150
|
+
/** Optional callback for progress updates (legacy minimal signature). */
|
|
139
151
|
onProgress?: (testId: string, passed: boolean, details: string) => void;
|
|
152
|
+
/**
|
|
153
|
+
* Optional callback fired after each test completes with the full
|
|
154
|
+
* TestResult (category, required, durationMs, specRef). Prefer this
|
|
155
|
+
* over onProgress for live dashboards and streaming UIs that need
|
|
156
|
+
* structured data per test.
|
|
157
|
+
*/
|
|
158
|
+
onTestComplete?: (result: TestResult) => void;
|
|
140
159
|
/** Extra headers to include on all requests */
|
|
141
160
|
headers?: Record<string, string>;
|
|
142
161
|
/** Request timeout in milliseconds (default: 15000) */
|
|
@@ -156,4 +175,4 @@ interface RunOptions {
|
|
|
156
175
|
*/
|
|
157
176
|
declare function runComplianceSuite(target: string | TransportTarget, options?: RunOptions): Promise<ComplianceReport>;
|
|
158
177
|
|
|
159
|
-
export { type ComplianceReport, type PreviewOptions, type RunOptions, SPEC_BASE, SPEC_VERSION, TEST_DEFINITIONS, type TestResult, computeGrade, computeScore, generateBadge, parseSSEResponse, previewTests, runComplianceSuite };
|
|
178
|
+
export { type ComplianceReport, type PreviewOptions, type RunOptions, SPEC_BASE, SPEC_VERSION, TEST_DEFINITIONS, type TestResult, computeGrade, computeScore, generateBadge, parseSSEResponse, previewTests, runComplianceSuite, urlHash };
|
package/dist/runner.js
CHANGED
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
generateBadge,
|
|
8
8
|
parseSSEResponse,
|
|
9
9
|
previewTests,
|
|
10
|
-
runComplianceSuite
|
|
11
|
-
|
|
10
|
+
runComplianceSuite,
|
|
11
|
+
urlHash
|
|
12
|
+
} from "./chunk-DGGPE3ZM.js";
|
|
12
13
|
export {
|
|
13
14
|
SPEC_BASE,
|
|
14
15
|
SPEC_VERSION,
|
|
@@ -18,5 +19,6 @@ export {
|
|
|
18
19
|
generateBadge,
|
|
19
20
|
parseSSEResponse,
|
|
20
21
|
previewTests,
|
|
21
|
-
runComplianceSuite
|
|
22
|
+
runComplianceSuite,
|
|
23
|
+
urlHash
|
|
22
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yawlabs/mcp-compliance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "CLI tool and MCP server that tests MCP servers for spec compliance",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Yaw Labs <contact@yaw.sh> (https://yaw.sh)",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
25
|
"!dist/**/*.test.*",
|
|
26
|
+
"schemas",
|
|
26
27
|
"README.md",
|
|
27
28
|
"LICENSE"
|
|
28
29
|
],
|
|
@@ -47,6 +48,8 @@
|
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@biomejs/biome": "^1.9.4",
|
|
49
50
|
"@types/node": "^25.5.2",
|
|
51
|
+
"ajv": "^8.18.0",
|
|
52
|
+
"ajv-formats": "^3.0.1",
|
|
50
53
|
"tsup": "^8.4.0",
|
|
51
54
|
"typescript": "^5.8.3",
|
|
52
55
|
"vitest": "^3.1.1"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mcp.hosting/schemas/compliance/report.v1.json",
|
|
4
|
+
"title": "MCP Compliance Report",
|
|
5
|
+
"description": "Structured output of the mcp-compliance test suite. Stable, versioned contract — increment schemaVersion on breaking changes. Consumed by mcp.hosting and third-party dashboards.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"specVersion",
|
|
10
|
+
"toolVersion",
|
|
11
|
+
"url",
|
|
12
|
+
"timestamp",
|
|
13
|
+
"score",
|
|
14
|
+
"grade",
|
|
15
|
+
"overall",
|
|
16
|
+
"summary",
|
|
17
|
+
"categories",
|
|
18
|
+
"tests",
|
|
19
|
+
"warnings",
|
|
20
|
+
"serverInfo",
|
|
21
|
+
"toolCount",
|
|
22
|
+
"toolNames",
|
|
23
|
+
"resourceCount",
|
|
24
|
+
"resourceNames",
|
|
25
|
+
"promptCount",
|
|
26
|
+
"promptNames",
|
|
27
|
+
"badge"
|
|
28
|
+
],
|
|
29
|
+
"properties": {
|
|
30
|
+
"schemaVersion": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"const": "1",
|
|
33
|
+
"description": "Version of this report schema. Breaking changes bump the major version."
|
|
34
|
+
},
|
|
35
|
+
"specVersion": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"description": "MCP spec version tested against, e.g. \"2025-11-25\"."
|
|
38
|
+
},
|
|
39
|
+
"toolVersion": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"description": "Version of the mcp-compliance tool that produced this report."
|
|
42
|
+
},
|
|
43
|
+
"url": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "HTTP URL or stdio display string for the server under test."
|
|
46
|
+
},
|
|
47
|
+
"timestamp": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"format": "date-time",
|
|
50
|
+
"description": "ISO 8601 timestamp of when the report was generated."
|
|
51
|
+
},
|
|
52
|
+
"score": {
|
|
53
|
+
"type": "number",
|
|
54
|
+
"minimum": 0,
|
|
55
|
+
"maximum": 100,
|
|
56
|
+
"description": "Weighted compliance score: required tests 70%, optional 30%."
|
|
57
|
+
},
|
|
58
|
+
"grade": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"enum": ["A", "B", "C", "D", "F"],
|
|
61
|
+
"description": "Letter grade derived from score. A>=90, B>=75, C>=60, D>=40, F<40."
|
|
62
|
+
},
|
|
63
|
+
"overall": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"enum": ["pass", "partial", "fail"],
|
|
66
|
+
"description": "High-level verdict: pass = all required tests passed, partial = some failed, fail = many failed."
|
|
67
|
+
},
|
|
68
|
+
"summary": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"required": ["total", "passed", "failed", "required", "requiredPassed"],
|
|
71
|
+
"properties": {
|
|
72
|
+
"total": { "type": "integer", "minimum": 0 },
|
|
73
|
+
"passed": { "type": "integer", "minimum": 0 },
|
|
74
|
+
"failed": { "type": "integer", "minimum": 0 },
|
|
75
|
+
"required": { "type": "integer", "minimum": 0 },
|
|
76
|
+
"requiredPassed": { "type": "integer", "minimum": 0 }
|
|
77
|
+
},
|
|
78
|
+
"additionalProperties": false
|
|
79
|
+
},
|
|
80
|
+
"categories": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"description": "Per-category pass/total counts, keyed by TestCategory.",
|
|
83
|
+
"additionalProperties": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"required": ["passed", "total"],
|
|
86
|
+
"properties": {
|
|
87
|
+
"passed": { "type": "integer", "minimum": 0 },
|
|
88
|
+
"total": { "type": "integer", "minimum": 0 }
|
|
89
|
+
},
|
|
90
|
+
"additionalProperties": false
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"tests": {
|
|
94
|
+
"type": "array",
|
|
95
|
+
"items": { "$ref": "#/$defs/TestResult" }
|
|
96
|
+
},
|
|
97
|
+
"warnings": {
|
|
98
|
+
"type": "array",
|
|
99
|
+
"items": { "type": "string" },
|
|
100
|
+
"description": "Non-fatal diagnostics from the test run. Capped at 100 entries."
|
|
101
|
+
},
|
|
102
|
+
"serverInfo": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"required": ["protocolVersion", "name", "version", "capabilities"],
|
|
105
|
+
"properties": {
|
|
106
|
+
"protocolVersion": { "type": ["string", "null"] },
|
|
107
|
+
"name": { "type": ["string", "null"] },
|
|
108
|
+
"version": { "type": ["string", "null"] },
|
|
109
|
+
"capabilities": { "type": "object" }
|
|
110
|
+
},
|
|
111
|
+
"additionalProperties": false
|
|
112
|
+
},
|
|
113
|
+
"toolCount": { "type": "integer", "minimum": 0 },
|
|
114
|
+
"toolNames": { "type": "array", "items": { "type": "string" } },
|
|
115
|
+
"resourceCount": { "type": "integer", "minimum": 0 },
|
|
116
|
+
"resourceNames": { "type": "array", "items": { "type": "string" } },
|
|
117
|
+
"promptCount": { "type": "integer", "minimum": 0 },
|
|
118
|
+
"promptNames": { "type": "array", "items": { "type": "string" } },
|
|
119
|
+
"badge": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"required": ["imageUrl", "reportUrl", "markdown", "html"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"imageUrl": { "type": "string", "format": "uri" },
|
|
124
|
+
"reportUrl": { "type": "string", "format": "uri" },
|
|
125
|
+
"markdown": { "type": "string" },
|
|
126
|
+
"html": { "type": "string" }
|
|
127
|
+
},
|
|
128
|
+
"additionalProperties": false
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"additionalProperties": false,
|
|
132
|
+
"$defs": {
|
|
133
|
+
"TestResult": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"required": ["id", "name", "category", "passed", "required", "details", "durationMs"],
|
|
136
|
+
"properties": {
|
|
137
|
+
"id": { "type": "string" },
|
|
138
|
+
"name": { "type": "string" },
|
|
139
|
+
"category": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"enum": [
|
|
142
|
+
"transport",
|
|
143
|
+
"lifecycle",
|
|
144
|
+
"tools",
|
|
145
|
+
"resources",
|
|
146
|
+
"prompts",
|
|
147
|
+
"errors",
|
|
148
|
+
"schema",
|
|
149
|
+
"security"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
"passed": { "type": "boolean" },
|
|
153
|
+
"required": { "type": "boolean" },
|
|
154
|
+
"details": { "type": "string" },
|
|
155
|
+
"durationMs": { "type": "integer", "minimum": 0 },
|
|
156
|
+
"specRef": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"format": "uri",
|
|
159
|
+
"description": "Deep link to the relevant spec section."
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"additionalProperties": false
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|