mcp-scorecard 0.5.8 → 0.5.10
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/CHANGELOG.md +10 -0
- package/README.md +10 -0
- package/dist/cli/commands.js +11 -3
- package/dist/cli/commands.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/http-v2.d.ts +18 -0
- package/dist/http-v2.js +80 -0
- package/dist/http-v2.js.map +1 -0
- package/dist/mcp-server.d.ts +13 -1
- package/dist/mcp-server.js +28 -4
- package/dist/mcp-server.js.map +1 -1
- package/dist/resolvers/github-resolver.js +46 -32
- package/dist/resolvers/github-resolver.js.map +1 -1
- package/dist/resolvers/npm-resolver.js +60 -52
- package/dist/resolvers/npm-resolver.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 0.5.10 - 2026-08-12
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- Remove resolver-owned npm and GitHub scratch directories after every audit, including failed resolutions. Large batch runs no longer exhaust runner inodes under `/tmp/scorecard-work`.
|
|
5
|
+
|
|
6
|
+
## 0.5.9 - 2026-08-12
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `mcp-scorecard serve --http` — Streamable HTTP v2 stateless (`POST /mcp`, `GET /health`, no session id, loopback). Stdio remains the default.
|
|
10
|
+
|
|
1
11
|
## 0.5.8 - 2026-08-12
|
|
2
12
|
|
|
3
13
|
### Changed
|
package/README.md
CHANGED
|
@@ -36,8 +36,18 @@ npx -y mcp-scorecard my-mcp --min-score 80
|
|
|
36
36
|
|
|
37
37
|
# Structured JSON for piping into your own tooling
|
|
38
38
|
npx -y mcp-scorecard my-mcp --json
|
|
39
|
+
|
|
40
|
+
# Run scorecard itself as an MCP server (stdio default)
|
|
41
|
+
npx -y mcp-scorecard serve
|
|
42
|
+
|
|
43
|
+
# Same server on Streamable HTTP — v2 stateless, loopback only
|
|
44
|
+
npx -y mcp-scorecard serve --http
|
|
45
|
+
# GET http://127.0.0.1:3000/health
|
|
46
|
+
# POST http://127.0.0.1:3000/mcp (sessionless)
|
|
39
47
|
```
|
|
40
48
|
|
|
49
|
+
Env for HTTP: `MCP_SCORECARD_HOST`, `MCP_SCORECARD_PORT`, `MCP_SCORECARD_TRANSPORT=http`.
|
|
50
|
+
|
|
41
51
|
## Demo
|
|
42
52
|
|
|
43
53
|
Real captured run auditing the official MCP reference server
|
package/dist/cli/commands.js
CHANGED
|
@@ -24,7 +24,8 @@ const USAGE = `mcp-scorecard v${SERVER_VERSION}
|
|
|
24
24
|
|
|
25
25
|
Usage:
|
|
26
26
|
mcp-scorecard <subject> [--json|--badge|--html] [--profile P] [--baseline f.json] [--min-score N]
|
|
27
|
-
mcp-scorecard serve run AS an MCP server (agents can call the 'audit' tool)
|
|
27
|
+
mcp-scorecard serve run AS an MCP server over stdio (agents can call the 'audit' tool)
|
|
28
|
+
mcp-scorecard serve --http same server on Streamable HTTP (v2 stateless, loopback /mcp)
|
|
28
29
|
mcp-scorecard compare a b c audit several subjects, print a side-by-side table
|
|
29
30
|
|
|
30
31
|
Subjects:
|
|
@@ -105,13 +106,20 @@ async function resolveSubject(subject) {
|
|
|
105
106
|
async function auditSubject(subject) {
|
|
106
107
|
if (isWebTarget(subject))
|
|
107
108
|
return runWebAudit(subject);
|
|
108
|
-
|
|
109
|
+
const target = await resolveSubject(subject);
|
|
110
|
+
try {
|
|
111
|
+
return await runAudit(target);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
target.cleanup?.();
|
|
115
|
+
}
|
|
109
116
|
}
|
|
110
117
|
export async function run(argv) {
|
|
111
118
|
// `serve` → run mcp-scorecard itself AS an MCP server (agents call the audit tool).
|
|
112
119
|
if (argv[0] === 'serve') {
|
|
113
120
|
const { serve } = await import('../mcp-server.js');
|
|
114
|
-
|
|
121
|
+
const http = argv.includes('--http') || process.env.MCP_SCORECARD_TRANSPORT === 'http';
|
|
122
|
+
await serve({ transport: http ? 'http' : 'stdio' });
|
|
115
123
|
// Keep the process alive for the stdio transport (the CLI entry would
|
|
116
124
|
// otherwise process.exit() as soon as run() resolves).
|
|
117
125
|
await new Promise(() => { });
|
package/dist/cli/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,sFAAsF;AACtF,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEjH,MAAM,KAAK,GAAG,kBAAkB,cAAc
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* same string. Bumping this without updating package.json is intentional during
|
|
4
4
|
* dev (keep src as source of truth); a release script can sync them.
|
|
5
5
|
*/
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const SERVER_NAME = "mcp-scorecard";
|
|
7
|
+
export declare const SERVER_VERSION = "0.5.10";
|
|
7
8
|
/** Identifier used when the probe connects to a target MCP server. */
|
|
8
9
|
export declare const PROBE_CLIENT_NAME = "mcp-scorecard";
|
|
9
10
|
/** Env var set on the spawned target so MCP authors can detect we are probing
|
package/dist/constants.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* same string. Bumping this without updating package.json is intentional during
|
|
4
4
|
* dev (keep src as source of truth); a release script can sync them.
|
|
5
5
|
*/
|
|
6
|
-
export const
|
|
6
|
+
export const SERVER_NAME = "mcp-scorecard";
|
|
7
|
+
export const SERVER_VERSION = "0.5.10";
|
|
7
8
|
/** Identifier used when the probe connects to a target MCP server. */
|
|
8
9
|
export const PROBE_CLIENT_NAME = 'mcp-scorecard';
|
|
9
10
|
/** Env var set on the spawned target so MCP authors can detect we are probing
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEvC,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;iEACiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAa;IACzC,2RAA2R;CAC5R,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU;IACV,mBAAmB;IACnB,sBAAsB;IACtB,sBAAsB;IACtB,iBAAiB;IACjB,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,mBAAmB;CACpB,CAAC;AAEF;;cAEc;AACd,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa;IACb,OAAO;IACP,OAAO;IACP,cAAc;IACd,eAAe;IACf,eAAe;IACf,iBAAiB;IACjB,SAAS;CACV,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamable HTTP v2 stateless transport — same contract as garmin-mcp:
|
|
3
|
+
* no session id, JSON responses, new MCP server per POST, loopback default.
|
|
4
|
+
*/
|
|
5
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
6
|
+
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
7
|
+
export type HttpV2Options = {
|
|
8
|
+
name: string;
|
|
9
|
+
version: string;
|
|
10
|
+
createServer: () => Server;
|
|
11
|
+
host?: string;
|
|
12
|
+
port?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function handleHttpV2Request(options: HttpV2Options, req: IncomingMessage, res: ServerResponse, body?: unknown): Promise<void>;
|
|
15
|
+
export declare function listenHttpV2(options: HttpV2Options): Promise<{
|
|
16
|
+
url: string;
|
|
17
|
+
close: () => Promise<void>;
|
|
18
|
+
}>;
|
package/dist/http-v2.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamable HTTP v2 stateless transport — same contract as garmin-mcp:
|
|
3
|
+
* no session id, JSON responses, new MCP server per POST, loopback default.
|
|
4
|
+
*/
|
|
5
|
+
import { createServer } from "node:http";
|
|
6
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
7
|
+
function readJsonBody(req) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const chunks = [];
|
|
10
|
+
req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
11
|
+
req.on("end", () => {
|
|
12
|
+
if (chunks.length === 0) {
|
|
13
|
+
resolve(undefined);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
reject(error);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
req.on("error", reject);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function handleHttpV2Request(options, req, res, body) {
|
|
27
|
+
const url = new URL(req.url ?? "/", `http://${options.host ?? "127.0.0.1"}`);
|
|
28
|
+
if (req.method === "GET" && url.pathname === "/health") {
|
|
29
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
30
|
+
res.end(JSON.stringify({ ok: true, name: options.name, version: options.version }));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (req.method === "POST" && url.pathname === "/mcp") {
|
|
34
|
+
const server = options.createServer();
|
|
35
|
+
const transport = new StreamableHTTPServerTransport({
|
|
36
|
+
sessionIdGenerator: undefined,
|
|
37
|
+
enableJsonResponse: true
|
|
38
|
+
});
|
|
39
|
+
res.on("close", () => {
|
|
40
|
+
transport.close().catch(() => undefined);
|
|
41
|
+
server.close().catch(() => undefined);
|
|
42
|
+
});
|
|
43
|
+
await server.connect(transport);
|
|
44
|
+
await transport.handleRequest(req, res, body);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
res.writeHead(404, { "content-type": "application/json" });
|
|
48
|
+
res.end(JSON.stringify({ error: "not found" }));
|
|
49
|
+
}
|
|
50
|
+
export function listenHttpV2(options) {
|
|
51
|
+
const host = options.host ?? "127.0.0.1";
|
|
52
|
+
const port = options.port ?? 3000;
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const httpServer = createServer((req, res) => {
|
|
55
|
+
const run = async () => {
|
|
56
|
+
const body = req.method === "POST" ? await readJsonBody(req) : undefined;
|
|
57
|
+
await handleHttpV2Request({ ...options, host }, req, res, body);
|
|
58
|
+
};
|
|
59
|
+
run().catch((error) => {
|
|
60
|
+
console.error("MCP HTTP request failed:", error);
|
|
61
|
+
if (!res.headersSent) {
|
|
62
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
63
|
+
res.end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32603, message: "Internal server error" }, id: null }));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
httpServer.on("error", reject);
|
|
68
|
+
httpServer.listen(port, host, () => {
|
|
69
|
+
const addr = httpServer.address();
|
|
70
|
+
const bound = typeof addr === "object" && addr ? addr.port : port;
|
|
71
|
+
resolve({
|
|
72
|
+
url: `http://${host}:${bound}`,
|
|
73
|
+
close: () => new Promise((done, fail) => {
|
|
74
|
+
httpServer.close((err) => (err ? fail(err) : done()));
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=http-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-v2.js","sourceRoot":"","sources":["../src/http-v2.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MCP server mode — exposes mcp-scorecard itself as an MCP server so an agent
|
|
3
|
+
* can call the `audit` tool mid-task (e.g. to vet a server before installing it).
|
|
4
|
+
* An MCP that scores MCPs. Run with: `mcp-scorecard serve`.
|
|
5
|
+
*
|
|
6
|
+
* Uses the low-level Server + setRequestHandler API with a plain JSON-Schema
|
|
7
|
+
* tool definition (no zod shape) to stay decoupled from the SDK's zod version.
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
export declare function createScorecardServer(): Server;
|
|
11
|
+
export declare function serve(options?: {
|
|
12
|
+
transport?: "stdio" | "http";
|
|
13
|
+
}): Promise<void>;
|
package/dist/mcp-server.js
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
10
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
11
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
-
import { SERVER_VERSION } from './constants.js';
|
|
12
|
+
import { SERVER_NAME, SERVER_VERSION } from './constants.js';
|
|
13
|
+
import { listenHttpV2 } from './http-v2.js';
|
|
13
14
|
import { runAudit } from './audit/runner.js';
|
|
14
15
|
import { runWebAudit } from './audit/web/web-runner.js';
|
|
15
16
|
import { resolveGithubRepo } from './resolvers/github-resolver.js';
|
|
@@ -71,10 +72,15 @@ async function auditTarget(target) {
|
|
|
71
72
|
else {
|
|
72
73
|
resolved = await resolveNpmPackage(target);
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
+
try {
|
|
76
|
+
return await runAudit(resolved);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
resolved.cleanup?.();
|
|
80
|
+
}
|
|
75
81
|
}
|
|
76
|
-
export
|
|
77
|
-
const server = new Server({ name:
|
|
82
|
+
export function createScorecardServer() {
|
|
83
|
+
const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} } });
|
|
78
84
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
79
85
|
tools: [
|
|
80
86
|
{
|
|
@@ -118,6 +124,24 @@ export async function serve() {
|
|
|
118
124
|
};
|
|
119
125
|
}
|
|
120
126
|
});
|
|
127
|
+
return server;
|
|
128
|
+
}
|
|
129
|
+
export async function serve(options) {
|
|
130
|
+
const transport = options?.transport ?? "stdio";
|
|
131
|
+
if (transport === "http") {
|
|
132
|
+
const host = process.env.MCP_SCORECARD_HOST ?? "127.0.0.1";
|
|
133
|
+
const port = Number(process.env.MCP_SCORECARD_PORT ?? 3000);
|
|
134
|
+
const { url } = await listenHttpV2({
|
|
135
|
+
name: SERVER_NAME,
|
|
136
|
+
version: SERVER_VERSION,
|
|
137
|
+
createServer: createScorecardServer,
|
|
138
|
+
host,
|
|
139
|
+
port
|
|
140
|
+
});
|
|
141
|
+
console.error(`mcp-scorecard MCP server v${SERVER_VERSION} running (http v2 stateless) — ${url}/mcp`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const server = createScorecardServer();
|
|
121
145
|
await server.connect(new StdioServerTransport());
|
|
122
146
|
console.error(`mcp-scorecard MCP server v${SERVER_VERSION} running (stdio) — tool: audit`);
|
|
123
147
|
}
|
package/dist/mcp-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* never published.
|
|
8
8
|
*/
|
|
9
9
|
import { spawnSync } from 'node:child_process';
|
|
10
|
-
import { existsSync, mkdirSync, mkdtempSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
11
11
|
import { join, resolve as pathResolve } from 'node:path';
|
|
12
12
|
import { resolveNpmPackage } from './npm-resolver.js';
|
|
13
13
|
const SCRATCH_ROOT = '/tmp/scorecard-work';
|
|
@@ -25,41 +25,55 @@ export async function resolveGithubRepo(url) {
|
|
|
25
25
|
if (!existsSync(SCRATCH_ROOT))
|
|
26
26
|
mkdirSync(SCRATCH_ROOT, { recursive: true });
|
|
27
27
|
const dest = mkdtempSync(join(SCRATCH_ROOT, 'gh-'));
|
|
28
|
+
const cleanup = () => rmSync(dest, { recursive: true, force: true });
|
|
28
29
|
const cloneDir = join(dest, parsed.repo);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
try {
|
|
31
|
+
const gh = spawnSync('gh', ['repo', 'clone', `${parsed.owner}/${parsed.repo}`, cloneDir, '--', '--depth=1'], {
|
|
32
|
+
encoding: 'utf8'
|
|
33
|
+
});
|
|
34
|
+
if (gh.status !== 0) {
|
|
35
|
+
throw new Error(`gh repo clone failed for ${parsed.owner}/${parsed.repo}: ${gh.stderr}`);
|
|
36
|
+
}
|
|
37
|
+
const pkgJsonPath = join(cloneDir, 'package.json');
|
|
38
|
+
if (!existsSync(pkgJsonPath)) {
|
|
39
|
+
throw new Error(`Cloned repo has no package.json: ${pkgJsonPath}`);
|
|
40
|
+
}
|
|
41
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
42
|
+
// Prefer auditing the published npm package — that's what agents actually
|
|
43
|
+
// pull via `npx -y <name>`. Falls back to local dist if npm pack fails.
|
|
44
|
+
if (typeof pkg.name === 'string') {
|
|
45
|
+
try {
|
|
46
|
+
const resolved = await resolveNpmPackage(pkg.name);
|
|
47
|
+
const cleanupNpm = resolved.cleanup;
|
|
48
|
+
resolved.cleanup = () => {
|
|
49
|
+
cleanupNpm?.();
|
|
50
|
+
cleanup();
|
|
51
|
+
};
|
|
52
|
+
return resolved;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// package not published — try local dist
|
|
56
|
+
}
|
|
45
57
|
}
|
|
46
|
-
|
|
47
|
-
|
|
58
|
+
const localBin = pathResolve(cloneDir, (pkg.bin && typeof pkg.bin === 'object'
|
|
59
|
+
? (Object.values(pkg.bin)[0] ?? 'dist/index.js')
|
|
60
|
+
: (typeof pkg.bin === 'string' ? pkg.bin : 'dist/index.js')));
|
|
61
|
+
if (!existsSync(localBin)) {
|
|
62
|
+
throw new Error(`No published npm package and no local bin at ${localBin}. Run \`npm run build\` in the repo first.`);
|
|
48
63
|
}
|
|
64
|
+
return {
|
|
65
|
+
displayName: pkg.name ?? `${parsed.owner}/${parsed.repo}`,
|
|
66
|
+
version: pkg.version,
|
|
67
|
+
command: 'node',
|
|
68
|
+
args: [localBin],
|
|
69
|
+
packageDir: cloneDir,
|
|
70
|
+
packageJson: pkg,
|
|
71
|
+
cleanup
|
|
72
|
+
};
|
|
49
73
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!existsSync(localBin)) {
|
|
54
|
-
throw new Error(`No published npm package and no local bin at ${localBin}. Run \`npm run build\` in the repo first.`);
|
|
74
|
+
catch (err) {
|
|
75
|
+
cleanup();
|
|
76
|
+
throw err;
|
|
55
77
|
}
|
|
56
|
-
return {
|
|
57
|
-
displayName: pkg.name ?? `${parsed.owner}/${parsed.repo}`,
|
|
58
|
-
version: pkg.version,
|
|
59
|
-
command: 'node',
|
|
60
|
-
args: [localBin],
|
|
61
|
-
packageDir: cloneDir,
|
|
62
|
-
packageJson: pkg
|
|
63
|
-
};
|
|
64
78
|
}
|
|
65
79
|
//# sourceMappingURL=github-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-resolver.js","sourceRoot":"","sources":["../../src/resolvers/github-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"github-resolver.js","sourceRoot":"","sources":["../../src/resolvers/github-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - uses --no-fund --no-audit to keep output clean and avoid any phone-home.
|
|
9
9
|
*/
|
|
10
10
|
import { spawnSync } from 'node:child_process';
|
|
11
|
-
import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
11
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join, resolve as pathResolve } from 'node:path';
|
|
14
14
|
const SCRATCH_ROOT = '/tmp/scorecard-work';
|
|
@@ -42,59 +42,67 @@ function pickBin(pkg) {
|
|
|
42
42
|
export async function resolveNpmPackage(spec) {
|
|
43
43
|
const scratch = ensureScratchRoot();
|
|
44
44
|
const dest = mkdtempSync(join(scratch, 'probe-'));
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!tarball)
|
|
54
|
-
throw new Error(`npm pack produced no .tgz under ${dest}`);
|
|
55
|
-
const tarPath = join(dest, tarball);
|
|
56
|
-
const extractDir = join(dest, 'pkg');
|
|
57
|
-
mkdirSync(extractDir, { recursive: true });
|
|
58
|
-
const tar = spawnSync('tar', ['xzf', tarPath, '-C', extractDir, '--strip-components=1'], {
|
|
59
|
-
encoding: 'utf8'
|
|
60
|
-
});
|
|
61
|
-
if (tar.status !== 0) {
|
|
62
|
-
throw new Error(`tar extract failed for ${tarPath}: ${tar.stderr}`);
|
|
63
|
-
}
|
|
64
|
-
const pkgJsonPath = join(extractDir, 'package.json');
|
|
65
|
-
if (!existsSync(pkgJsonPath)) {
|
|
66
|
-
throw new Error(`Extracted package has no package.json at ${pkgJsonPath}`);
|
|
67
|
-
}
|
|
68
|
-
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
69
|
-
// Install production deps inside the extracted tarball so the launched
|
|
70
|
-
// binary can `import` its declared dependencies. We skip devDeps,
|
|
71
|
-
// scripts, fund/audit chatter, and any postinstall side-effects.
|
|
72
|
-
const hasDeps = pkg.dependencies && Object.keys(pkg.dependencies).length > 0;
|
|
73
|
-
if (hasDeps) {
|
|
74
|
-
const inst = spawnSync('npm', ['install', '--omit=dev', '--no-fund', '--no-audit', '--ignore-scripts', '--no-package-lock'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], cwd: extractDir });
|
|
75
|
-
if (inst.status !== 0) {
|
|
76
|
-
throw new Error(`npm install (prod deps) failed in ${extractDir}: ${inst.stderr || inst.stdout}`);
|
|
45
|
+
const cleanup = () => rmSync(dest, { recursive: true, force: true });
|
|
46
|
+
try {
|
|
47
|
+
const pack = spawnSync('npm', ['pack', spec, '--pack-destination', dest, '--no-fund', '--no-audit'], {
|
|
48
|
+
encoding: 'utf8',
|
|
49
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
50
|
+
});
|
|
51
|
+
if (pack.status !== 0) {
|
|
52
|
+
throw new Error(`npm pack failed for ${spec}: ${pack.stderr || pack.stdout}`);
|
|
77
53
|
}
|
|
54
|
+
const tarball = readdirSync(dest).find((f) => f.endsWith('.tgz'));
|
|
55
|
+
if (!tarball)
|
|
56
|
+
throw new Error(`npm pack produced no .tgz under ${dest}`);
|
|
57
|
+
const tarPath = join(dest, tarball);
|
|
58
|
+
const extractDir = join(dest, 'pkg');
|
|
59
|
+
mkdirSync(extractDir, { recursive: true });
|
|
60
|
+
const tar = spawnSync('tar', ['xzf', tarPath, '-C', extractDir, '--strip-components=1'], {
|
|
61
|
+
encoding: 'utf8'
|
|
62
|
+
});
|
|
63
|
+
if (tar.status !== 0) {
|
|
64
|
+
throw new Error(`tar extract failed for ${tarPath}: ${tar.stderr}`);
|
|
65
|
+
}
|
|
66
|
+
const pkgJsonPath = join(extractDir, 'package.json');
|
|
67
|
+
if (!existsSync(pkgJsonPath)) {
|
|
68
|
+
throw new Error(`Extracted package has no package.json at ${pkgJsonPath}`);
|
|
69
|
+
}
|
|
70
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
71
|
+
// Install production deps inside the extracted tarball so the launched
|
|
72
|
+
// binary can `import` its declared dependencies. We skip devDeps,
|
|
73
|
+
// scripts, fund/audit chatter, and any postinstall side-effects.
|
|
74
|
+
const hasDeps = pkg.dependencies && Object.keys(pkg.dependencies).length > 0;
|
|
75
|
+
if (hasDeps) {
|
|
76
|
+
const inst = spawnSync('npm', ['install', '--omit=dev', '--no-fund', '--no-audit', '--ignore-scripts', '--no-package-lock'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], cwd: extractDir });
|
|
77
|
+
if (inst.status !== 0) {
|
|
78
|
+
throw new Error(`npm install (prod deps) failed in ${extractDir}: ${inst.stderr || inst.stdout}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const binRel = pickBin(pkg);
|
|
82
|
+
if (!binRel) {
|
|
83
|
+
throw new Error(`Package ${pkg.name} has no bin or main — cannot launch.`);
|
|
84
|
+
}
|
|
85
|
+
const binAbs = pathResolve(extractDir, binRel);
|
|
86
|
+
if (!existsSync(binAbs)) {
|
|
87
|
+
throw new Error(`Resolved bin does not exist after extract: ${binAbs}`);
|
|
88
|
+
}
|
|
89
|
+
// Ensure it's a file, not a dir.
|
|
90
|
+
if (!statSync(binAbs).isFile()) {
|
|
91
|
+
throw new Error(`Resolved bin is not a file: ${binAbs}`);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
displayName: pkg.name,
|
|
95
|
+
version: pkg.version,
|
|
96
|
+
command: 'node',
|
|
97
|
+
args: [binAbs],
|
|
98
|
+
packageDir: extractDir,
|
|
99
|
+
packageJson: pkg,
|
|
100
|
+
cleanup
|
|
101
|
+
};
|
|
78
102
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
throw
|
|
82
|
-
}
|
|
83
|
-
const binAbs = pathResolve(extractDir, binRel);
|
|
84
|
-
if (!existsSync(binAbs)) {
|
|
85
|
-
throw new Error(`Resolved bin does not exist after extract: ${binAbs}`);
|
|
86
|
-
}
|
|
87
|
-
// Ensure it's a file, not a dir.
|
|
88
|
-
if (!statSync(binAbs).isFile()) {
|
|
89
|
-
throw new Error(`Resolved bin is not a file: ${binAbs}`);
|
|
103
|
+
catch (err) {
|
|
104
|
+
cleanup();
|
|
105
|
+
throw err;
|
|
90
106
|
}
|
|
91
|
-
return {
|
|
92
|
-
displayName: pkg.name,
|
|
93
|
-
version: pkg.version,
|
|
94
|
-
command: 'node',
|
|
95
|
-
args: [binAbs],
|
|
96
|
-
packageDir: extractDir,
|
|
97
|
-
packageJson: pkg
|
|
98
|
-
};
|
|
99
107
|
}
|
|
100
108
|
//# sourceMappingURL=npm-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-resolver.js","sourceRoot":"","sources":["../../src/resolvers/npm-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"npm-resolver.js","sourceRoot":"","sources":["../../src/resolvers/npm-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -57,6 +57,8 @@ export interface ResolvedTarget {
|
|
|
57
57
|
packageDir: string;
|
|
58
58
|
/** package.json contents, if any. */
|
|
59
59
|
packageJson?: Record<string, unknown>;
|
|
60
|
+
/** Release resolver-owned temporary files after the audit finishes. */
|
|
61
|
+
cleanup?: () => void;
|
|
60
62
|
}
|
|
61
63
|
export type CheckId = 'schema_validity' | 'tool_naming' | 'dense_series_caps' | 'privacy_modes' | 'mutation_gating' | 'agent_manifest' | 'smoke_test' | 'resources' | 'tool_descriptions' | 'annotations' | 'manifest_discoverability' | 'web_https' | 'web_security_headers' | 'web_auth_posture' | 'web_oauth_discovery' | 'web_llms_txt' | 'web_mcp_server_card' | 'web_agent_skills' | 'web_api_catalog' | 'web_robots_signals' | 'web_structured_data' | 'web_exposed_paths' | 'web_cors_posture';
|
|
62
64
|
/**
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsJH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAC7F,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-scorecard",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.10",
|
|
4
4
|
"mcpName": "io.github.davidmosiah/mcp-scorecard",
|
|
5
5
|
"description": "Grade any MCP server's agent-readiness in one command \u2014 stdio (10 protocol checks) AND hosted/remote servers (10 security + web agent-readiness checks). Open source, local-first, no credentials.",
|
|
6
6
|
"type": "module",
|
|
@@ -24,12 +24,14 @@
|
|
|
24
24
|
"dev": "tsx src/index.ts",
|
|
25
25
|
"test:checks": "node scripts/test-checks.mjs",
|
|
26
26
|
"test:self": "node scripts/smoke-self.mjs",
|
|
27
|
-
"test": "npm run typecheck && npm run build && npm run test:dense-series && npm run test:checks && npm run test:self && npm run test:web && npm run test:features",
|
|
27
|
+
"test": "npm run typecheck && npm run build && npm run test:dense-series && npm run test:checks && npm run test:self && npm run test:web && npm run test:features && npm run test:http-v2 && npm run test:scratch-cleanup",
|
|
28
|
+
"test:http-v2": "node scripts/http-v2-test.mjs",
|
|
28
29
|
"prepublishOnly": "npm test",
|
|
29
30
|
"test:web": "node scripts/test-web.mjs",
|
|
30
31
|
"test:features": "node scripts/test-features.mjs",
|
|
31
32
|
"gen:checks": "node scripts/gen-checks-page.mjs",
|
|
32
|
-
"test:dense-series": "node scripts/dense-series-caps-test.mjs"
|
|
33
|
+
"test:dense-series": "node scripts/dense-series-caps-test.mjs",
|
|
34
|
+
"test:scratch-cleanup": "node scripts/scratch-cleanup-test.mjs"
|
|
33
35
|
},
|
|
34
36
|
"keywords": [
|
|
35
37
|
"mcp",
|