@k08200/mcp-probe 0.1.0 → 0.8.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.
Files changed (41) hide show
  1. package/README.md +224 -13
  2. package/dist/checker.d.ts +2 -11
  3. package/dist/checker.d.ts.map +1 -1
  4. package/dist/checker.js +92 -9
  5. package/dist/checker.js.map +1 -1
  6. package/dist/cli.js +115 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts +4 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +122 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/protocols/mcp-client.d.ts.map +1 -1
  13. package/dist/protocols/mcp-client.js +212 -61
  14. package/dist/protocols/mcp-client.js.map +1 -1
  15. package/dist/reporters/badge.d.ts +12 -0
  16. package/dist/reporters/badge.d.ts.map +1 -0
  17. package/dist/reporters/badge.js +34 -0
  18. package/dist/reporters/badge.js.map +1 -0
  19. package/dist/reporters/github.d.ts +7 -0
  20. package/dist/reporters/github.d.ts.map +1 -0
  21. package/dist/reporters/github.js +138 -0
  22. package/dist/reporters/github.js.map +1 -0
  23. package/dist/reporters/json-reporter.d.ts +2 -2
  24. package/dist/reporters/json-reporter.d.ts.map +1 -1
  25. package/dist/reporters/json-reporter.js.map +1 -1
  26. package/dist/reporters/terminal.d.ts +2 -1
  27. package/dist/reporters/terminal.d.ts.map +1 -1
  28. package/dist/reporters/terminal.js +38 -0
  29. package/dist/reporters/terminal.js.map +1 -1
  30. package/dist/types.d.ts +66 -2
  31. package/dist/types.d.ts.map +1 -1
  32. package/examples/datadog.tools.json +13 -0
  33. package/examples/github-actions/fleet.yml +25 -0
  34. package/examples/github-actions/remote-server.yml +24 -0
  35. package/examples/github-actions/single-server.yml +21 -0
  36. package/examples/mcp-probe.config.json +19 -0
  37. package/examples/recipes/README.md +35 -0
  38. package/examples/recipes/datadog.tools.json +23 -0
  39. package/examples/recipes/gmail.tools.json +18 -0
  40. package/examples/recipes/supabase.tools.json +19 -0
  41. package/package.json +4 -3
