@kryptosai/mcp-observatory 0.27.0 → 1.28.1

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 (160) hide show
  1. package/COMMERCIAL.md +28 -2
  2. package/CONTRIBUTORS.md +39 -0
  3. package/README.md +114 -22
  4. package/dist/src/action-receipt.d.ts +20 -0
  5. package/dist/src/action-receipt.js +85 -0
  6. package/dist/src/action-receipt.js.map +1 -0
  7. package/dist/src/adapters/http.js +1 -5
  8. package/dist/src/adapters/http.js.map +1 -1
  9. package/dist/src/audit.d.ts +64 -0
  10. package/dist/src/audit.js +359 -0
  11. package/dist/src/audit.js.map +1 -0
  12. package/dist/src/cassette.js +3 -2
  13. package/dist/src/cassette.js.map +1 -1
  14. package/dist/src/checks/attack-sim.d.ts +20 -0
  15. package/dist/src/checks/attack-sim.js +316 -0
  16. package/dist/src/checks/attack-sim.js.map +1 -0
  17. package/dist/src/ci-issue.js +4 -3
  18. package/dist/src/ci-issue.js.map +1 -1
  19. package/dist/src/cli.js +25 -4
  20. package/dist/src/cli.js.map +1 -1
  21. package/dist/src/commands/attack-sim.d.ts +2 -0
  22. package/dist/src/commands/attack-sim.js +220 -0
  23. package/dist/src/commands/attack-sim.js.map +1 -0
  24. package/dist/src/commands/audit.d.ts +2 -0
  25. package/dist/src/commands/audit.js +132 -0
  26. package/dist/src/commands/audit.js.map +1 -0
  27. package/dist/src/commands/init-ci.d.ts +3 -0
  28. package/dist/src/commands/init-ci.js +78 -13
  29. package/dist/src/commands/init-ci.js.map +1 -1
  30. package/dist/src/commands/legacy.js +8 -1
  31. package/dist/src/commands/legacy.js.map +1 -1
  32. package/dist/src/commands/receipt.d.ts +2 -0
  33. package/dist/src/commands/receipt.js +113 -0
  34. package/dist/src/commands/receipt.js.map +1 -0
  35. package/dist/src/commands/scan.js +30 -6
  36. package/dist/src/commands/scan.js.map +1 -1
  37. package/dist/src/commands/score.js +63 -0
  38. package/dist/src/commands/score.js.map +1 -1
  39. package/dist/src/commands/serve.js +9 -1
  40. package/dist/src/commands/serve.js.map +1 -1
  41. package/dist/src/commands/setup-ci-conversion.d.ts +3 -1
  42. package/dist/src/commands/setup-ci-conversion.js +23 -8
  43. package/dist/src/commands/setup-ci-conversion.js.map +1 -1
  44. package/dist/src/commands/telemetry.js +20 -14
  45. package/dist/src/commands/telemetry.js.map +1 -1
  46. package/dist/src/commands/test.js +31 -2
  47. package/dist/src/commands/test.js.map +1 -1
  48. package/dist/src/findings.d.ts +1 -0
  49. package/dist/src/findings.js +42 -1
  50. package/dist/src/findings.js.map +1 -1
  51. package/dist/src/history.js +3 -2
  52. package/dist/src/history.js.map +1 -1
  53. package/dist/src/index.d.ts +4 -0
  54. package/dist/src/index.js +4 -0
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/integrations/smithery.js +5 -1
  57. package/dist/src/integrations/smithery.js.map +1 -1
  58. package/dist/src/receipt.d.ts +100 -0
  59. package/dist/src/receipt.js +375 -0
  60. package/dist/src/receipt.js.map +1 -0
  61. package/dist/src/reporters/attack-sim.d.ts +2 -0
  62. package/dist/src/reporters/attack-sim.js +89 -0
  63. package/dist/src/reporters/attack-sim.js.map +1 -0
  64. package/dist/src/reporters/pr-comment.js +20 -6
  65. package/dist/src/reporters/pr-comment.js.map +1 -1
  66. package/dist/src/reporters/sarif.js +11 -1
  67. package/dist/src/reporters/sarif.js.map +1 -1
  68. package/dist/src/runner.d.ts +3 -0
  69. package/dist/src/runner.js +5 -0
  70. package/dist/src/runner.js.map +1 -1
  71. package/dist/src/score.js +1 -1
  72. package/dist/src/score.js.map +1 -1
  73. package/dist/src/security-profiles.d.ts +13 -0
  74. package/dist/src/security-profiles.js +59 -0
  75. package/dist/src/security-profiles.js.map +1 -0
  76. package/dist/src/storage.js +3 -2
  77. package/dist/src/storage.js.map +1 -1
  78. package/dist/src/telemetry.d.ts +10 -0
  79. package/dist/src/telemetry.js +17 -1
  80. package/dist/src/telemetry.js.map +1 -1
  81. package/dist/src/types.d.ts +1 -1
  82. package/dist/src/utils/files.d.ts +1 -0
  83. package/dist/src/utils/files.js +21 -0
  84. package/dist/src/utils/files.js.map +1 -0
  85. package/dist/src/utils/ids.js +18 -5
  86. package/dist/src/utils/ids.js.map +1 -1
  87. package/dist/src/utils/url.d.ts +2 -0
  88. package/dist/src/utils/url.js +15 -0
  89. package/dist/src/utils/url.js.map +1 -0
  90. package/dist/src/validate.js +1 -1
  91. package/dist/src/validate.js.map +1 -1
  92. package/docs/10x-agentic-growth-sprint.md +47 -0
  93. package/docs/agent-ecosystem-promotion-plan.md +244 -0
  94. package/docs/agent-tasks.md +95 -0
  95. package/docs/agentic-contributor-outreach.md +52 -0
  96. package/docs/automatic-ci-integration.md +33 -0
  97. package/docs/campaign-attribution.md +58 -0
  98. package/docs/code-scanning-demo.md +57 -0
  99. package/docs/commercial-boundary.md +83 -0
  100. package/docs/contributor-proof-cards/README.md +33 -0
  101. package/docs/contributor-recognition.md +92 -0
  102. package/docs/examples/nsa-mcp-audit-report.md +372 -0
  103. package/docs/examples/nsa-mcp-results.sarif +930 -0
  104. package/docs/examples/nsa-mcp-score.json +13 -0
  105. package/docs/feishu-lark-mcp.md +1 -1
  106. package/docs/github-code-scanning-for-mcp.md +1 -1
  107. package/docs/government-enterprise-pilot.md +93 -0
  108. package/docs/launch.md +64 -0
  109. package/docs/mcp-attack-simulator.md +57 -0
  110. package/docs/mcp-receipts.md +109 -0
  111. package/docs/mcp-server-safety-index.md +29 -22
  112. package/docs/nsa-mcp-audit-ci.md +88 -0
  113. package/docs/procurement-one-pager.md +74 -0
  114. package/docs/proof.md +5 -2
  115. package/docs/public-guidance-crosswalk.md +48 -0
  116. package/docs/receipt-graph.md +54 -0
  117. package/docs/safety-index/artifacts/antv-chart-server.json +40 -22
  118. package/docs/safety-index/artifacts/antv-chart-server.md +22 -9
  119. package/docs/safety-index/artifacts/browsermcp-server.json +36 -18
  120. package/docs/safety-index/artifacts/browsermcp-server.md +22 -9
  121. package/docs/safety-index/artifacts/context7-server.json +83 -26
  122. package/docs/safety-index/artifacts/context7-server.md +33 -20
  123. package/docs/safety-index/artifacts/cyanheads-git-mcp-server.json +2438 -0
  124. package/docs/safety-index/artifacts/cyanheads-git-mcp-server.md +176 -0
  125. package/docs/safety-index/artifacts/everything-server.json +150 -57
  126. package/docs/safety-index/artifacts/everything-server.md +36 -23
  127. package/docs/safety-index/artifacts/executeautomation-playwright-server.json +162 -19
  128. package/docs/safety-index/artifacts/executeautomation-playwright-server.md +25 -12
  129. package/docs/safety-index/artifacts/filesystem-server.json +221 -19
  130. package/docs/safety-index/artifacts/filesystem-server.md +24 -11
  131. package/docs/safety-index/artifacts/kubernetes-server.attack.json +1559 -0
  132. package/docs/safety-index/artifacts/kubernetes-server.attack.md +43 -0
  133. package/docs/safety-index/artifacts/kubernetes-server.attack.sarif +2857 -0
  134. package/docs/safety-index/artifacts/kubernetes-server.json +1573 -0
  135. package/docs/safety-index/artifacts/kubernetes-server.md +176 -0
  136. package/docs/safety-index/artifacts/memory-server.json +93 -32
  137. package/docs/safety-index/artifacts/memory-server.md +45 -25
  138. package/docs/safety-index/artifacts/opentofu-server.json +44 -18
  139. package/docs/safety-index/artifacts/opentofu-server.md +23 -10
  140. package/docs/safety-index/artifacts/playwright-mcp-server.json +177 -21
  141. package/docs/safety-index/artifacts/playwright-mcp-server.md +27 -14
  142. package/docs/safety-index/artifacts/promptopia-server.json +45 -19
  143. package/docs/safety-index/artifacts/promptopia-server.md +21 -8
  144. package/docs/safety-index/artifacts/puppeteer-server.json +77 -22
  145. package/docs/safety-index/artifacts/puppeteer-server.md +28 -15
  146. package/docs/safety-index/artifacts/ref-tools-server.json +36 -18
  147. package/docs/safety-index/artifacts/ref-tools-server.md +21 -8
  148. package/docs/safety-index/artifacts/sequential-thinking-server.json +38 -21
  149. package/docs/safety-index/artifacts/sequential-thinking-server.md +22 -9
  150. package/docs/safety-index/targets.json +90 -14
  151. package/docs/security-due-diligence.md +87 -0
  152. package/docs/setup-ci-doctor.md +13 -1
  153. package/docs/target-gallery.md +49 -0
  154. package/docs/target-registry.md +5 -1
  155. package/docs/tool-call-receipts.md +115 -0
  156. package/examples/insecure-mcp-server/mcp-observatory.target.json +13 -0
  157. package/examples/insecure-mcp-server/server.mjs +62 -0
  158. package/package.json +31 -2
  159. package/schemas/run-artifact.schema.json +1 -0
  160. package/scripts/postinstall.mjs +138 -0
