mcp-scorecard 0.2.0 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ - **Run AS an MCP server** (`mcp-scorecard serve`): exposes an `audit` tool so agents can score any MCP server mid-task — an MCP that scores MCPs. Add to a client: `{"command":"npx","args":["-y","mcp-scorecard","serve"]}`.
6
+ - **Letter grade (A–F) + `--badge`**: `npx mcp-scorecard <t> --badge` emits a shields.io markdown badge for your README.
7
+ - **Top fixes**: the markdown report now leads with the 3 changes that gain the most points.
8
+ - **Deeper web security checks** (web mode, now 12 checks): exposed `/.git` and `/.env` detection (content-verified, no SPA false positives) and CORS posture (flags wildcard/reflected origin + credentials).
9
+ - GitHub Action (`action.yml`) to gate CI on a minimum score.
10
+
11
+
12
+
3
13
  ## 0.2.0
4
14
 
5
15
  - **Web mode**: audit hosted/remote MCP servers + sites by URL (`npx -y mcp-scorecard https://your-server`). Adds 10 security + agent-readiness checks: HTTPS/TLS, security headers, auth posture, OAuth discovery, llms.txt, MCP Server Card (SEP-1649), Agent Skills index, API catalog (RFC 9727), robots + AI/Content-Signal, structured metadata (JSON-LD / OG / Markdown-for-Agents). The stdio path (10 protocol-quality checks) is unchanged.
package/README.md CHANGED
@@ -229,3 +229,22 @@ production agent.
229
229
  ## License
230
230
 
231
231
  MIT - see [LICENSE](LICENSE).
232
+
233
+ ---
234
+
235
+ ## New in v0.3.0 — differentiators
236
+
237
+ - **Run it AS an MCP server** so agents can call it mid-task:
238
+ ```json
239
+ { "mcpServers": { "mcp-scorecard": { "command": "npx", "args": ["-y", "mcp-scorecard", "serve"] } } }
240
+ ```
241
+ Then your agent can `audit("some-mcp-server")` before installing it. *An MCP that scores MCPs.*
242
+ - **Audit hosted/remote servers** by URL (12 security + agent-readiness checks): `npx -y mcp-scorecard https://your-server`
243
+ - **Badge for your README:** `npx -y mcp-scorecard my-mcp --badge` → a shields.io markdown badge.
244
+ - **GitHub Action:**
245
+ ```yaml
246
+ - uses: davidmosiah/mcp-scorecard@v0.3.0
247
+ with:
248
+ target: dist/index.js
249
+ min-score: 80
250
+ ```
@@ -6,6 +6,7 @@
6
6
  * with a synthetic detail entry rather than crashing the audit.
7
7
  */
8
8
  import { SERVER_VERSION } from '../constants.js';
9
+ import { toGrade } from '../types.js';
9
10
  import { checkAgentManifest } from './checks/agent-manifest.js';
10
11
  import { checkAnnotations } from './checks/annotations.js';
11
12
  import { checkManifestDiscoverability } from './checks/manifest-discoverability.js';
@@ -61,6 +62,7 @@ export async function runAudit(target) {
61
62
  safeRun('annotations', () => checkAnnotations(snapshot)),
62
63
  safeRun('manifest_discoverability', () => checkManifestDiscoverability(snapshot))
63
64
  ];
