@yawlabs/mcp-compliance 0.2.1 → 0.3.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.
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  TEST_DEFINITIONS,
3
3
  runComplianceSuite
4
- } from "../chunk-SP24UFRC.js";
4
+ } from "../chunk-U66YZGE5.js";
5
5
 
6
6
  // src/mcp/server.ts
7
+ import { createRequire } from "module";
7
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
9
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
- import { createRequire } from "module";
10
10
 
11
11
  // src/mcp/tools.ts
12
12
  import { z } from "zod";
@@ -15,11 +15,32 @@ function registerTools(server2) {
15
15
  "mcp_compliance_test",
16
16
  "Run the full MCP compliance test suite against a server URL. Returns grade (A-F), score, and detailed results for all 43 tests covering transport, lifecycle, tools, resources, prompts, errors, and schema validation.",
17
17
  {
18
- url: z.string().url().describe("The MCP server URL to test (must be HTTP or HTTPS)")
18
+ url: z.string().url().describe("The MCP server URL to test (must be HTTP or HTTPS)"),
19
+ auth: z.string().optional().describe('Authorization header value (e.g., "Bearer tok123")'),
20
+ headers: z.record(z.string()).optional().describe('Additional headers to include on all requests (e.g., {"X-Api-Key": "abc"})'),
21
+ timeout: z.number().optional().describe("Request timeout in milliseconds (default: 15000)"),
22
+ retries: z.number().optional().describe("Number of retries for failed tests (default: 0)"),
23
+ only: z.array(z.string()).optional().describe("Only run tests matching these categories or test IDs"),
24
+ skip: z.array(z.string()).optional().describe("Skip tests matching these categories or test IDs")
25
+ },
26
+ {
27
+ title: "Run MCP Compliance Tests",
28
+ readOnlyHint: true,
29
+ destructiveHint: false,
30
+ idempotentHint: true,
31
+ openWorldHint: true
19
32
  },
20
- async ({ url }) => {
33
+ async ({ url, auth, headers: extraHeaders, timeout, retries, only, skip }) => {
21
34
  try {
22
- const report = await runComplianceSuite(url);
35
+ const headers = { ...extraHeaders };
36
+ if (auth) headers.Authorization = auth;
37
+ const report = await runComplianceSuite(url, {
38
+ headers: Object.keys(headers).length > 0 ? headers : void 0,
39
+ timeout,
40
+ retries,
41
+ only,
42
+ skip
43
+ });
23
44
  const summary = [
24
45
  `Grade: ${report.grade} (${report.score}%)`,
25
46
  `Overall: ${report.overall}`,
@@ -59,25 +80,42 @@ ${JSON.stringify(report, null, 2)}` }
59
80
  "mcp_compliance_badge",
60
81
  "Get the badge markdown embed code for an MCP server. Runs the compliance test suite first to determine the grade.",
61
82
  {
62
- url: z.string().url().describe("The MCP server URL to test")
83
+ url: z.string().url().describe("The MCP server URL to test"),
84
+ auth: z.string().optional().describe('Authorization header value (e.g., "Bearer tok123")'),
85
+ headers: z.record(z.string()).optional().describe("Additional headers to include on all requests"),
86
+ timeout: z.number().optional().describe("Request timeout in milliseconds (default: 15000)")
87
+ },
88
+ {
89
+ title: "Get Compliance Badge",
90
+ readOnlyHint: true,
91
+ destructiveHint: false,
92
+ idempotentHint: true,
93
+ openWorldHint: true
63
94
  },
64
- async ({ url }) => {
95
+ async ({ url, auth, headers: extraHeaders, timeout }) => {
65
96
  try {
66
- const report = await runComplianceSuite(url);
97
+ const headers = { ...extraHeaders };
98
+ if (auth) headers.Authorization = auth;
99
+ const report = await runComplianceSuite(url, {
100
+ headers: Object.keys(headers).length > 0 ? headers : void 0,
101
+ timeout
102
+ });
67
103
  const badge = report.badge;
68
104
  return {
69
- content: [{
70
- type: "text",
71
- text: [
72
- `Grade: ${report.grade} (${report.score}%)`,
73
- "",
74
- "Markdown:",
75
- badge.markdown,
76
- "",
77
- "HTML:",
78
- badge.html
79
- ].join("\n")
80
- }]
105
+ content: [
106
+ {
107
+ type: "text",
108
+ text: [
109
+ `Grade: ${report.grade} (${report.score}%)`,
110
+ "",
111
+ "Markdown:",
112
+ badge.markdown,
113
+ "",
114
+ "HTML:",
115
+ badge.html
116
+ ].join("\n")
117
+ }
118
+ ]
81
119
  };
82
120
  } catch (err) {
83
121
  return {
@@ -93,33 +131,44 @@ ${JSON.stringify(report, null, 2)}` }
93
131
  {
94
132
  testId: z.string().describe('The test ID to explain (e.g., "transport-post", "lifecycle-init", "tools-schema")')
95
133
  },
134
+ {
135
+ title: "Explain Compliance Test",
136
+ readOnlyHint: true,
137
+ destructiveHint: false,
138
+ idempotentHint: true,
139
+ openWorldHint: false
140
+ },
96
141
  async ({ testId }) => {
97
142
  const def = TEST_DEFINITIONS.find((t) => t.id === testId);
98
143
  if (!def) {
99
144
  return {
100
- content: [{
101
- type: "text",
102
- text: `Unknown test ID: "${testId}"
145
+ content: [
146
+ {
147
+ type: "text",
148
+ text: `Unknown test ID: "${testId}"
103
149
 
104
150
  Valid test IDs:
105
151
  ${TEST_DEFINITIONS.map((t) => t.id).join(", ")}`
106
- }],
152
+ }
153
+ ],
107
154
  isError: true
108
155
  };
109
156
  }
110
157
  return {
111
- content: [{
112
- type: "text",
113
- text: [
114
- `Test: ${def.id}`,
115
- `Name: ${def.name}`,
116
- `Category: ${def.category}`,
117
- `Required: ${def.required ? "Yes" : "No"}`,
118
- `Spec reference: https://modelcontextprotocol.io/specification/2025-11-25/${def.specRef}`,
119
- "",
120
- def.description
121
- ].join("\n")
122
- }]
158
+ content: [
159
+ {
160
+ type: "text",
161
+ text: [
162
+ `Test: ${def.id}`,
163
+ `Name: ${def.name}`,
164
+ `Category: ${def.category}`,
165
+ `Required: ${def.required ? "Yes" : "No"}`,
166
+ `Spec reference: https://modelcontextprotocol.io/specification/2025-11-25/${def.specRef}`,
167
+ "",
168
+ def.description
169
+ ].join("\n")
170
+ }
171
+ ]
123
172
  };
124
173
  }
125
174
  );
package/dist/runner.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type TestCategory = 'transport' | 'lifecycle' | 'tools' | 'resources' | 'prompts' | 'errors' | 'schema';
1
+ type TestCategory = "transport" | "lifecycle" | "tools" | "resources" | "prompts" | "errors" | "schema";
2
2
  interface TestResult {
3
3
  id: string;
4
4
  name: string;
@@ -9,8 +9,8 @@ interface TestResult {
9
9
  durationMs: number;
10
10
  specRef?: string;
11
11
  }
12
- type Grade = 'A' | 'B' | 'C' | 'D' | 'F';
13
- type Overall = 'pass' | 'partial' | 'fail';
12
+ type Grade = "A" | "B" | "C" | "D" | "F";
13
+ type Overall = "pass" | "partial" | "fail";
14
14
  interface ComplianceReport {
15
15
  specVersion: string;
16
16
  toolVersion: string;
@@ -66,7 +66,7 @@ declare function computeGrade(score: number): Grade;
66
66
  declare function computeScore(tests: TestResult[]): {
67
67
  score: number;
68
68
  grade: Grade;
69
- overall: 'pass' | 'partial' | 'fail';
69
+ overall: "pass" | "partial" | "fail";
70
70
  summary: {
71
71
  total: number;
72
72
  passed: number;
package/dist/runner.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  computeScore,
5
5
  generateBadge,
6
6
  runComplianceSuite
7
- } from "./chunk-SP24UFRC.js";
7
+ } from "./chunk-U66YZGE5.js";
8
8
  export {
9
9
  TEST_DEFINITIONS,
10
10
  computeGrade,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/mcp-compliance",
3
- "version": "0.2.1",
3
+ "version": "0.3.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 (https://yaw.sh)",
@@ -24,7 +24,10 @@
24
24
  "build": "tsup",
25
25
  "dev": "tsup --watch",
26
26
  "test": "vitest run",
27
- "lint": "tsc --noEmit",
27
+ "lint": "biome check src/",
28
+ "lint:fix": "biome check --write src/",
29
+ "typecheck": "tsc --noEmit",
30
+ "test:ci": "npm run build && npm test",
28
31
  "prepublishOnly": "npm run build"
29
32
  },
30
33
  "dependencies": {
@@ -35,6 +38,7 @@
35
38
  "zod": "^3.24.4"
36
39
  },
37
40
  "devDependencies": {
41
+ "@biomejs/biome": "^1.9.4",
38
42
  "@types/node": "^25.5.2",
39
43
  "tsup": "^8.4.0",
40
44
  "typescript": "^5.8.3",
@@ -52,7 +56,10 @@
52
56
  ],
53
57
  "repository": {
54
58
  "type": "git",
55
- "url": "git+https://github.com/yawlabs/mcp-compliance.git"
59
+ "url": "git+https://github.com/YawLabs/mcp-compliance.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/YawLabs/mcp-compliance/issues"
56
63
  },
57
64
  "homepage": "https://mcp.hosting"
58
65
  }