@@ -0,0 +1,359 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { extractObservatoryFindings } from "./findings.js";
6
+ import { runTarget } from "./runner.js";
7
+ import { loadSecurityProfile } from "./security-profiles.js";
8
+ import { validateTargetConfig } from "./validate.js";
9
+ function stableHash(value) {
10
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
11
+ }
12
+ function severityFromObservatory(finding) {
13
+ if (finding.category === "security" && finding.ruleId.includes("credential-pattern"))
14
+ return "critical";
15
+ if (finding.category === "attack-sim" && finding.ruleId.includes("credential-like-output"))
16
+ return "critical";
17
+ if (finding.category === "attack-sim" && finding.ruleId.includes("canary-exposed"))
18
+ return "critical";
19
+ return finding.severity;
20
+ }
21
+ function controlsForFinding(profile, finding) {
22
+ const direct = profile.ruleControls[finding.ruleId];
23
+ if (direct)
24
+ return direct;
25
+ const fromCategory = profile.categoryControls[finding.category] ?? profile.categoryControls[finding.checkId];
26
+ return fromCategory ?? ["trust_boundaries"];
27
+ }
28
+ function normalizeFinding(profile, artifact, finding, generatedAt) {
29
+ const severity = severityFromObservatory(finding);
30
+ const controlMappings = controlsForFinding(profile, finding);
31
+ const fingerprint = stableHash({
32
+ target: artifact.target.targetId,
33
+ rule: finding.ruleId,
34
+ subject: finding.subject,
35
+ description: finding.message,
36
+ });
37
+ return {
38
+ id: finding.id,
39
+ check_id: finding.checkId,
40
+ rule_id: finding.ruleId,
41
+ title: finding.title,
42
+ description: finding.message,
43
+ severity,
44
+ category: finding.category,
45
+ target: {
46
+ target_id: artifact.target.targetId,
47
+ subject_type: finding.subject.type,
48
+ subject_name: finding.subject.name,
49
+ },
50
+ evidence: finding.evidence ?? {},
51
+ recommendation: finding.recommendation ?? "Review this MCP release-gate finding before production deployment.",
52
+ confidence: severity === "info" ? "medium" : "high",
53
+ fingerprint,
54
+ control_mappings: controlMappings,
55
+ generated_at: generatedAt,
56
+ };
57
+ }
58
+ function envSecretFindings(profile, target, generatedAt) {
59
+ if (target.adapter !== "local-process" || !target.env)
60
+ return [];
61
+ const secretLikeNames = Object.keys(target.env).filter((name) => /(?:secret|token|password|passwd|api[_-]?key|credential)/i.test(name));
62
+ return secretLikeNames.map((name) => {
63
+ const fingerprint = stableHash({ target: target.targetId, env: name, rule: "env-secret" });
64
+ return {
65
+ id: `mcp-observatory/audit/env-secret/${fingerprint}`,
66
+ check_id: "security",
67
+ rule_id: "mcp-observatory/audit/env-secret",
68
+ title: "Secret-like environment variable configured",
69
+ description: `Target environment contains secret-like variable "${name}".`,
70
+ severity: "critical",
71
+ category: "secrets_exposure",
72
+ target: { target_id: target.targetId, subject_type: "target", subject_name: target.targetId },
73
+ evidence: { env_var: name, value_redacted: true },
74
+ recommendation: "Use a secret manager or CI secret store and verify the MCP server never returns this value in tool responses or logs.",
75
+ confidence: "high",
76
+ fingerprint,
77
+ control_mappings: profile.ruleControls["mcp-observatory/security/credential-pattern"] ?? ["secrets_exposure", "auditability"],
78
+ generated_at: generatedAt,
79
+ };
80
+ });
81
+ }
82
+ function auditabilityFindings(profile, artifact, generatedAt) {
83
+ const hasAuditHint = Object.values(artifact.target.metadata ?? {}).some((value) => /audit|log|event|trace/i.test(value));
84
+ if (hasAuditHint)
85
+ return [];
86
+ const fingerprint = stableHash({ target: artifact.target.targetId, rule: "auditability-not-declared" });
87
+ return [{
88
+ id: `mcp-observatory/audit/auditability/${fingerprint}`,
89
+ check_id: "conformance",
90
+ rule_id: "mcp-observatory/audit/auditability-not-declared",
91
+ title: "Audit logging not declared",
92
+ description: "The target did not declare structured audit logging, event output, or traceability metadata for tool calls.",
93
+ severity: "medium",
94
+ category: "auditability",
95
+ target: { target_id: artifact.target.targetId, subject_type: "target", subject_name: artifact.target.targetId },
96
+ evidence: { metadata_keys: Object.keys(artifact.target.metadata ?? {}) },
97
+ recommendation: "Document how tool calls, permission decisions, failures, and sensitive data handling are logged for security review.",
98
+ confidence: "medium",
99
+ fingerprint,
100
+ control_mappings: profile.categoryControls["tools-invoke"] ?? ["auditability"],
101
+ generated_at: generatedAt,
102
+ }];
103
+ }
104
+ function computeTrustStatus(findings) {
105
+ if (findings.some((finding) => finding.severity === "critical"))
106
+ return "critical_risk";
107
+ if (findings.some((finding) => finding.severity === "high"))
108
+ return "high_risk";
109
+ if (findings.some((finding) => finding.severity === "medium"))
110
+ return "needs_review";
111
+ if (findings.length === 0 || findings.every((finding) => finding.severity === "info"))
112
+ return "enterprise_ready";
113
+ return "scanned";
114
+ }
115
+ function computeScore(findings) {
116
+ const penalty = findings.reduce((sum, finding) => {
117
+ if (finding.severity === "critical")
118
+ return sum + 35;
119
+ if (finding.severity === "high")
120
+ return sum + 22;
121
+ if (finding.severity === "medium")
122
+ return sum + 10;
123
+ if (finding.severity === "low")
124
+ return sum + 3;
125
+ return sum + 0;
126
+ }, 0);
127
+ return Math.max(0, Math.min(100, 100 - penalty));
128
+ }
129
+ function countSeverities(findings) {
130
+ return {
131
+ critical: findings.filter((finding) => finding.severity === "critical").length,
132
+ high: findings.filter((finding) => finding.severity === "high").length,
133
+ medium: findings.filter((finding) => finding.severity === "medium").length,
134
+ low: findings.filter((finding) => finding.severity === "low").length,
135
+ info: findings.filter((finding) => finding.severity === "info").length,
136
+ };
137
+ }
138
+ function countControls(profile, findings) {
139
+ const counts = Object.fromEntries(profile.controlAreas.map((control) => [control, 0]));
140
+ for (const finding of findings) {
141
+ for (const control of finding.control_mappings)
142
+ counts[control] += 1;
143
+ }
144
+ return counts;
145
+ }
146
+ export function buildAuditReport(artifact, target, profileId = "nsa-mcp") {
147
+ const profile = loadSecurityProfile(profileId);
148
+ const generatedAt = new Date().toISOString();
149
+ const normalized = extractObservatoryFindings(artifact)
150
+ .map((finding) => normalizeFinding(profile, artifact, finding, generatedAt));
151
+ const rawFindings = [
152
+ ...normalized,
153
+ ...envSecretFindings(profile, target, generatedAt),
154
+ ...auditabilityFindings(profile, artifact, generatedAt),
155
+ ];
156
+ const findings = [...new Map(rawFindings.map((finding) => [finding.fingerprint, finding])).values()];
157
+ const severityCounts = countSeverities(findings);
158
+ const score = computeScore(findings);
159
+ const trustStatus = computeTrustStatus(findings);
160
+ const summary = {
161
+ profile: profile.id,
162
+ generated_at: generatedAt,
163
+ target_id: artifact.target.targetId,
164
+ score,
165
+ trust_status: trustStatus,
166
+ finding_count: findings.length,
167
+ pass_count: artifact.checks.filter((check) => check.status === "pass").length,
168
+ warning_count: severityCounts.medium + severityCounts.low,
169
+ fail_count: severityCounts.critical + severityCounts.high,
170
+ severity_counts: severityCounts,
171
+ control_counts: countControls(profile, findings),
172
+ };
173
+ return {
174
+ report_type: "mcp-observatory-audit",
175
+ schema_version: "1.0.0",
176
+ profile: {
177
+ id: profile.id,
178
+ title: profile.title,
179
+ description: profile.description,
180
+ disclaimer: profile.disclaimer,
181
+ controlAreas: profile.controlAreas,
182
+ },
183
+ artifact,
184
+ summary,
185
+ findings,
186
+ };
187
+ }
188
+ export async function runAudit(target, profileId = "nsa-mcp") {
189
+ const artifact = await runTarget(target, { invokeTools: true, securityCheck: true, attackSimulation: {} });
190
+ return buildAuditReport(artifact, target, profileId);
191
+ }
192
+ export function auditScore(report) {
193
+ return {
194
+ target_id: report.summary.target_id,
195
+ profile: report.summary.profile,
196
+ score: report.summary.score,
197
+ status: report.summary.trust_status,
198
+ finding_count: report.summary.finding_count,
199
+ critical: report.summary.severity_counts.critical,
200
+ high: report.summary.severity_counts.high,
201
+ medium: report.summary.severity_counts.medium,
202
+ low: report.summary.severity_counts.low,
203
+ info: report.summary.severity_counts.info,
204
+ generated_at: report.summary.generated_at,
205
+ };
206
+ }
207
+ function markdownTable(rows) {
208
+ if (rows.length === 0)
209
+ return "";
210
+ return [
211
+ `| ${rows[0].join(" | ")} |`,
212
+ `| ${rows[0].map(() => "---").join(" | ")} |`,
213
+ ...rows.slice(1).map((row) => `| ${row.join(" | ")} |`),
214
+ ].join("\n");
215
+ }
216
+ function escapeCell(value) {
217
+ const text = typeof value === "string" ? value : JSON.stringify(value ?? "");
218
+ return text.replaceAll("|", "\\|").replaceAll("\n", " ");
219
+ }
220
+ export function renderAuditMarkdown(report) {
221
+ const grouped = new Map();
222
+ for (const control of report.profile.controlAreas)
223
+ grouped.set(control, []);
224
+ for (const finding of report.findings) {
225
+ for (const control of finding.control_mappings) {
226
+ grouped.get(control)?.push(finding);
227
+ }
228
+ }
229
+ const lines = [
230
+ "# MCP Observatory Security Audit",
231
+ "",
232
+ `**Target:** \`${report.summary.target_id}\``,
233
+ `**Profile:** \`${report.profile.id}\` - ${report.profile.title}`,
234
+ `**Generated:** ${report.summary.generated_at}`,
235
+ "",
236
+ "## Executive Summary",
237
+ "",
238
+ `MCP Observatory evaluated this server as a security release gate before deployment into sensitive, regulated, or mission-critical agentic AI environments.`,
239
+ "",
240
+ `**Overall risk score:** ${report.summary.score}/100`,
241
+ `**Trust status:** \`${report.summary.trust_status}\``,
242
+ `**Findings:** ${report.summary.finding_count} total (${report.summary.severity_counts.critical} critical, ${report.summary.severity_counts.high} high, ${report.summary.severity_counts.medium} medium, ${report.summary.severity_counts.low} low, ${report.summary.severity_counts.info} info)`,
243
+ `**Checks:** ${report.summary.pass_count} pass, ${report.summary.warning_count} warning, ${report.summary.fail_count} fail`,
244
+ "",
245
+ `> ${report.profile.disclaimer}`,
246
+ "",
247
+ "## Control Summary",
248
+ "",
249
+ markdownTable([
250
+ ["Control Area", "Findings"],
251
+ ...report.profile.controlAreas.map((control) => [control, String(report.summary.control_counts[control] ?? 0)]),
252
+ ]),
253
+ "",
254
+ "## Findings By Control Area",
255
+ ];
256
+ for (const [control, findings] of grouped) {
257
+ if (findings.length === 0)
258
+ continue;
259
+ lines.push("", `### ${control}`, "");
260
+ for (const finding of findings) {
261
+ lines.push(`#### [${finding.severity}] ${finding.title}`, "", finding.description, "", `- Rule: \`${finding.rule_id}\``, `- Check: \`${finding.check_id}\``, `- Target: \`${finding.target.subject_name ?? finding.target.target_id}\``, `- Confidence: \`${finding.confidence}\``, `- Fingerprint: \`${finding.fingerprint}\``, `- Evidence: \`${escapeCell(JSON.stringify(finding.evidence))}\``, `- Recommendation: ${finding.recommendation}`, "");
262
+ }
263
+ }
264
+ lines.push("## GitHub Code Scanning", "", "Run the same audit with `--format sarif` and upload the result with GitHub Code Scanning. Each normalized finding is emitted as one SARIF result with control mapping tags.");
265
+ return lines.join("\n");
266
+ }
267
+ function sarifLevel(severity) {
268
+ if (severity === "critical" || severity === "high")
269
+ return "error";
270
+ if (severity === "medium")
271
+ return "warning";
272
+ return "note";
273
+ }
274
+ export function renderAuditSarif(report, artifactUri = "mcp-observatory-audit.json") {
275
+ const seenRules = new Set();
276
+ const rules = [];
277
+ const results = [];
278
+ for (const finding of report.findings) {
279
+ if (!seenRules.has(finding.rule_id)) {
280
+ seenRules.add(finding.rule_id);
281
+ rules.push({
282
+ id: finding.rule_id,
283
+ name: finding.title,
284
+ shortDescription: { text: finding.title },
285
+ fullDescription: { text: finding.description },
286
+ defaultConfiguration: { level: sarifLevel(finding.severity) },
287
+ help: { text: `${finding.recommendation}\n\nTrust status: ${report.summary.trust_status}. Controls: ${finding.control_mappings.join(", ")}.` },
288
+ properties: {
289
+ tags: ["mcp", "mcp-observatory", report.profile.id, ...finding.control_mappings],
290
+ control_mappings: finding.control_mappings,
291
+ confidence: finding.confidence,
292
+ },
293
+ });
294
+ }
295
+ results.push({
296
+ ruleId: finding.rule_id,
297
+ level: sarifLevel(finding.severity),
298
+ message: { text: finding.description },
299
+ locations: [{
300
+ physicalLocation: {
301
+ artifactLocation: { uri: artifactUri },
302
+ region: { startLine: 1 },
303
+ },
304
+ }],
305
+ partialFingerprints: {
306
+ "mcp-observatory/fingerprint": finding.fingerprint,
307
+ },
308
+ properties: {
309
+ id: finding.id,
310
+ check_id: finding.check_id,
311
+ severity: finding.severity,
312
+ category: finding.category,
313
+ target: finding.target,
314
+ control_mappings: finding.control_mappings,
315
+ confidence: finding.confidence,
316
+ tags: ["mcp", "mcp-observatory", report.profile.id, ...finding.control_mappings],
317
+ },
318
+ });
319
+ }
320
+ return JSON.stringify({
321
+ $schema: "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json",
322
+ version: "2.1.0",
323
+ runs: [{
324
+ tool: {
325
+ driver: {
326
+ name: "mcp-observatory",
327
+ informationUri: "https://github.com/KryptosAI/mcp-observatory",
328
+ rules,
329
+ },
330
+ },
331
+ automationDetails: { id: `mcp-observatory/audit/${report.summary.target_id}` },
332
+ results,
333
+ }],
334
+ }, null, 2);
335
+ }
336
+ export async function resolveAuditTarget(input) {
337
+ if (input.length === 0)
338
+ throw new Error("Provide a target path or command.");
339
+ const first = input[0];
340
+ const resolved = path.resolve(first);
341
+ if (input.length === 1 && existsSync(resolved)) {
342
+ const statPath = resolved;
343
+ const targetPath = path.join(statPath, "mcp-observatory.target.json");
344
+ const filePath = statPath.endsWith(".json") ? statPath : targetPath;
345
+ const target = validateTargetConfig(JSON.parse(await readFile(filePath, "utf8")));
346
+ if (target.adapter === "local-process" && !target.cwd && !statPath.endsWith(".json")) {
347
+ return { ...target, cwd: statPath };
348
+ }
349
+ return target;
350
+ }
351
+ return {
352
+ targetId: input[0],
353
+ adapter: "local-process",
354
+ command: input[0],
355
+ args: input.slice(1),
356
+ timeoutMs: 15_000,
357
+ };
358
+ }
359
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/audit.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
- import { readFile, writeFile } from "node:fs/promises";
1
+ import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { ensureDirectory } from "./storage.js";
4
+ import { writeTextFileAtomic } from "./utils/files.js";
4
5
  import { slugify } from "./utils/ids.js";