65
+ const totalScore = aggregateScore(checks);
64
66
  return {
65
67
  target: {
66
68
  displayName: target.displayName,
@@ -68,7 +70,9 @@ export async function runAudit(target) {
68
70
  serverName: snapshot.serverInfo.name,
69
71
  serverVersion: snapshot.serverInfo.version
70
72
  },
71
- totalScore: aggregateScore(checks),
73
+ totalScore,
74
+ grade: toGrade(totalScore),
75
+ mode: 'stdio',
72
76
  checks,
73
77
  generatedAt: new Date().toISOString(),
74
78
  scorecardVersion: SERVER_VERSION
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/audit/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/audit/runner.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@ export function aggregateScore(checks) {
11
11
  // Use the expected denominator (10 checks * 10 each = 100); if a check
12
12
  // failed to even run, we still divide by 10 so the score reflects gaps.
13
13
  const sum = checks.reduce((acc, c) => acc + Math.max(0, Math.min(10, c.score)), 0);
14
- const denom = EXPECTED_CHECK_COUNT * 10;
14
+ const denom = checks.length * 10; // supports stdio (10) + web (12) modes
15
15
  return Math.round((sum / denom) * 100);
16
16
  }
17
17
  //# sourceMappingURL=scorer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../src/audit/scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,oBAAoB,GAAG,EAAE,CAAC;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../src/audit/scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,uCAAuC;IACzE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;AACzC,CAAC"}
@@ -23,7 +23,13 @@ export function scoreWeb(p) {
23
23
  mk('web_agent_skills', 'Agent Skills index', p.agentSkills ? 10 : 0, p.agentSkills ? '/.well-known/agent-skills/index.json present' : 'Agent Skills discovery index missing', p.agentSkills ? [] : ['Publish /.well-known/agent-skills/index.json (Agent Skills Discovery RFC) listing your skills.']),
24
24
  mk('web_api_catalog', 'API catalog (RFC 9727)', p.apiCatalog ? 10 : 0, p.apiCatalog ? '/.well-known/api-catalog present' : 'API catalog missing', p.apiCatalog ? [] : ['Publish /.well-known/api-catalog (application/linkset+json) pointing to your OpenAPI / docs / status.']),
25
25
  mk('web_robots_signals', 'robots + AI signals', (p.robotsTxt ? 4 : 0) + (p.aiBotRules ? 2 : 0) + (p.contentSignal ? 2 : 0) + (p.sitemap ? 2 : 0), `robots:${p.robotsTxt ? 'y' : 'n'} ai-bots:${p.aiBotRules ? 'y' : 'n'} content-signal:${p.contentSignal ? 'y' : 'n'} sitemap:${p.sitemap ? 'y' : 'n'}`, (p.robotsTxt && p.aiBotRules && p.contentSignal && p.sitemap) ? [] : ['robots.txt with explicit AI-bot rules + a Content-Signal directive + a Sitemap line.']),
26
- mk('web_structured_data', 'Structured metadata', (p.jsonLd ? 4 : 0) + (p.ogTags ? 3 : 0) + (p.markdownNegotiation ? 3 : 0), `json-ld:${p.jsonLd ? 'y' : 'n'} og:${p.ogTags ? 'y' : 'n'} markdown-for-agents:${p.markdownNegotiation ? 'y' : 'n'}`, (p.jsonLd && p.ogTags && p.markdownNegotiation) ? [] : ['Add JSON-LD (schema.org), OpenGraph tags, and Markdown-for-Agents (Accept: text/markdown).'])
26
+ mk('web_structured_data', 'Structured metadata', (p.jsonLd ? 4 : 0) + (p.ogTags ? 3 : 0) + (p.markdownNegotiation ? 3 : 0), `json-ld:${p.jsonLd ? 'y' : 'n'} og:${p.ogTags ? 'y' : 'n'} markdown-for-agents:${p.markdownNegotiation ? 'y' : 'n'}`, (p.jsonLd && p.ogTags && p.markdownNegotiation) ? [] : ['Add JSON-LD (schema.org), OpenGraph tags, and Markdown-for-Agents (Accept: text/markdown).']),
27
+ mk('web_exposed_paths', 'No exposed secrets', (p.gitExposed || p.envExposed) ? 0 : 10, (p.gitExposed || p.envExposed)
28
+ ? `CRITICAL: ${[p.gitExposed && '/.git/config', p.envExposed && '/.env'].filter(Boolean).join(' + ')} is publicly readable`
29
+ : 'no /.git or /.env exposed' + (p.securityTxt ? ' (+ security.txt present)' : ''), (p.gitExposed || p.envExposed) ? ['URGENT: block public access to /.git and /.env — they leak source history and credentials.'] : []),
30
+ mk('web_cors_posture', 'CORS posture', (p.corsAllowCredentials && (p.corsAllowOrigin === '*' || /mcp-scorecard\.test/.test(p.corsAllowOrigin || ''))) ? 2 : 10, (p.corsAllowCredentials && (p.corsAllowOrigin === '*' || /mcp-scorecard\.test/.test(p.corsAllowOrigin || '')))
31
+ ? 'DANGEROUS: credentials allowed with wildcard/reflected origin'
32
+ : `safe (allow-origin: ${p.corsAllowOrigin ?? 'none'}, credentials: ${p.corsAllowCredentials})`, (p.corsAllowCredentials && (p.corsAllowOrigin === '*' || /mcp-scorecard\.test/.test(p.corsAllowOrigin || ''))) ? ['Never combine Access-Control-Allow-Credentials:true with a wildcard or reflected Access-Control-Allow-Origin.'] : [])
27
33
  ];
28
34
  }
29
35
  //# sourceMappingURL=web-checks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-checks.js","sourceRoot":"","sources":["../../../src/audit/web/web-checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-checks.js","sourceRoot":"","sources":["../../../src/audit/web/web-checks.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,13 @@ async function get(url, opts = {}) {
3
3
  const ctrl = new AbortController();
4
4
  const t = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 8000);