package/dist/config.js ADDED
@@ -0,0 +1,122 @@
1
+ import { dirname, isAbsolute, resolve } from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { checkMcpServer } from './checker.js';
4
+ function isObject(value) {
5
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
6
+ }
7
+ function validateServer(server, index) {
8
+ if (!isObject(server)) {
9
+ throw new Error(`Invalid config: servers[${index}] must be an object`);
10
+ }
11
+ if (typeof server.name !== 'string' || server.name.length === 0) {
12
+ throw new Error(`Invalid config: servers[${index}].name must be a non-empty string`);
13
+ }
14
+ if (typeof server.target !== 'string' || server.target.length === 0) {
15
+ throw new Error(`Invalid config: servers[${index}].target must be a non-empty string`);
16
+ }
17
+ if (server.serverArgs !== undefined && (!Array.isArray(server.serverArgs) || !server.serverArgs.every((arg) => typeof arg === 'string'))) {
18
+ throw new Error(`Invalid config: servers[${index}].serverArgs must be a string array`);
19
+ }
20
+ if (server.timeoutMs !== undefined && (typeof server.timeoutMs !== 'number' || server.timeoutMs <= 0)) {
21
+ throw new Error(`Invalid config: servers[${index}].timeoutMs must be a positive number`);
22
+ }
23
+ if (server.transport !== undefined && !['stdio', 'http', 'sse'].includes(String(server.transport))) {
24
+ throw new Error(`Invalid config: servers[${index}].transport must be stdio, http, or sse`);
25
+ }
26
+ if (server.headers !== undefined) {
27
+ if (!isObject(server.headers)) {
28
+ throw new Error(`Invalid config: servers[${index}].headers must be an object`);
29
+ }
30
+ for (const [key, value] of Object.entries(server.headers)) {
31
+ if (typeof value !== 'string') {
32
+ throw new Error(`Invalid config: servers[${index}].headers.${key} must be a string`);
33
+ }
34
+ }
35
+ }
36
+ if (server.probeTools !== undefined && typeof server.probeTools !== 'boolean') {
37
+ throw new Error(`Invalid config: servers[${index}].probeTools must be a boolean`);
38
+ }
39
+ if (server.toolsFile !== undefined && typeof server.toolsFile !== 'string') {
40
+ throw new Error(`Invalid config: servers[${index}].toolsFile must be a string`);
41
+ }
42
+ return server;
43
+ }
44
+ export function loadConfig(configFile) {
45
+ if (!existsSync(configFile)) {
46
+ throw new Error(`Cannot read config file: ${configFile}`);
47
+ }
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(readFileSync(configFile, 'utf8'));
51
+ }
52
+ catch {
53
+ throw new Error(`Invalid config JSON: ${configFile}`);
54
+ }
55
+ if (!isObject(parsed)) {
56
+ throw new Error(`Invalid config: root must be an object`);
57
+ }
58
+ if (parsed.timeoutMs !== undefined && (typeof parsed.timeoutMs !== 'number' || parsed.timeoutMs <= 0)) {
59
+ throw new Error(`Invalid config: timeoutMs must be a positive number`);
60
+ }
61
+ if (!Array.isArray(parsed.servers) || parsed.servers.length === 0) {
62
+ throw new Error(`Invalid config: servers must be a non-empty array`);
63
+ }
64
+ return {
65
+ timeoutMs: parsed.timeoutMs,
66
+ servers: parsed.servers.map(validateServer),
67
+ };
68
+ }
69
+ function deriveOverallStatus(statuses) {
70
+ if (statuses.includes('fail'))
71
+ return 'fail';
72
+ if (statuses.includes('warn'))
73
+ return 'warn';
74
+ return 'pass';
75
+ }
76
+ function resolveConfigPath(configFile, maybeRelative) {
77
+ if (!maybeRelative || isAbsolute(maybeRelative))
78
+ return maybeRelative;
79
+ return resolve(dirname(configFile), maybeRelative);
80
+ }
81
+ function expandEnvVars(value) {
82
+ return value.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi, (match, name) => {
83
+ const envValue = process.env[name];
84
+ if (envValue === undefined) {
85
+ throw new Error(`Environment variable ${name} is not set`);
86
+ }
87
+ return envValue;
88
+ });
89
+ }
90
+ function expandHeaders(headers) {
91
+ if (!headers)
92
+ return undefined;
93
+ return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, expandEnvVars(value)]));
94
+ }
95
+ export async function checkConfigFile(configFile, defaultTimeoutMs = 10000) {
96
+ const startTime = Date.now();
97
+ const config = loadConfig(configFile);
98
+ const servers = [];
99
+ for (const server of config.servers) {
100
+ const options = {
101
+ target: server.target,
102
+ serverArgs: server.serverArgs,
103
+ timeoutMs: server.timeoutMs ?? config.timeoutMs ?? defaultTimeoutMs,
104
+ transport: server.transport,
105
+ headers: expandHeaders(server.headers),
106
+ probeTools: server.probeTools,
107
+ toolsFile: resolveConfigPath(configFile, server.toolsFile),
108
+ };
109
+ servers.push({
110
+ name: server.name,
111
+ report: await checkMcpServer(options),
112
+ });
113
+ }
114
+ return {
115
+ target: configFile,
116
+ timestamp: new Date().toISOString(),
117
+ overallStatus: deriveOverallStatus(servers.map((server) => server.report.overallStatus)),
118
+ servers,
119
+ totalLatencyMs: Date.now() - startTime,
120
+ };
121
+ }
122
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoB7D,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiFhF"}
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AA4H7E,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwHhF"}
@@ -1,31 +1,137 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
5
+ const VERSION = '0.8.0';
6
+ // Known startup warning patterns from official MCP servers — not fatal errors
7
+ const STDERR_WARNING_PATTERNS = [
8
+ /^warn(?:ing)?:/i,
9
+ /deprecat/i,
10
+ /optional.*not found/i,
11
+ /version.*mismatch/i,
12
+ /missing optional/i,
13
+ /checking for updates/i,
14
+ /update available/i,
15
+ ];
16
+ function isStderrNoise(line) {
17
+ return STDERR_WARNING_PATTERNS.some((p) => p.test(line));
18
+ }
3
19
  function firstMeaningfulLine(text) {
4
20
  const lines = text.split('\n').map((l) => l.trim()).filter(Boolean);
5
- // 1. "Error: ..." lines are most informative
6
- const errorColonLine = lines.find((l) => /^Error:/.test(l));
7
- if (errorColonLine)
8
- return errorColonLine;
9
- // 2. Skip stack frames, node internals, carets, and bare code fragments
21
+ const nonNoise = lines.filter((l) => !isStderrNoise(l));
22
+ const target = nonNoise.length > 0 ? nonNoise : lines;
23
+ const errorLine = target.find((l) => /^Error:/i.test(l));
24
+ if (errorLine)
25
+ return errorLine;
10
26
  const skip = /^at |^node:|^\^$|^const |^throw |^Require stack/;
11
- const meaningful = lines.find((l) => !skip.test(l) && l.length > 3);
12
- return meaningful ?? lines[0] ?? text;
27
+ return target.find((l) => !skip.test(l) && l.length > 3) ?? target[0] ?? text;
13
28
  }