5
6
  // ── I/O ──────────────────────────────────────────────────────────────────────
6
7
  export function defaultCassettesDirectory(cwd = process.cwd()) {
@@ -11,7 +12,7 @@ export async function saveCassette(cassette, outDir) {
11
12
  const timestamp = new Date().toISOString().replaceAll(":", "-");
12
13
  const fileName = `${timestamp}--${slugify(cassette.targetId)}.cassette.json`;
13
14
  const filePath = path.join(outDir, fileName);
14
- await writeFile(filePath, JSON.stringify(cassette, null, 2) + "\n", "utf8");
15
+ await writeTextFileAtomic(filePath, JSON.stringify(cassette, null, 2) + "\n");
15
16
  return filePath;
16
17
  }
17
18
  export async function loadCassette(filePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"cassette.js","sourceRoot":"","sources":["../../src/cassette.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAqBzC,gFAAgF;AAEhF,MAAM,UAAU,yBAAyB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAkB,EAClB,MAAc;IAEd,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,GAAG,SAAS,KAAK,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5E,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE1C,IACE,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACZ,IAAgC,CAAC,SAAS,CAAC,KAAK,CAAC;QAClD,CAAC,KAAK,CAAC,OAAO,CAAE,IAAgC,CAAC,SAAS,CAAC,CAAC,EAC5D,CAAC;QACD,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,4CAA4C,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,IAAgB,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"cassette.js","sourceRoot":"","sources":["../../src/cassette.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAqBzC,gFAAgF;AAEhF,MAAM,UAAU,yBAAyB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAkB,EAClB,MAAc;IAEd,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,GAAG,SAAS,KAAK,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE1C,IACE,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACZ,IAAgC,CAAC,SAAS,CAAC,KAAK,CAAC;QAClD,CAAC,KAAK,CAAC,OAAO,CAAE,IAAgC,CAAC,SAAS,CAAC,CAAC,EAC5D,CAAC;QACD,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,4CAA4C,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,IAAgB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { CheckResult, RunArtifact } from "../types.js";
2
+ import { type ReceiptAction } from "../action-receipt.js";
3
+ import { type CheckContext, type ObservedCheck } from "./base.js";
4
+ export type AttackClass = "tool-poisoning" | "exfiltration-canary" | "permission-boundary" | "contract-drift";
5
+ export type AttackFindingSeverity = "high" | "medium" | "low";
6
+ export interface AttackSimulationFinding {
7
+ ruleId: string;
8
+ attackClass: AttackClass;
9
+ severity: AttackFindingSeverity;
10
+ itemType: "target" | "tool" | "prompt" | "resource" | "schema" | "response";
11
+ itemName: string;
12
+ message: string;
13
+ evidence: Record<string, unknown>;
14
+ recommendation: string;
15
+ recommendedAction?: ReceiptAction;
16
+ }
17
+ export interface AttackSimulationOptions {
18
+ baseline?: RunArtifact;
19
+ }
20
+ export declare function runAttackSimulationCheck(context: CheckContext, previousChecks: CheckResult[], options?: AttackSimulationOptions): Promise<ObservedCheck>;