5
5
  try {
6
+ const headersIn = { 'user-agent': UA, accept: opts.accept ?? '*/*' };
7
+ if (opts.origin)
8
+ headersIn['origin'] = opts.origin;
6
9
  const res = await fetch(url, {
7
10
  signal: ctrl.signal,
8
11
  redirect: 'follow',
9
- headers: { 'user-agent': UA, accept: opts.accept ?? '*/*' }
12
+ headers: headersIn
10
13
  });
11
14
  const headers = {};
12
15
  res.headers.forEach((v, k) => { headers[k.toLowerCase()] = v; });
@@ -29,7 +32,7 @@ export async function fetchWebProbe(rawUrl) {
29
32
  const base = rawUrl.replace(/\/+$/, '');
30
33
  const u = new URL(base);
31
34
  const at = (p) => `${u.origin}${p}`;
32
- const [root, llms, robots, card, skills, apiCat, sitemap, oauthPR, oauthAS, authMd, mdNeg] = await Promise.all([
35
+ const [root, llms, robots, card, skills, apiCat, sitemap, oauthPR, oauthAS, authMd, mdNeg, gitCfg, envFile, secTxt, corsProbe] = await Promise.all([
33
36
  get(base + '/'),
34
37
  get(at('/llms.txt')),
35
38
  get(at('/robots.txt')),
@@ -40,8 +43,18 @@ export async function fetchWebProbe(rawUrl) {
40
43
  get(at('/.well-known/oauth-protected-resource')),
41
44
  get(at('/.well-known/oauth-authorization-server')),
42
45
  get(at('/auth.md')),
43
- get(base + '/', { accept: 'text/markdown' })
46
+ get(base + '/', { accept: 'text/markdown' }),
47
+ get(at('/.git/config')),
48
+ get(at('/.env')),
49
+ get(at('/.well-known/security.txt')),
50
+ get(base + '/', { origin: 'https://mcp-scorecard.test' })
44
51
  ]);
52
+ // Verify CONTENT (not just 200) — SPAs/CDNs return 200 + index.html for any path.
53
+ const gitExposed = ok(gitCfg) && /\[core\]|repositoryformatversion/i.test(gitCfg.text) && !/<html/i.test(gitCfg.text);
54
+ const envExposed = ok(envFile) && /^[A-Z0-9_]+=/m.test(envFile.text) && !/<html/i.test(envFile.text);
55
+ const securityTxt = ok(secTxt) && /contact:/i.test(secTxt.text);
56
+ const corsAllowOrigin = corsProbe?.headers['access-control-allow-origin'] ?? null;
57
+ const corsAllowCredentials = (corsProbe?.headers['access-control-allow-credentials'] ?? '').toLowerCase() === 'true';
45
58
  const robotsText = ok(robots) ? robots.text.toLowerCase() : '';
46
59
  const rootHtml = ok(root) ? root.text : '';
47
60
  let serverCardValid = false;
@@ -72,7 +85,12 @@ export async function fetchWebProbe(rawUrl) {
72
85
  authMd: ok(authMd) && /auth\.md/i.test(authMd.text),
73
86
  jsonLd: /application\/ld\+json/i.test(rootHtml),
74
87
  ogTags: /property=["']og:/i.test(rootHtml),
75
- markdownNegotiation: !!mdNeg && (mdNeg.headers['content-type'] || '').includes('text/markdown')
88
+ markdownNegotiation: !!mdNeg && (mdNeg.headers['content-type'] || '').includes('text/markdown'),
89
+ gitExposed,
90
+ envExposed,
91
+ securityTxt,
92
+ corsAllowOrigin,
93
+ corsAllowCredentials
76
94
  };
77
95
  }
78
96
  //# sourceMappingURL=web-probe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-probe.js","sourceRoot":"","sources":["../../../src/audit/web/web-probe.ts"],"names":[],"mappings":"AAOA,MAAM,EAAE,GAAG,uDAAuD,CAAC;AAEnE,KAAK,UAAU,GAAG,CAAC,GAAW,EAAE,OAAgD,EAAE;IAChF,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE;SAC5D,CAAC,CAAC;QACH,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAC/D,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,EAAE,GAAG,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAE5C,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7G,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;QACf,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;QACpB,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QACtB,GAAG,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC;QAC5C,GAAG,CAAC,EAAE,CAAC,sCAAsC,CAAC,CAAC;QAC/C,GAAG,CAAC,EAAE,CAAC,0BAA0B,CAAC,CAAC;QACnC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;QACvB,GAAG,CAAC,EAAE,CAAC,uCAAuC,CAAC,CAAC;QAChD,GAAG,CAAC,EAAE,CAAC,yCAAyC,CAAC,CAAC;QAClD,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACnB,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;KAC7C,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,MAAM,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5C,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACb,IAAI,CAAC;YAAC,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAK,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,eAAe,GAAG,KAAK,CAAC;QAAC,CAAC;IACpG,CAAC;IAED,OAAO;QACL,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAC9B,UAAU,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;QAC5B,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE;QAClD,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC;QACpB,eAAe;QACf,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC;QACvB,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC;QACtB,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC;QACrB,UAAU,EAAE,wEAAwE,CAAC,IAAI,CAAC,UAAU,CAAC;QACrG,aAAa,EAAE,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;QAChD,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;QACpB,sBAAsB,EAAE,EAAE,CAAC,OAAO,CAAC;QACnC,eAAe,EAAE,EAAE,CAAC,OAAO,CAAC;QAC5B,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC;QACpD,MAAM,EAAE,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/C,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC1C,mBAAmB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;KAChG,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"web-probe.js","sourceRoot":"","sources":["../../../src/audit/web/web-probe.ts"],"names":[],"mappings":"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"}
@@ -3,18 +3,19 @@
3
3
  * pure web checks, aggregate into the same AuditReport shape as the stdio path.
4
4
  */
5
5
  import { SERVER_VERSION } from '../../constants.js';
6
+ import { toGrade } from '../../types.js';
6
7
  import { aggregateScore } from '../scorer.js';
7
8
  import { fetchWebProbe } from './web-probe.js';
8
9
  import { scoreWeb } from './web-checks.js';
9
10
  export async function runWebAudit(url) {
10
11
  const probe = await fetchWebProbe(url);
11
12
  const checks = scoreWeb(probe);
13
+ const totalScore = aggregateScore(checks);
12
14
  return {
13
- target: {
14
- displayName: probe.url,
15
- serverName: probe.url
16
- },
17
- totalScore: aggregateScore(checks),
15
+ target: { displayName: probe.url, serverName: probe.url },
16
+ totalScore,
17
+ grade: toGrade(totalScore),
18
+ mode: 'web',
18
19
  checks,
19
20
  generatedAt: new Date().toISOString(),
20
21
  scorecardVersion: SERVER_VERSION
@@ -1 +1 @@
1
- {"version":3,"file":"web-runner.js","sourceRoot":"","sources":["../../../src/audit/web/web-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO;QACL,MAAM,EAAE;YACN,WAAW,EAAE,KAAK,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK,CAAC,GAAG;SACtB;QACD,UAAU,EAAE,cAAc,CAAC,MAAM,CAAC;QAClC,MAAM;QACN,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,gBAAgB,EAAE,cAAc;KACjC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"web-runner.js","sourceRoot":"","sources":["../../../src/audit/web/web-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,EAAE;QACzD,UAAU;QACV,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;QAC1B,IAAI,EAAE,KAAK;QACX,MAAM;QACN,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,gBAAgB,EAAE,cAAc;KACjC,CAAC;AACJ,CAAC"}
@@ -19,19 +19,22 @@ import { runWebAudit } from '../audit/web/web-runner.js';
19
19
  function isWebTarget(subject) {
20
20
  return /^https?:\/\//.test(subject) && !/github\.com/.test(subject);
21
21
  }
22
- import { renderJson, renderMarkdown } from './output.js';
22
+ import { renderBadge, renderJson, renderMarkdown } from './output.js';
23
23
  const USAGE = `mcp-scorecard v${SERVER_VERSION}
24
24
 
25
25
  Usage:
26
- mcp-scorecard <subject> [--json] [--min-score N]
26
+ mcp-scorecard <subject> [--json|--badge] [--min-score N]
27
+ mcp-scorecard serve run AS an MCP server (agents can call the 'audit' tool)
27
28
 
28
29
  Subjects:
29
30
  npm-package e.g. whoop-mcp-unofficial[@version]
30
31
  github-url e.g. https://github.com/davidmosiah/whoop-mcp
32
+ https://host a HOSTED/remote MCP server or site (web security + agent-readiness audit)
31
33
  /abs/path/dist/index.js built MCP server entry
32
34
 
33
35
  Flags:
34
36
  --json emit structured JSON to stdout
37
+ --badge emit a markdown shields.io badge (paste into your README)
35
38
  --min-score N exit non-zero if total score < N (default 0)
36
39
  --version print version
37
40
  --help, -h print this message
@@ -40,7 +43,7 @@ Privacy: the probe sets MCP_PROBE=1 so MCP authors can detect an audit and
40
43
  skip auth-only side effects. Probe responses are NEVER persisted; only
41
44
  counts and field names are recorded. See the README for the security model.`;
42
45
  function parseArgs(argv) {
43
- const out = { json: false, minScore: 0, help: false, showVersion: false };
46
+ const out = { json: false, badge: false, minScore: 0, help: false, showVersion: false };
44
47
  for (let i = 0; i < argv.length; i++) {
45
48
  const arg = argv[i];
46
49
  if (arg === '--help' || arg === '-h')
@@ -49,6 +52,8 @@ function parseArgs(argv) {
49
52
  out.showVersion = true;
50
53
  else if (arg === '--json')
51
54
  out.json = true;
55
+ else if (arg === '--badge')
56
+ out.badge = true;
52
57
  else if (arg === '--min-score') {
53
58
  const v = argv[++i];
54
59
  const n = Number.parseInt(v, 10);
@@ -81,6 +86,15 @@ async function resolveSubject(subject) {
81
86
  return resolveNpmPackage(subject);
82
87
  }
83
88
  export async function run(argv) {
89
+ // `serve` → run mcp-scorecard itself AS an MCP server (agents call the audit tool).
90
+ if (argv[0] === 'serve') {
91
+ const { serve } = await import('../mcp-server.js');
92
+ await serve();
93
+ // Keep the process alive for the stdio transport (the CLI entry would
94
+ // otherwise process.exit() as soon as run() resolves).
95
+ await new Promise(() => { });
96
+ return 0;
97
+ }
84
98
  let parsed;
85
99
  try {
86
100
  parsed = parseArgs(argv);
@@ -129,7 +143,7 @@ export async function run(argv) {
129
143
  return 1;
130
144
  }
131
145
  }
132
- process.stdout.write(parsed.json ? renderJson(report) : renderMarkdown(report));
146
+ process.stdout.write(parsed.badge ? renderBadge(report) : parsed.json ? renderJson(report) : renderMarkdown(report));
133
147
  process.stdout.write('\n');
134
148
  if (report.totalScore < parsed.minScore) {
135
149
  process.stderr.write(`\nScore ${report.totalScore} < --min-score ${parsed.minScore}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
@@ -10,4 +10,6 @@
10
10
  import type { AuditReport } from '../types.js';
11
11
  /** Markdown table-ish output suitable for terminals and PR comments. */
12
12
  export declare function renderMarkdown(report: AuditReport): string;
13
+ /** A shields.io badge (markdown) maintainers can paste into their README. */
14
+ export declare function renderBadge(report: AuditReport): string;
13
15
  export declare function renderJson(report: AuditReport): string;
@@ -26,11 +26,23 @@ export function renderMarkdown(report) {
26
26
  const versionTag = report.target.version ? ` @${report.target.version}` : '';
27
27
  lines.push(`# mcp-scorecard - ${report.target.displayName}${versionTag}`);
28
28
  lines.push('');
29
- lines.push(`**Agent-readiness score:** ${report.totalScore}/100`);
29
+ lines.push(`**Score: ${report.totalScore}/100 — grade ${report.grade}** · mode: \`${report.mode}\``);
30
30
  lines.push('');
31
31
  for (const c of report.checks) {
32
32
  lines.push(`- ${STATUS_ICON[c.status]} ${c.label.padEnd(28)} (${redact(c.summary)})`);
33
33
  }
34
+ // Top fixes: the lowest-scoring checks that have a remediation — biggest points first.
35
+ const top = report.checks
36
+ .filter((c) => c.fixes.length > 0 && c.score < 10)
37
+ .sort((a, b) => a.score - b.score)
38
+ .slice(0, 3);
39
+ if (top.length > 0) {
40
+ lines.push('');
41
+ lines.push('## Top fixes (most points to gain)');
42
+ for (const c of top) {
43
+ lines.push(`- **+${10 - c.score} pts · ${c.label}** — ${redact(c.fixes[0])}`);
44
+ }
45
+ }
34
46
  const detailLines = [];
35
47
  for (const c of report.checks) {
36
48
  if (c.details.length > 0) {
@@ -62,6 +74,14 @@ export function renderMarkdown(report) {
62
74
  lines.push(`_Generated by mcp-scorecard v${report.scorecardVersion} at ${report.generatedAt}_`);
63
75
  return lines.join('\n');
64
76
  }
77
+ /** A shields.io badge (markdown) maintainers can paste into their README. */
78
+ export function renderBadge(report) {
79
+ const color = report.grade === 'A' ? 'brightgreen' : report.grade === 'B' ? 'green'
80
+ : report.grade === 'C' ? 'yellow' : report.grade === 'D' ? 'orange' : 'red';
81
+ const msg = encodeURIComponent(`${report.totalScore}/100 (${report.grade})`);
82
+ const url = `https://img.shields.io/badge/mcp--scorecard-${msg}-${color}`;
83
+ return `[![mcp-scorecard: ${report.grade}](${url})](https://mcp-scorecard.vercel.app)`;
84
+ }
65
85
  export function renderJson(report) {
66
86
  // JSON output is also redacted at the string level so consumers don't
67
87
  // accidentally persist secrets from probed servers.
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,GAA0C;IACzD,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,MAAM,YAAY,GAAG,IAAI,MAAM,CAC7B,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,4BAA4B,EAChG,IAAI,CACL,CAAC;AAEF,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,UAAU,EAAE,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,8BAA8B,MAAM,CAAC,UAAU,MAAM,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,gCAAgC,MAAM,CAAC,gBAAgB,OAAO,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;IAChG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,GAAG,CAAC;QACJ,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1B,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAC7B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;KAC1B,CAAC,CAAC,CAAC;IACJ,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
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 SERVER_VERSION = "0.1.3";
6
+ export declare const SERVER_VERSION = "0.3.0";
7
7
  /** Identifier used when the probe connects to a target MCP server. */
8
8
  export declare const PROBE_CLIENT_NAME = "mcp-scorecard";
9
9
  /** Env var set on the spawned target so MCP authors can detect we are probing
package/dist/constants.js CHANGED
@@ -3,7 +3,7 @@
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 SERVER_VERSION = '0.1.3';
6
+ export const SERVER_VERSION = '0.3.0';
7
7
  /** Identifier used when the probe connects to a target MCP server. */
8
8
  export const PROBE_CLIENT_NAME = 'mcp-scorecard';
9
9
  /** Env var set on the spawned target so MCP authors can detect we are probing
@@ -0,0 +1 @@
1
+ export declare function serve(): Promise<void>;
@@ -0,0 +1,79 @@
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 { existsSync } from 'node:fs';
10
+ import { isAbsolute } from 'node:path';
11
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
14
+ import { SERVER_VERSION } from './constants.js';
15
+ import { runAudit } from './audit/runner.js';
16
+ import { runWebAudit } from './audit/web/web-runner.js';
17
+ import { resolveGithubRepo } from './resolvers/github-resolver.js';
18
+ import { resolveLocal } from './resolvers/local-resolver.js';
19
+ import { resolveNpmPackage } from './resolvers/npm-resolver.js';
20
+ async function auditTarget(target) {
21
+ if (/^https?:\/\//.test(target) && !/github\.com/.test(target)) {
22
+ return runWebAudit(target);
23
+ }
24
+ let resolved;
25
+ if (/^https?:\/\/github\.com\//.test(target) || target.startsWith('github:')) {
26
+ resolved = await resolveGithubRepo(target);
27
+ }
28
+ else if (isAbsolute(target) && existsSync(target)) {
29
+ resolved = await resolveLocal(target);
30
+ }
31
+ else {
32
+ resolved = await resolveNpmPackage(target);
33
+ }
34
+ return runAudit(resolved);
35
+ }
36
+ export async function serve() {
37
+ const server = new Server({ name: 'mcp-scorecard', version: SERVER_VERSION }, { capabilities: { tools: {} } });
38
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
39
+ tools: [
40
+ {
41
+ name: 'audit',
42
+ description: "Grade an MCP server's agent-readiness and security. Accepts an npm package name, a GitHub repo URL, a local dist path (→ stdio protocol-quality checks), or a hosted https:// URL (→ web security + agent-readiness checks). Returns a 0–100 score, an A–F grade, itemized checks, and actionable fixes.",
43
+ inputSchema: {
44
+ type: 'object',
45
+ properties: {
46
+ target: {
47
+ type: 'string',
48
+ description: 'npm package, GitHub URL, local dist path, or https:// hosted MCP server'
49
+ }
50
+ },
51
+ required: ['target']
52
+ }
53
+ }
54
+ ]
55
+ }));
56
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
57
+ if (req.params.name !== 'audit') {
58
+ return { content: [{ type: 'text', text: `unknown tool: ${req.params.name}` }], isError: true };
59
+ }
60
+ const target = String(req.params.arguments?.target ?? '').trim();
61
+ if (!target) {
62
+ return { content: [{ type: 'text', text: 'missing required argument: target' }], isError: true };
63
+ }
64
+ try {
65
+ const report = await auditTarget(target);
66
+ const summary = `${report.target.displayName}: ${report.totalScore}/100 (grade ${report.grade}, ${report.mode} mode)`;
67
+ return { content: [{ type: 'text', text: `${summary}\n\n${JSON.stringify(report, null, 2)}` }] };
68
+ }
69
+ catch (err) {
70
+ return {
71
+ content: [{ type: 'text', text: `audit failed for "${target}": ${err instanceof Error ? err.message : String(err)}` }],
72
+ isError: true
73
+ };
74
+ }
75
+ });
76
+ await server.connect(new StdioServerTransport());
77
+ console.error(`mcp-scorecard MCP server v${SERVER_VERSION} running (stdio) — tool: audit`);
78
+ }
79
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -57,7 +57,7 @@ export interface ResolvedTarget {
57
57
  /** package.json contents, if any. */
58
58
  packageJson?: Record<string, unknown>;
59
59
  }
60
- export type CheckId = 'schema_validity' | 'tool_naming' | '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';
60
+ export type CheckId = 'schema_validity' | 'tool_naming' | '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';
61
61
  /**
62
62
  * Snapshot captured from a hosted/remote target over HTTP — the parallel of
63
63
  * ProbeSnapshot for the web/security audit path. Pure scorers read this.
@@ -82,6 +82,11 @@ export interface WebProbe {
82
82
  jsonLd: boolean;
83
83
  ogTags: boolean;
84
84
  markdownNegotiation: boolean;
85
+ gitExposed: boolean;
86
+ envExposed: boolean;
87
+ securityTxt: boolean;
88
+ corsAllowOrigin: string | null;
89
+ corsAllowCredentials: boolean;
85
90
  }
86
91
  export interface CheckResult {
87
92
  id: CheckId;
@@ -103,7 +108,10 @@ export interface AuditReport {
103
108
  serverVersion?: string;
104
109
  };
105
110
  totalScore: number;
111
+ grade: 'A' | 'B' | 'C' | 'D' | 'F';
112
+ mode: 'stdio' | 'web';
106
113
  checks: CheckResult[];
107
114
  generatedAt: string;
108
115
  scorecardVersion: string;
109
116
  }
117
+ export declare function toGrade(score: number): 'A' | 'B' | 'C' | 'D' | 'F';
package/dist/types.js CHANGED
@@ -2,5 +2,7 @@
2
2
  * Shared types: the snapshot the probe captures and the shape of a check.
3
3
  * Kept deliberately minimal so the audit pipeline stays portable.
4
4
  */
5
- export {};
5
+ export function toGrade(score) {
6
+ return score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : score >= 60 ? 'D' : 'F';
7
+ }
6
8
  //# sourceMappingURL=types.js.map
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;AAkJH,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.2.0",
3
+ "version": "0.3.0",
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",