14
29
  function withTimeout(promise, ms, label) {
15
- const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms));
16
- return Promise.race([promise, timeout]);
30
+ let timeoutId;
31
+ const timeoutPromise = new Promise((_, reject) => {
32
+ timeoutId = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
33
+ });
34
+ return Promise.race([promise, timeoutPromise]).finally(() => {
35
+ if (timeoutId)
36
+ clearTimeout(timeoutId);
37
+ });
38
+ }
39
+ // Fallback: generate minimal inputs from JSON Schema when no sidecar entry exists
40
+ function generateMinimalInput(schema) {
41
+ if (!schema || typeof schema !== 'object')
42
+ return {};
43
+ const s = schema;
44
+ const props = s['properties'];
45
+ if (!props)
46
+ return {};
47
+ const required = s['required'] ?? [];
48
+ const input = {};
49
+ for (const key of required) {
50
+ const prop = props[key];
51
+ if (!prop)
52
+ continue;
53
+ switch (prop['type']) {
54
+ case 'string':
55
+ input[key] = '';
56
+ break;
57
+ case 'number':
58
+ case 'integer':
59
+ input[key] = 0;
60
+ break;
61
+ case 'boolean':
62
+ input[key] = false;
63
+ break;
64
+ case 'array':
65
+ input[key] = [];
66
+ break;
67
+ case 'object':
68
+ input[key] = {};
69
+ break;
70
+ default: input[key] = null;
71
+ }
72
+ }
73
+ return input;
74
+ }
75
+ function isAuthError(message, notErrorCodes) {
76
+ if (/401|403|unauthorized|forbidden/i.test(message))
77
+ return true;
78
+ if (notErrorCodes) {
79
+ return notErrorCodes.some((code) => message.includes(String(code)));
80
+ }
81
+ return false;
82
+ }
83
+ function toolResultErrorMessage(result) {
84
+ if (!result || typeof result !== 'object')
85
+ return undefined;
86
+ const toolResult = result;
87
+ if (toolResult.isError !== true)
88
+ return undefined;
89
+ if (!Array.isArray(toolResult.content))
90
+ return 'Tool returned an error result';
91
+ const textParts = toolResult.content
92
+ .map((part) => {
93
+ if (!part || typeof part !== 'object')
94
+ return undefined;
95
+ const maybeText = part.text;
96
+ return typeof maybeText === 'string' ? maybeText : undefined;
97
+ })
98
+ .filter((part) => Boolean(part));
99
+ return textParts.join('\n') || 'Tool returned an error result';
100
+ }
101
+ function makeRequestInit(headers) {
102
+ if (!headers || Object.keys(headers).length === 0)
103
+ return undefined;
104
+ return { headers };
105
+ }
106
+ function createTransport(options) {
107
+ const mode = options.transport ?? 'stdio';
108
+ if (mode === 'stdio') {
109
+ if (!options.command) {
110
+ throw new Error('stdio transport requires a command');
111
+ }
112
+ const transport = new StdioClientTransport({
113
+ command: options.command,
114
+ args: options.args ?? [],
115
+ env: { ...process.env },
116
+ stderr: 'pipe',
117
+ });
118
+ const stderrChunks = [];
119
+ transport.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
120
+ return { transport, stderrChunks };
121
+ }
122
+ if (!options.url) {
123
+ throw new Error(`${mode} transport requires a URL target`);
124
+ }
125
+ const url = new URL(options.url);
126
+ const requestInit = makeRequestInit(options.headers);
127
+ const transport = mode === 'sse'
128
+ ? new SSEClientTransport(url, { requestInit })
129
+ : new StreamableHTTPClientTransport(url, { requestInit });
130
+ return { transport, stderrChunks: [] };
17
131
  }
18
132
  export async function probeMcpServer(options) {
19
- const transport = new StdioClientTransport({
20
- command: options.command,
21
- args: options.args,
22
- env: { ...process.env },
23
- stderr: 'pipe',
24
- });
25
- // Collect stderr so we can surface crash reasons in error messages
26
- const stderrChunks = [];
27
- transport.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
28
- const client = new Client({ name: 'mcp-probe', version: '0.1.0' }, { capabilities: { roots: { listChanged: false } } });
133
+ const { transport, stderrChunks } = createTransport(options);
134
+ const client = new Client({ name: 'mcp-probe', version: VERSION }, { capabilities: { roots: { listChanged: false } } });
29
135
  const connectStart = Date.now();
30
136
  try {
31
137
  await withTimeout(client.connect(transport), options.timeoutMs, 'Connection');
@@ -35,53 +141,98 @@ export async function probeMcpServer(options) {
35
141
  const reason = stderrText
36
142
  ? firstMeaningfulLine(stderrText)
37
143
  : err instanceof Error ? err.message : String(err);
144
+ await client.close().catch(() => undefined);
38
145
  throw new Error(reason);
39
146
  }
40
147
  const connectLatencyMs = Date.now() - connectStart;
41
- const rawServerInfo = client.getServerVersion();
42
- const rawCaps = client.getServerCapabilities();
43
- const capabilities = Object.keys(rawCaps ?? {});
44
- const toolsStart = Date.now();
45
- const toolsResult = await withTimeout(client.listTools(), options.timeoutMs, 'tools/list');
46
- const toolsLatencyMs = Date.now() - toolsStart;
47
- let resourcesLatencyMs;
48
- let promptsLatencyMs;
49
- const resourcesList = [];
50
- const promptsList = [];
51
- if (rawCaps?.resources) {
52
- const t = Date.now();
53
- const result = await withTimeout(client.listResources(), options.timeoutMs, 'resources/list');
54
- resourcesLatencyMs = Date.now() - t;
55
- for (const r of result.resources) {
56
- resourcesList.push({ uri: r.uri, name: r.name, description: r.description });
148
+ try {
149
+ const rawServerInfo = client.getServerVersion();
150
+ const rawCaps = client.getServerCapabilities();
151
+ const capabilities = Object.keys(rawCaps ?? {});
152
+ const toolsStart = Date.now();
153
+ const toolsResult = await withTimeout(client.listTools(), options.timeoutMs, 'tools/list');
154
+ const toolsLatencyMs = Date.now() - toolsStart;
155
+ let resourcesLatencyMs;
156
+ let promptsLatencyMs;
157
+ const resourcesList = [];
158
+ const promptsList = [];
159
+ if (rawCaps?.resources) {
160
+ const t = Date.now();
161
+ const result = await withTimeout(client.listResources(), options.timeoutMs, 'resources/list');
162
+ resourcesLatencyMs = Date.now() - t;
163
+ for (const r of result.resources) {
164
+ resourcesList.push({ uri: r.uri, name: r.name, description: r.description });
165
+ }
57
166
  }
58
- }
59
- if (rawCaps?.prompts) {
60
- const t = Date.now();
61
- const result = await withTimeout(client.listPrompts(), options.timeoutMs, 'prompts/list');
62
- promptsLatencyMs = Date.now() - t;
63
- for (const p of result.prompts) {
64
- promptsList.push({ name: p.name, description: p.description });
167
+ if (rawCaps?.prompts) {
168
+ const t = Date.now();
169
+ const result = await withTimeout(client.listPrompts(), options.timeoutMs, 'prompts/list');
170
+ promptsLatencyMs = Date.now() - t;
171
+ for (const p of result.prompts) {
172
+ promptsList.push({ name: p.name, description: p.description });
173
+ }
65
174
  }
175
+ let toolCallResults;
176
+ if (options.probeTools && toolsResult.tools.length > 0) {
177
+ toolCallResults = [];
178
+ for (const tool of toolsResult.tools) {
179
+ const sidecarEntry = options.sidecar?.tools[tool.name];
180
+ // Sidecar input beats auto-generated because it can reach the real call path.
181
+ const input = sidecarEntry?.input ?? generateMinimalInput(tool.inputSchema);
182
+ const source = sidecarEntry ? 'sidecar' : 'auto';
183
+ const notErrorCodes = sidecarEntry?.expect?.not_error_code;
184
+ const start = Date.now();
185
+ try {
186
+ const result = await withTimeout(client.callTool({ name: tool.name, arguments: input }), options.timeoutMs, `callTool(${tool.name})`);
187
+ const toolError = toolResultErrorMessage(result);
188
+ if (toolError) {
189
+ const status = isAuthError(toolError, notErrorCodes) ? 'warn' : 'fail';
190
+ toolCallResults.push({
191
+ tool: tool.name,
192
+ status,
193
+ latencyMs: Date.now() - start,
194
+ error: toolError,
195
+ source,
196
+ });
197
+ continue;
198
+ }
199
+ toolCallResults.push({ tool: tool.name, status: 'pass', latencyMs: Date.now() - start, source });
200
+ }
201
+ catch (err) {
202
+ const msg = err instanceof Error ? err.message : String(err);
203
+ const status = isAuthError(msg, notErrorCodes) ? 'warn' : 'fail';
204
+ toolCallResults.push({
205
+ tool: tool.name,
206
+ status,
207
+ latencyMs: Date.now() - start,
208
+ error: msg,
209
+ source,
210
+ });
211
+ }
212
+ }
213
+ }
214
+ return {
215
+ serverInfo: {
216
+ name: rawServerInfo?.name ?? 'unknown',
217
+ version: rawServerInfo?.version ?? 'unknown',
218
+ capabilities,
219
+ },
220
+ tools: toolsResult.tools.map((t) => ({
221
+ name: t.name,
222
+ description: t.description,
223
+ inputSchema: t.inputSchema,
224
+ })),
225
+ resources: resourcesList,
226
+ prompts: promptsList,
227
+ connectLatencyMs,
228
+ toolsLatencyMs,
229
+ resourcesLatencyMs,
230
+ promptsLatencyMs,
231
+ toolCallResults,
232
+ };
233
+ }
234
+ finally {
235
+ await client.close().catch(() => undefined);
66
236
  }
67
- await client.close();
68
- return {
69
- serverInfo: {
70
- name: rawServerInfo?.name ?? 'unknown',
71
- version: rawServerInfo?.version ?? 'unknown',
72
- capabilities,
73
- },
74
- tools: toolsResult.tools.map((t) => ({
75
- name: t.name,
76
- description: t.description,
77
- inputSchema: t.inputSchema,
78
- })),
79
- resources: resourcesList,
80
- prompts: promptsList,
81
- connectLatencyMs,
82
- toolsLatencyMs,
83
- resourcesLatencyMs,
84
- promptsLatencyMs,
85
- };
86
237
  }
87
238
  //# sourceMappingURL=mcp-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { BatchReport, CheckReport } from '../types.js';
2
+ type AnyReport = CheckReport | BatchReport;
3
+ export type ShieldsBadge = {
4
+ schemaVersion: 1;
5
+ label: string;
6
+ message: string;
7
+ color: string;
8
+ };
9
+ export declare function buildBadge(report: AnyReport): ShieldsBadge;
10
+ export declare function writeBadgeFile(report: AnyReport, path: string): void;
11
+ export {};
12
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/reporters/badge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AAEzE,KAAK,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;AAE3C,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,CAAC,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAuBF,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,CAO1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGpE"}
@@ -0,0 +1,34 @@
1
+ import { dirname } from 'path';
2
+ import { mkdirSync, writeFileSync } from 'fs';
3
+ const COLORS = {
4
+ pass: 'brightgreen',
5
+ warn: 'yellow',
6
+ fail: 'red',
7
+ };
8
+ function isBatchReport(report) {
9
+ return 'servers' in report;
10
+ }
11
+ function batchMessage(report) {
12
+ const passed = report.servers.filter((server) => server.report.overallStatus === 'pass').length;
13
+ const warned = report.servers.filter((server) => server.report.overallStatus === 'warn').length;
14
+ const failed = report.servers.filter((server) => server.report.overallStatus === 'fail').length;
15
+ const parts = [`${passed} pass`];
16
+ if (warned > 0)
17
+ parts.push(`${warned} warn`);
18
+ if (failed > 0)
19
+ parts.push(`${failed} fail`);
20
+ return parts.join(', ');
21
+ }
22
+ export function buildBadge(report) {
23
+ return {
24
+ schemaVersion: 1,
25
+ label: isBatchReport(report) ? 'mcp fleet' : 'mcp probe',
26
+ message: isBatchReport(report) ? batchMessage(report) : report.overallStatus,
27
+ color: COLORS[report.overallStatus],
28
+ };
29
+ }
30
+ export function writeBadgeFile(report, path) {
31
+ mkdirSync(dirname(path), { recursive: true });
32
+ writeFileSync(path, `${JSON.stringify(buildBadge(report), null, 2)}\n`);
33
+ }
34
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../src/reporters/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAY9C,MAAM,MAAM,GAAgC;IAC1C,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,KAAK;CACZ,CAAC;AAEF,SAAS,aAAa,CAAC,MAAiB;IACtC,OAAO,SAAS,IAAI,MAAM,CAAC;AAC7B,CAAC;AAED,SAAS,YAAY,CAAC,MAAmB;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAChG,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAChG,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAEhG,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;IAC7C,IAAI,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;QACxD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa;QAC5E,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,IAAY;IAC5D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { BatchReport, CheckReport } from '../types.js';
2
+ type AnyReport = CheckReport | BatchReport;
3
+ export declare function buildGithubSummary(report: AnyReport): string;
4
+ export declare function buildGithubAnnotations(report: AnyReport): string[];
5
+ export declare function renderGithubActions(report: AnyReport, summaryPath?: string | undefined): void;
6
+ export {};
7
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/reporters/github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAa,WAAW,EAA+B,MAAM,aAAa,CAAC;AAEpG,KAAK,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;AA6G3C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAE5D;AAmBD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,CAYlE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,qBAAkC,GAAG,IAAI,CAQ1G"}