@zivis/mcp 0.1.0-alpha.9 → 0.1.6

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 (328) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +19 -0
  3. package/dist/api-client.d.ts +1 -31
  4. package/dist/api-client.js +26 -66
  5. package/dist/auth/index.d.ts +1 -22
  6. package/dist/auth/index.js +15 -46
  7. package/dist/auth/jwt.d.ts +0 -16
  8. package/dist/auth/jwt.js +0 -13
  9. package/dist/auth/keychain.d.ts +6 -32
  10. package/dist/auth/keychain.js +83 -114
  11. package/dist/auth/oauth.d.ts +1 -42
  12. package/dist/auth/oauth.js +22 -64
  13. package/dist/auth/sessions.d.ts +5 -25
  14. package/dist/auth/sessions.js +20 -39
  15. package/dist/auth/token-refresh.d.ts +2 -22
  16. package/dist/auth/token-refresh.js +12 -47
  17. package/dist/cli.d.ts +1 -18
  18. package/dist/cli.js +30 -908
  19. package/dist/index.d.ts +0 -6
  20. package/dist/index.js +0 -7
  21. package/dist/lib/inspect-cache.d.ts +10 -0
  22. package/dist/lib/inspect-cache.js +75 -0
  23. package/dist/lib/next-steps.d.ts +27 -0
  24. package/dist/lib/next-steps.js +21 -0
  25. package/dist/matcher/ast-eval.d.ts +8 -0
  26. package/dist/matcher/ast-eval.js +95 -0
  27. package/dist/matcher/finding.d.ts +55 -0
  28. package/dist/matcher/finding.js +1 -0
  29. package/dist/matcher/index.d.ts +8 -0
  30. package/dist/matcher/index.js +202 -0
  31. package/dist/matcher/inference-candidates.d.ts +26 -0
  32. package/dist/matcher/inference-candidates.js +81 -0
  33. package/dist/matcher/walker.d.ts +7 -0
  34. package/dist/matcher/walker.js +71 -0
  35. package/dist/pattern-pack/index.d.ts +125 -0
  36. package/dist/pattern-pack/index.js +189 -0
  37. package/dist/pattern-packs/zivis-public-0.2.0/capsules/agents/privilege-separation.yaml +224 -0
  38. package/dist/pattern-packs/zivis-public-0.2.0/capsules/prompting/self-consistency-no-isolation.yaml +237 -0
  39. package/dist/pattern-packs/zivis-public-0.2.0/capsules/retrieval/context-injection-no-validator.yaml +348 -0
  40. package/dist/pattern-packs/zivis-public-0.2.0/capsules/security/late-org-filter.yaml +266 -0
  41. package/dist/pattern-packs/zivis-public-0.2.0/controls/external_validator_on_facts.yaml +37 -0
  42. package/dist/pattern-packs/zivis-public-0.2.0/controls/fact_validator_present.yaml +68 -0
  43. package/dist/pattern-packs/zivis-public-0.2.0/controls/human_approval_gate.yaml +44 -0
  44. package/dist/pattern-packs/zivis-public-0.2.0/controls/langgraph_state_machine_with_per_node_tools.yaml +35 -0
  45. package/dist/pattern-packs/zivis-public-0.2.0/controls/per_sample_retrieval_diversification.yaml +38 -0
  46. package/dist/pattern-packs/zivis-public-0.2.0/controls/prisma_extension_or_middleware_attaching_org_filter.yaml +31 -0
  47. package/dist/pattern-packs/zivis-public-0.2.0/controls/row_level_security_policy.yaml +37 -0
  48. package/dist/pattern-packs/zivis-public-0.2.0/controls/source_attribution_present.yaml +58 -0
  49. package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +167 -0
  50. package/dist/pattern-packs/zivis-public-0.2.0/prompts/agents/privilege-separation/identify.md +54 -0
  51. package/dist/pattern-packs/zivis-public-0.2.0/prompts/prompting/self-consistency-no-isolation/identify.md +60 -0
  52. package/dist/pattern-packs/zivis-public-0.2.0/prompts/retrieval/context-injection-no-validator/identify.md +109 -0
  53. package/dist/pattern-packs/zivis-public-0.2.0/prompts/security/late-org-filter/identify.md +78 -0
  54. package/dist/project-binding.d.ts +2 -19
  55. package/dist/project-binding.js +38 -21
  56. package/dist/prompts/audit-dependencies.d.ts +2 -0
  57. package/dist/prompts/audit-dependencies.js +47 -0
  58. package/dist/prompts/getting-started.d.ts +2 -0
  59. package/dist/prompts/getting-started.js +37 -0
  60. package/dist/prompts/index.d.ts +2 -0
  61. package/dist/prompts/index.js +6 -0
  62. package/dist/resolve-application-id.d.ts +0 -4
  63. package/dist/resolve-application-id.js +0 -5
  64. package/dist/sanitize.d.ts +1 -21
  65. package/dist/sanitize.js +7 -41
  66. package/dist/server.d.ts +1 -13
  67. package/dist/server.js +134 -253
  68. package/dist/tools/artifacts.d.ts +76 -0
  69. package/dist/tools/artifacts.js +178 -0
  70. package/dist/tools/check-project.d.ts +5 -18
  71. package/dist/tools/check-project.js +120 -111
  72. package/dist/tools/check-repo-trust.d.ts +4 -19
  73. package/dist/tools/check-repo-trust.js +56 -47
  74. package/dist/tools/create-diagram.d.ts +0 -5
  75. package/dist/tools/create-diagram.js +0 -10
  76. package/dist/tools/create-document.d.ts +0 -5
  77. package/dist/tools/create-document.js +3 -9
  78. package/dist/tools/create-finding.d.ts +85 -0
  79. package/dist/tools/create-finding.js +136 -0
  80. package/dist/tools/delete-finding.d.ts +19 -0
  81. package/dist/tools/delete-finding.js +36 -0
  82. package/dist/tools/discover-local-infra.d.ts +0 -10
  83. package/dist/tools/discover-local-infra.js +3 -73
  84. package/dist/tools/enterprise/get-org-zat.d.ts +0 -5
  85. package/dist/tools/enterprise/get-org-zat.js +0 -6
  86. package/dist/tools/enterprise/get-threat-model.d.ts +1 -8
  87. package/dist/tools/enterprise/get-threat-model.js +9 -31
  88. package/dist/tools/enterprise/list-attack-scenarios.d.ts +24 -0
  89. package/dist/tools/enterprise/list-attack-scenarios.js +63 -0
  90. package/dist/tools/enterprise/list-threat-models.d.ts +1 -6
  91. package/dist/tools/enterprise/list-threat-models.js +1 -9
  92. package/dist/tools/enterprise/manage-actor.d.ts +2 -7
  93. package/dist/tools/enterprise/manage-actor.js +13 -7
  94. package/dist/tools/enterprise/manage-attack-scenario.d.ts +1 -6
  95. package/dist/tools/enterprise/manage-attack-scenario.js +12 -7
  96. package/dist/tools/enterprise/manage-data-asset.d.ts +2 -7
  97. package/dist/tools/enterprise/manage-data-asset.js +16 -7
  98. package/dist/tools/enterprise/manage-security-control.d.ts +1 -6
  99. package/dist/tools/enterprise/manage-security-control.js +17 -7
  100. package/dist/tools/explain-signal-for-diff.d.ts +34 -0
  101. package/dist/tools/explain-signal-for-diff.js +75 -0
  102. package/dist/tools/generate-diagram.d.ts +0 -6
  103. package/dist/tools/generate-diagram.js +21 -13
  104. package/dist/tools/get-application-overview.d.ts +0 -5
  105. package/dist/tools/get-application-overview.js +0 -6
  106. package/dist/tools/get-application.d.ts +0 -5
  107. package/dist/tools/get-application.js +0 -6
  108. package/dist/tools/get-diagram.d.ts +0 -5
  109. package/dist/tools/get-diagram.js +1 -11
  110. package/dist/tools/get-document.d.ts +0 -5
  111. package/dist/tools/get-document.js +0 -6
  112. package/dist/tools/get-oss-zat.d.ts +0 -5
  113. package/dist/tools/get-oss-zat.js +0 -7
  114. package/dist/tools/get-signal.d.ts +24 -0
  115. package/dist/tools/get-signal.js +75 -0
  116. package/dist/tools/get-started.d.ts +18 -0
  117. package/dist/tools/get-started.js +470 -0
  118. package/dist/tools/get-trust-keys.d.ts +0 -5
  119. package/dist/tools/get-trust-keys.js +0 -6
  120. package/dist/tools/import-openapi-endpoints.d.ts +0 -5
  121. package/dist/tools/import-openapi-endpoints.js +0 -6
  122. package/dist/tools/inspect-zat.d.ts +0 -5
  123. package/dist/tools/inspect-zat.js +0 -19
  124. package/dist/tools/inspect.d.ts +21 -0
  125. package/dist/tools/inspect.js +222 -0
  126. package/dist/tools/list-applications.d.ts +1 -6
  127. package/dist/tools/list-applications.js +0 -6
  128. package/dist/tools/list-diagrams.d.ts +0 -5
  129. package/dist/tools/list-diagrams.js +0 -6
  130. package/dist/tools/list-documents.d.ts +0 -5
  131. package/dist/tools/list-documents.js +0 -6
  132. package/dist/tools/list-endpoints.d.ts +1 -6
  133. package/dist/tools/list-endpoints.js +0 -6
  134. package/dist/tools/list-signals.d.ts +37 -0
  135. package/dist/tools/list-signals.js +83 -0
  136. package/dist/tools/manage-application.d.ts +64 -0
  137. package/dist/tools/manage-application.js +129 -0
  138. package/dist/tools/manage-diagram.d.ts +0 -5
  139. package/dist/tools/manage-diagram.js +0 -16
  140. package/dist/tools/manage-endpoint-lifecycle.d.ts +80 -0
  141. package/dist/tools/manage-endpoint-lifecycle.js +180 -0
  142. package/dist/tools/open-in-ide.d.ts +2 -14
  143. package/dist/tools/open-in-ide.js +0 -13
  144. package/dist/tools/review-change.d.ts +34 -0
  145. package/dist/tools/review-change.js +93 -0
  146. package/dist/tools/security-review.d.ts +0 -16
  147. package/dist/tools/security-review.js +63 -77
  148. package/dist/tools/threat-get-capsule.d.ts +15 -0
  149. package/dist/tools/threat-get-capsule.js +53 -0
  150. package/dist/tools/threat-get-inference-prompt.d.ts +15 -0
  151. package/dist/tools/threat-get-inference-prompt.js +73 -0
  152. package/dist/tools/threat-list-relevant-capsules.d.ts +17 -0
  153. package/dist/tools/threat-list-relevant-capsules.js +158 -0
  154. package/dist/tools/threat-run-matcher.d.ts +17 -0
  155. package/dist/tools/threat-run-matcher.js +145 -0
  156. package/dist/tools/update-document.d.ts +0 -5
  157. package/dist/tools/update-document.js +3 -9
  158. package/dist/tools/update-endpoint.d.ts +1 -6
  159. package/dist/tools/update-endpoint.js +0 -7
  160. package/dist/tools/update-finding.d.ts +61 -0
  161. package/dist/tools/update-finding.js +80 -0
  162. package/dist/tools/update-mermaid-source.d.ts +0 -13
  163. package/dist/tools/update-mermaid-source.js +0 -14
  164. package/dist/tools/verify-trust-mark.d.ts +0 -5
  165. package/dist/tools/verify-trust-mark.js +0 -6
  166. package/dist/types.d.ts +13 -13
  167. package/dist/types.js +22 -28
  168. package/package.json +28 -5
  169. package/dist/api-client.js.map +0 -1
  170. package/dist/auth/index.js.map +0 -1
  171. package/dist/auth/jwt.js.map +0 -1
  172. package/dist/auth/keychain.js.map +0 -1
  173. package/dist/auth/oauth.js.map +0 -1
  174. package/dist/auth/sessions.js.map +0 -1
  175. package/dist/auth/token-refresh.js.map +0 -1
  176. package/dist/cli.js.map +0 -1
  177. package/dist/index.js.map +0 -1
  178. package/dist/project-binding.js.map +0 -1
  179. package/dist/resolve-application-id.js.map +0 -1
  180. package/dist/sanitize.js.map +0 -1
  181. package/dist/server.js.map +0 -1
  182. package/dist/tools/check-project.js.map +0 -1
  183. package/dist/tools/check-repo-trust.js.map +0 -1
  184. package/dist/tools/create-diagram.js.map +0 -1
  185. package/dist/tools/create-document.js.map +0 -1
  186. package/dist/tools/discover-local-infra.js.map +0 -1
  187. package/dist/tools/enterprise/capture-evidence.d.ts +0 -54
  188. package/dist/tools/enterprise/capture-evidence.js +0 -72
  189. package/dist/tools/enterprise/capture-evidence.js.map +0 -1
  190. package/dist/tools/enterprise/create-report-ticket.d.ts +0 -34
  191. package/dist/tools/enterprise/create-report-ticket.js +0 -44
  192. package/dist/tools/enterprise/create-report-ticket.js.map +0 -1
  193. package/dist/tools/enterprise/end-pentest-session.d.ts +0 -33
  194. package/dist/tools/enterprise/end-pentest-session.js +0 -42
  195. package/dist/tools/enterprise/end-pentest-session.js.map +0 -1
  196. package/dist/tools/enterprise/generate-report.d.ts +0 -55
  197. package/dist/tools/enterprise/generate-report.js +0 -111
  198. package/dist/tools/enterprise/generate-report.js.map +0 -1
  199. package/dist/tools/enterprise/get-org-zat.js.map +0 -1
  200. package/dist/tools/enterprise/get-report-status.d.ts +0 -27
  201. package/dist/tools/enterprise/get-report-status.js +0 -38
  202. package/dist/tools/enterprise/get-report-status.js.map +0 -1
  203. package/dist/tools/enterprise/get-threat-model.js.map +0 -1
  204. package/dist/tools/enterprise/list-agents.d.ts +0 -42
  205. package/dist/tools/enterprise/list-agents.js +0 -95
  206. package/dist/tools/enterprise/list-agents.js.map +0 -1
  207. package/dist/tools/enterprise/list-report-issues.d.ts +0 -36
  208. package/dist/tools/enterprise/list-report-issues.js +0 -50
  209. package/dist/tools/enterprise/list-report-issues.js.map +0 -1
  210. package/dist/tools/enterprise/list-threat-models.js.map +0 -1
  211. package/dist/tools/enterprise/manage-actor.js.map +0 -1
  212. package/dist/tools/enterprise/manage-attack-scenario.js.map +0 -1
  213. package/dist/tools/enterprise/manage-component.d.ts +0 -58
  214. package/dist/tools/enterprise/manage-component.js +0 -90
  215. package/dist/tools/enterprise/manage-component.js.map +0 -1
  216. package/dist/tools/enterprise/manage-data-asset.js.map +0 -1
  217. package/dist/tools/enterprise/manage-data-flow.d.ts +0 -57
  218. package/dist/tools/enterprise/manage-data-flow.js +0 -98
  219. package/dist/tools/enterprise/manage-data-flow.js.map +0 -1
  220. package/dist/tools/enterprise/manage-finding.d.ts +0 -69
  221. package/dist/tools/enterprise/manage-finding.js +0 -106
  222. package/dist/tools/enterprise/manage-finding.js.map +0 -1
  223. package/dist/tools/enterprise/manage-security-control.js.map +0 -1
  224. package/dist/tools/enterprise/manage-test-case.d.ts +0 -88
  225. package/dist/tools/enterprise/manage-test-case.js +0 -119
  226. package/dist/tools/enterprise/manage-test-case.js.map +0 -1
  227. package/dist/tools/enterprise/promote-finding-to-issue.d.ts +0 -36
  228. package/dist/tools/enterprise/promote-finding-to-issue.js +0 -65
  229. package/dist/tools/enterprise/promote-finding-to-issue.js.map +0 -1
  230. package/dist/tools/enterprise/publish-report-version.d.ts +0 -34
  231. package/dist/tools/enterprise/publish-report-version.js +0 -75
  232. package/dist/tools/enterprise/publish-report-version.js.map +0 -1
  233. package/dist/tools/enterprise/publish-test-to-library.d.ts +0 -31
  234. package/dist/tools/enterprise/publish-test-to-library.js +0 -40
  235. package/dist/tools/enterprise/publish-test-to-library.js.map +0 -1
  236. package/dist/tools/enterprise/record-test-result.d.ts +0 -67
  237. package/dist/tools/enterprise/record-test-result.js +0 -75
  238. package/dist/tools/enterprise/record-test-result.js.map +0 -1
  239. package/dist/tools/enterprise/start-pentest-session.d.ts +0 -35
  240. package/dist/tools/enterprise/start-pentest-session.js +0 -50
  241. package/dist/tools/enterprise/start-pentest-session.js.map +0 -1
  242. package/dist/tools/enterprise/sync-report-section.d.ts +0 -41
  243. package/dist/tools/enterprise/sync-report-section.js +0 -79
  244. package/dist/tools/enterprise/sync-report-section.js.map +0 -1
  245. package/dist/tools/enterprise/update-report-issue.d.ts +0 -55
  246. package/dist/tools/enterprise/update-report-issue.js +0 -69
  247. package/dist/tools/enterprise/update-report-issue.js.map +0 -1
  248. package/dist/tools/generate-diagram.js.map +0 -1
  249. package/dist/tools/get-agent-test-results.d.ts +0 -41
  250. package/dist/tools/get-agent-test-results.js +0 -86
  251. package/dist/tools/get-agent-test-results.js.map +0 -1
  252. package/dist/tools/get-application-overview.js.map +0 -1
  253. package/dist/tools/get-application.js.map +0 -1
  254. package/dist/tools/get-artifact-content.d.ts +0 -29
  255. package/dist/tools/get-artifact-content.js +0 -86
  256. package/dist/tools/get-artifact-content.js.map +0 -1
  257. package/dist/tools/get-diagram.js.map +0 -1
  258. package/dist/tools/get-document.js.map +0 -1
  259. package/dist/tools/get-finding-details.d.ts +0 -28
  260. package/dist/tools/get-finding-details.js +0 -43
  261. package/dist/tools/get-finding-details.js.map +0 -1
  262. package/dist/tools/get-findings.d.ts +0 -57
  263. package/dist/tools/get-findings.js +0 -103
  264. package/dist/tools/get-findings.js.map +0 -1
  265. package/dist/tools/get-oss-zat.js.map +0 -1
  266. package/dist/tools/get-recon-scan.d.ts +0 -27
  267. package/dist/tools/get-recon-scan.js +0 -46
  268. package/dist/tools/get-recon-scan.js.map +0 -1
  269. package/dist/tools/get-scan-output.d.ts +0 -27
  270. package/dist/tools/get-scan-output.js +0 -64
  271. package/dist/tools/get-scan-output.js.map +0 -1
  272. package/dist/tools/get-scenario-details.d.ts +0 -27
  273. package/dist/tools/get-scenario-details.js +0 -46
  274. package/dist/tools/get-scenario-details.js.map +0 -1
  275. package/dist/tools/get-test-case-results.d.ts +0 -37
  276. package/dist/tools/get-test-case-results.js +0 -66
  277. package/dist/tools/get-test-case-results.js.map +0 -1
  278. package/dist/tools/get-test-details.d.ts +0 -29
  279. package/dist/tools/get-test-details.js +0 -49
  280. package/dist/tools/get-test-details.js.map +0 -1
  281. package/dist/tools/get-trust-keys.js.map +0 -1
  282. package/dist/tools/import-openapi-endpoints.js.map +0 -1
  283. package/dist/tools/inspect-zat.js.map +0 -1
  284. package/dist/tools/list-agent-test-cases.d.ts +0 -41
  285. package/dist/tools/list-agent-test-cases.js +0 -73
  286. package/dist/tools/list-agent-test-cases.js.map +0 -1
  287. package/dist/tools/list-applications.js.map +0 -1
  288. package/dist/tools/list-diagrams.js.map +0 -1
  289. package/dist/tools/list-documents.js.map +0 -1
  290. package/dist/tools/list-endpoints.js.map +0 -1
  291. package/dist/tools/list-recon-scans.d.ts +0 -36
  292. package/dist/tools/list-recon-scans.js +0 -74
  293. package/dist/tools/list-recon-scans.js.map +0 -1
  294. package/dist/tools/list-scan-artifacts.d.ts +0 -41
  295. package/dist/tools/list-scan-artifacts.js +0 -63
  296. package/dist/tools/list-scan-artifacts.js.map +0 -1
  297. package/dist/tools/list-scans.d.ts +0 -44
  298. package/dist/tools/list-scans.js +0 -91
  299. package/dist/tools/list-scans.js.map +0 -1
  300. package/dist/tools/list-test-library.d.ts +0 -44
  301. package/dist/tools/list-test-library.js +0 -83
  302. package/dist/tools/list-test-library.js.map +0 -1
  303. package/dist/tools/list-test-scenarios.d.ts +0 -31
  304. package/dist/tools/list-test-scenarios.js +0 -66
  305. package/dist/tools/list-test-scenarios.js.map +0 -1
  306. package/dist/tools/local-scan.d.ts +0 -40
  307. package/dist/tools/local-scan.js +0 -261
  308. package/dist/tools/local-scan.js.map +0 -1
  309. package/dist/tools/manage-diagram.js.map +0 -1
  310. package/dist/tools/open-in-ide.js.map +0 -1
  311. package/dist/tools/run-test-scenario.d.ts +0 -37
  312. package/dist/tools/run-test-scenario.js +0 -70
  313. package/dist/tools/run-test-scenario.js.map +0 -1
  314. package/dist/tools/scan-pr.d.ts +0 -27
  315. package/dist/tools/scan-pr.js +0 -51
  316. package/dist/tools/scan-pr.js.map +0 -1
  317. package/dist/tools/security-review.js.map +0 -1
  318. package/dist/tools/setup-red-team-target.d.ts +0 -79
  319. package/dist/tools/setup-red-team-target.js +0 -430
  320. package/dist/tools/setup-red-team-target.js.map +0 -1
  321. package/dist/tools/triage-finding.d.ts +0 -47
  322. package/dist/tools/triage-finding.js +0 -116
  323. package/dist/tools/triage-finding.js.map +0 -1
  324. package/dist/tools/update-document.js.map +0 -1
  325. package/dist/tools/update-endpoint.js.map +0 -1
  326. package/dist/tools/update-mermaid-source.js.map +0 -1
  327. package/dist/tools/verify-trust-mark.js.map +0 -1
  328. package/dist/types.js.map +0 -1
@@ -1,20 +1,9 @@
1
- /**
2
- * zivis_discover_local_infra — Discover AI infrastructure in a local project
3
- *
4
- * Reads Docker, compose, and dependency files to understand the local AI
5
- * infrastructure. Returns structured recommendations for red team testing
6
- * via zivis_local_scan.
7
- *
8
- * This is a local-only tool — no API calls or authentication required.
9
- * Env values are always redacted for safety.
10
- */
11
1
  import { z } from "zod";
12
2
  import { readFile, readdir, stat } from "fs/promises";
13
3
  import { join } from "path";
14
4
  import { exec } from "child_process";
15
5
  import { promisify } from "util";
16
6
  const execAsync = promisify(exec);
17
- // ── Constants ──
18
7
  export const DISCOVER_LOCAL_INFRA_NAME = "zivis_discover_local_infra";
19
8
  export const DISCOVER_LOCAL_INFRA_DESCRIPTION = `Discover AI infrastructure in a local project directory by reading Docker, compose, and dependency files.
20
9
 
@@ -45,7 +34,6 @@ export const DISCOVER_LOCAL_INFRA_SCHEMA = {
45
34
  .optional()
46
35
  .describe("Path to the project directory to analyze. Defaults to the current working directory."),
47
36
  };
48
- // ── AI Framework Detection Maps ──
49
37
  const NPM_AI_PACKAGES = [
50
38
  { package: "openai", name: "OpenAI SDK" },
51
39
  { package: "@anthropic-ai/sdk", name: "Anthropic SDK" },
@@ -128,8 +116,7 @@ const INFRA_IMAGES = [
128
116
  "jaeger",
129
117
  "memcached",
130
118
  ];
131
- const MAX_FILE_SIZE = 100 * 1024; // 100KB cap
132
- // ── Handler ──
119
+ const MAX_FILE_SIZE = 100 * 1024;
133
120
  export function createDiscoverLocalInfraHandler() {
134
121
  return async (params) => {
135
122
  const projectDir = params.project_dir || process.cwd();
@@ -142,7 +129,6 @@ export function createDiscoverLocalInfraHandler() {
142
129
  suggestion: null,
143
130
  localScanCommand: null,
144
131
  };
145
- // Step 1: Check Docker daemon
146
132
  try {
147
133
  const { stdout } = await execAsync("docker version --format '{{.Server.Version}}'", {
148
134
  timeout: 5000,
@@ -152,7 +138,6 @@ export function createDiscoverLocalInfraHandler() {
152
138
  catch {
153
139
  result.docker = { running: false };
154
140
  }
155
- // Step 2: Find and parse compose files (check root and common subdirs)
156
141
  const composeFileNames = [
157
142
  "docker-compose.yml",
158
143
  "docker-compose.yaml",
@@ -174,10 +159,8 @@ export function createDiscoverLocalInfraHandler() {
174
159
  }
175
160
  }
176
161
  }
177
- // Step 3: Check running containers
178
162
  if (result.docker.running && result.compose.found) {
179
163
  try {
180
- // Use the directory containing the compose file
181
164
  const composeDir = result.compose.file?.includes("/")
182
165
  ? join(projectDir, result.compose.file.split("/").slice(0, -1).join("/"))
183
166
  : projectDir;
@@ -192,12 +175,9 @@ export function createDiscoverLocalInfraHandler() {
192
175
  }
193
176
  }
194
177
  catch {
195
- // docker compose ps failed, leave statuses as unknown
196
178
  }
197
179
  }
198
- // Step 4: Read dependency files and detect AI frameworks
199
180
  const detected = [];
200
- // package.json
201
181
  const pkgJson = await safeReadFile(join(projectDir, "package.json"));
202
182
  if (pkgJson) {
203
183
  try {
@@ -218,17 +198,14 @@ export function createDiscoverLocalInfraHandler() {
218
198
  }
219
199
  }
220
200
  catch {
221
- // Invalid JSON, skip
222
201
  }
223
202
  }
224
- // Search subdirectories (up to 2 levels deep) for dependency files
225
203
  const subdirs = await safeReaddir(projectDir);
226
204
  const searchDirs = [""];
227
205
  for (const dir of subdirs) {
228
206
  if (dir.startsWith(".") || dir === "node_modules" || dir === "vendor")
229
207
  continue;
230
208
  searchDirs.push(dir);
231
- // Also check one more level (e.g., demo-app/api/, apps/api/)
232
209
  const subSubDirs = await safeReaddir(join(projectDir, dir));
233
210
  for (const sub of subSubDirs) {
234
211
  if (sub.startsWith(".") || sub === "node_modules" || sub === "vendor")
@@ -239,7 +216,6 @@ export function createDiscoverLocalInfraHandler() {
239
216
  for (const dir of searchDirs) {
240
217
  const base = dir ? join(projectDir, dir) : projectDir;
241
218
  const prefix = dir ? `${dir}/` : "";
242
- // package.json
243
219
  const subPkgJson = await safeReadFile(join(base, "package.json"));
244
220
  if (subPkgJson) {
245
221
  try {
@@ -257,10 +233,8 @@ export function createDiscoverLocalInfraHandler() {
257
233
  }
258
234
  }
259
235
  catch {
260
- // Skip
261
236
  }
262
237
  }
263
- // requirements.txt
264
238
  const reqTxt = await safeReadFile(join(base, "requirements.txt"));
265
239
  if (reqTxt) {
266
240
  const lines = reqTxt.toLowerCase().split("\n");
@@ -278,7 +252,6 @@ export function createDiscoverLocalInfraHandler() {
278
252
  }
279
253
  }
280
254
  }
281
- // pyproject.toml
282
255
  const pyproject = await safeReadFile(join(base, "pyproject.toml"));
283
256
  if (pyproject) {
284
257
  for (const ai of PIP_AI_PACKAGES) {
@@ -295,7 +268,6 @@ export function createDiscoverLocalInfraHandler() {
295
268
  }
296
269
  }
297
270
  }
298
- // go.mod
299
271
  const goMod = await safeReadFile(join(base, "go.mod"));
300
272
  if (goMod) {
301
273
  for (const ai of GO_AI_PACKAGES) {
@@ -312,10 +284,8 @@ export function createDiscoverLocalInfraHandler() {
312
284
  }
313
285
  }
314
286
  result.aiFrameworks.detected = detected;
315
- // Step 5: Read .env files, redact values, flag AI keys
316
287
  const envFileNames = [".env", ".env.local", ".env.development"];
317
288
  const envHints = [];
318
- // Check root and subdirs for .env files
319
289
  for (const dir of ["", "infra", "docker"]) {
320
290
  for (const envFile of envFileNames) {
321
291
  const filePath = dir ? join(projectDir, dir, envFile) : join(projectDir, envFile);
@@ -335,7 +305,6 @@ export function createDiscoverLocalInfraHandler() {
335
305
  }
336
306
  }
337
307
  result.aiFrameworks.envHints = [...new Set(envHints)];
338
- // Step 6: Scan for Dockerfiles (reuse searchDirs from dependency scan)
339
308
  const dockerfiles = [];
340
309
  for (const dir of searchDirs) {
341
310
  const base = dir ? join(projectDir, dir) : projectDir;
@@ -352,7 +321,6 @@ export function createDiscoverLocalInfraHandler() {
352
321
  }
353
322
  }
354
323
  result.dockerfiles = dockerfiles;
355
- // Step 7: Check if local runner image exists
356
324
  if (result.docker.running) {
357
325
  try {
358
326
  const { stdout } = await execAsync("docker images ghcr.io/zivisai/zivis-local-runner --format '{{.Tag}}'", { timeout: 5000 });
@@ -374,7 +342,6 @@ export function createDiscoverLocalInfraHandler() {
374
342
  };
375
343
  }
376
344
  }
377
- // Step 8: Generate suggestion
378
345
  result.suggestion = generateSuggestion(result.compose.services, result.aiFrameworks.detected, result.aiFrameworks.envHints, result.dockerfiles);
379
346
  if (result.suggestion) {
380
347
  const parts = [`target_url="${result.suggestion.target_url}"`];
@@ -401,7 +368,6 @@ export function createDiscoverLocalInfraHandler() {
401
368
  };
402
369
  };
403
370
  }
404
- // ── Helpers ──
405
371
  async function safeReadFile(filePath) {
406
372
  try {
407
373
  const stats = await stat(filePath);
@@ -423,16 +389,12 @@ async function safeReaddir(dirPath) {
423
389
  return [];
424
390
  }
425
391
  }
426
- /**
427
- * Parse a docker-compose file using line-by-line analysis.
428
- * Extracts service names, images, ports, environment keys, and depends_on.
429
- */
430
392
  function parseComposeServices(content) {
431
393
  const lines = content.split("\n");
432
394
  const services = [];
433
395
  let inServices = false;
434
396
  let currentService = null;
435
- let currentSection = ""; // "ports", "environment", "depends_on", ""
397
+ let currentSection = "";
436
398
  let serviceIndent = -1;
437
399
  let sectionIndent = -1;
438
400
  for (const line of lines) {
@@ -441,13 +403,11 @@ function parseComposeServices(content) {
441
403
  if (trimmed === "" || trimmed.startsWith("#"))
442
404
  continue;
443
405
  const indent = raw.length - raw.trimStart().length;
444
- // Top-level "services:" key (indent 0)
445
406
  if (indent === 0 && /^services:\s*$/.test(trimmed)) {
446
407
  inServices = true;
447
408
  serviceIndent = -1;
448
409
  continue;
449
410
  }
450
- // Another top-level key ends the services block
451
411
  if (inServices && indent === 0) {
452
412
  inServices = false;
453
413
  if (currentService)
@@ -457,8 +417,6 @@ function parseComposeServices(content) {
457
417
  }
458
418
  if (!inServices)
459
419
  continue;
460
- // Detect service names: lines at the first indent level under services
461
- // that end with ":" and contain only word/dash chars
462
420
  if (serviceIndent === -1 && /^[\w][\w.-]*:\s*$/.test(trimmed)) {
463
421
  serviceIndent = indent;
464
422
  }
@@ -479,9 +437,7 @@ function parseComposeServices(content) {
479
437
  }
480
438
  if (!currentService)
481
439
  continue;
482
- // Service properties (indent > serviceIndent)
483
440
  if (indent > serviceIndent) {
484
- // Check for property keys
485
441
  const propMatch = trimmed.match(/^(image|ports|environment|depends_on|build):\s*(.*)/);
486
442
  if (propMatch) {
487
443
  const key = propMatch[1];
@@ -499,7 +455,6 @@ function parseComposeServices(content) {
499
455
  currentSection = "";
500
456
  continue;
501
457
  }
502
- // If we're at a deeper indent than section, parse items
503
458
  if (currentSection && sectionIndent >= 0 && indent > sectionIndent) {
504
459
  if (trimmed.startsWith("-")) {
505
460
  const value = trimmed.replace(/^-\s*/, "").replace(/["']/g, "").trim();
@@ -522,17 +477,14 @@ function parseComposeServices(content) {
522
477
  }
523
478
  }
524
479
  else if (currentSection === "environment" && trimmed.includes(":")) {
525
- // Environment as mapping (KEY: value)
526
480
  const envKey = trimmed.split(":")[0].trim();
527
481
  if (envKey)
528
482
  currentService.environmentKeys.push(envKey);
529
483
  }
530
484
  }
531
485
  else if (indent <= sectionIndent) {
532
- // Back to service property level, reset section
533
486
  currentSection = "";
534
487
  sectionIndent = -1;
535
- // Re-check for property match
536
488
  const rePropMatch = trimmed.match(/^(image|ports|environment|depends_on|build):\s*(.*)/);
537
489
  if (rePropMatch) {
538
490
  const key = rePropMatch[1];
@@ -554,7 +506,6 @@ function parseComposeServices(content) {
554
506
  }
555
507
  function parseDockerComposePsOutput(stdout) {
556
508
  const containers = [];
557
- // docker compose ps --format json outputs one JSON object per line
558
509
  for (const line of stdout.split("\n")) {
559
510
  const trimmed = line.trim();
560
511
  if (!trimmed)
@@ -567,7 +518,6 @@ function parseDockerComposePsOutput(stdout) {
567
518
  });
568
519
  }
569
520
  catch {
570
- // Not JSON, skip
571
521
  }
572
522
  }
573
523
  return containers;
@@ -584,14 +534,12 @@ async function parseDockerfile(dir, filename) {
584
534
  };
585
535
  for (const line of content.split("\n")) {
586
536
  const trimmed = line.trim();
587
- // FROM instruction
588
537
  if (/^FROM\s+/i.test(trimmed)) {
589
538
  const fromMatch = trimmed.match(/^FROM\s+(\S+)/i);
590
539
  if (fromMatch && !info.baseImage) {
591
540
  info.baseImage = fromMatch[1];
592
541
  }
593
542
  }
594
- // EXPOSE instruction
595
543
  if (/^EXPOSE\s+/i.test(trimmed)) {
596
544
  const ports = trimmed
597
545
  .replace(/^EXPOSE\s+/i, "")
@@ -600,7 +548,6 @@ async function parseDockerfile(dir, filename) {
600
548
  .filter((p) => !isNaN(p));
601
549
  info.exposedPorts.push(...ports);
602
550
  }
603
- // AI hints from pip install / npm install
604
551
  if (trimmed.includes("pip install") || trimmed.includes("pip3 install")) {
605
552
  for (const ai of PIP_AI_PACKAGES) {
606
553
  if (trimmed.includes(ai.package)) {
@@ -615,7 +562,6 @@ async function parseDockerfile(dir, filename) {
615
562
  }
616
563
  }
617
564
  }
618
- // Known AI base images
619
565
  if (/^FROM\s+/i.test(trimmed)) {
620
566
  const image = trimmed.replace(/^FROM\s+/i, "").split(/\s+/)[0].toLowerCase();
621
567
  if (image.includes("ollama"))
@@ -630,12 +576,10 @@ async function parseDockerfile(dir, filename) {
630
576
  }
631
577
  function generateSuggestion(services, frameworks, envHints, dockerfiles) {
632
578
  const reasons = [];
633
- // Filter out infrastructure services
634
579
  const appServices = services.filter((svc) => {
635
580
  const image = (svc.image || "").toLowerCase();
636
581
  return !INFRA_IMAGES.some((infra) => image.includes(infra));
637
582
  });
638
- // Determine target type
639
583
  const hasAiFrameworks = frameworks.length > 0;
640
584
  const hasAiEnvKeys = envHints.length > 0;
641
585
  const targetType = hasAiFrameworks || hasAiEnvKeys ? "ai_chat" : "api";
@@ -645,26 +589,21 @@ function generateSuggestion(services, frameworks, envHints, dockerfiles) {
645
589
  if (hasAiEnvKeys) {
646
590
  reasons.push(`Found AI-related env vars: ${envHints.join(", ")}`);
647
591
  }
648
- // Find the best service to target
649
592
  let targetPort = null;
650
- // Prefer running app services with ports
651
593
  const runningApps = appServices.filter((svc) => svc.status === "running" && svc.ports.length > 0);
652
594
  if (runningApps.length > 0) {
653
- // Pick the first one with a port in the typical app range
654
595
  const preferred = runningApps.find((svc) => svc.ports.some((p) => p.host >= 3000 && p.host <= 9000));
655
596
  const target = preferred || runningApps[0];
656
597
  targetPort = target.ports[0].host;
657
598
  reasons.push(`Service "${target.name}" is running on port ${targetPort}`);
658
599
  }
659
600
  else if (appServices.length > 0) {
660
- // Use any app service with ports
661
601
  const withPorts = appServices.find((svc) => svc.ports.length > 0);
662
602
  if (withPorts) {
663
603
  targetPort = withPorts.ports[0].host;
664
604
  reasons.push(`Service "${withPorts.name}" has port ${targetPort} mapped`);
665
605
  }
666
606
  }
667
- // Fallback: check Dockerfiles for EXPOSE
668
607
  if (!targetPort) {
669
608
  for (const df of dockerfiles) {
670
609
  if (df.exposedPorts.length > 0) {
@@ -674,19 +613,15 @@ function generateSuggestion(services, frameworks, envHints, dockerfiles) {
674
613
  }
675
614
  }
676
615
  }
677
- // If still no port, try common defaults
678
616
  if (!targetPort) {
679
617
  targetPort = 3000;
680
618
  reasons.push("Using default port 3000 (no port mapping found)");
681
619
  }
682
- // Infer chat endpoint from frameworks
683
620
  const chatEndpoint = inferChatEndpoint(frameworks);
684
621
  if (chatEndpoint) {
685
622
  reasons.push(`Inferred endpoint ${chatEndpoint} from framework detection`);
686
623
  }
687
- // Infer request template and response path
688
624
  const { requestTemplate, responsePath } = inferRequestFormat(frameworks);
689
- // Calculate confidence
690
625
  let confidence = "low";
691
626
  if (hasAiFrameworks && targetPort && runningApps.length > 0) {
692
627
  confidence = "high";
@@ -718,14 +653,12 @@ function inferChatEndpoint(frameworks) {
718
653
  return "/v1/chat/completions";
719
654
  if (names.has("Gradio"))
720
655
  return "/api/predict";
721
- // Default for any detected AI framework
722
656
  if (frameworks.length > 0)
723
657
  return "/api/chat";
724
658
  return undefined;
725
659
  }
726
660
  function inferRequestFormat(frameworks) {
727
661
  const names = new Set(frameworks.map((f) => f.name));
728
- // OpenAI-compatible APIs
729
662
  if (names.has("OpenAI SDK") ||
730
663
  names.has("Azure OpenAI") ||
731
664
  names.has("vLLM") ||
@@ -738,16 +671,14 @@ function inferRequestFormat(frameworks) {
738
671
  responsePath: "choices[0].message.content",
739
672
  };
740
673
  }
741
- // Vercel AI SDK
742
674
  if (names.has("Vercel AI SDK") || names.has("Vercel AI SDK (OpenAI)") || names.has("Vercel AI SDK (Anthropic)")) {
743
675
  return {
744
676
  requestTemplate: JSON.stringify({
745
677
  messages: [{ role: "user", content: "{{message}}" }],
746
678
  }),
747
- responsePath: undefined, // Vercel AI SDK streams by default
679
+ responsePath: undefined,
748
680
  };
749
681
  }
750
- // Ollama
751
682
  if (names.has("Ollama")) {
752
683
  return {
753
684
  requestTemplate: JSON.stringify({
@@ -760,4 +691,3 @@ function inferRequestFormat(frameworks) {
760
691
  }
761
692
  return {};
762
693
  }
763
- //# sourceMappingURL=discover-local-infra.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * zivis_get_org_zat — Get your organization's latest signed attestation token
3
- *
4
- * Maps to: GET /api/zat?framework=<optional> (JWT auth required)
5
- */
6
1
  import { z } from "zod";
7
2
  import type { ApiClient } from "../../api-client.js";
8
3
  export declare const GET_ORG_ZAT_NAME = "zivis_get_org_zat";
@@ -1,8 +1,3 @@
1
- /**
2
- * zivis_get_org_zat — Get your organization's latest signed attestation token
3
- *
4
- * Maps to: GET /api/zat?framework=<optional> (JWT auth required)
5
- */
6
1
  import { z } from "zod";
7
2
  export const GET_ORG_ZAT_NAME = "zivis_get_org_zat";
8
3
  export const GET_ORG_ZAT_DESCRIPTION = `Get your organization's latest ZIVIS Attestation Token (ZAT) — a cryptographically signed credential capturing your compliance posture.
@@ -59,4 +54,3 @@ export function createGetOrgZatHandler(apiClient) {
59
54
  }
60
55
  };
61
56
  }
62
- //# sourceMappingURL=get-org-zat.js.map
@@ -1,19 +1,12 @@
1
- /**
2
- * zivis_get_threat_model — Get a threat model with all entities
3
- *
4
- * Maps to: GET /api/threat-models/:id
5
- */
6
1
  import { z } from "zod";
7
2
  import type { ApiClient } from "../../api-client.js";
8
3
  export declare const GET_THREAT_MODEL_NAME = "zivis_get_threat_model";
9
- export declare const GET_THREAT_MODEL_DESCRIPTION = "Get a threat model with ALL its entities \u2014 actors, components, data flows, attack scenarios, security controls, data assets, test cases, findings, AND any linked diagrams.\n\nReturns the complete threat model including:\n- **Actors**: Who interacts with the system (external users, attackers, internal services)\n- **Components**: System parts (APIs, databases, frontends, services) with technology and trust level\n- **Data Flows**: How data moves between components (protocol, encryption, auth mechanism)\n- **Attack Scenarios**: STRIDE-categorized threats with severity, likelihood, attack vectors\n- **Security Controls**: Existing mitigations (preventive, detective, corrective) with effectiveness\n- **Data Assets**: What sensitive data exists and how it's classified\n- **Test Cases**: Security tests with results (pass/fail/partial/not_tested)\n- **Findings**: Discovered vulnerabilities with severity and remediation recommendations\n- **Linked Diagrams**: Architecture, data flow, trust boundary, and other diagrams associated with this threat model\n\nIMPORTANT: The threat_model_id must be a threat model UUID from zivis_list_threat_models, NOT a scan ID or agent instance ID.\n\nUse this to understand the full security posture before making changes, adding entities, or running pen tests.\nAfter viewing, use zivis_manage_actor, zivis_manage_component, zivis_manage_data_flow, etc. to add or update entities.\nUse zivis_get_diagram with a diagram_id from the linked_diagrams to view full diagram details (nodes, connections, boundaries).";
4
+ export declare const GET_THREAT_MODEL_DESCRIPTION = "Get a threat model \u2014 its metadata, status, owning application, and linked diagrams.\n\nReturns:\n- The threat model row (name, status, application association, timestamps)\n- **Linked Diagrams** (`linked_diagrams`): first-class `Diagram` entities linked to this threat model. Use `zivis_get_diagram` for full content.\n- Threat-model documents are listed via `zivis_list_documents` with `threat_model_id`.\n\nIMPORTANT: The threat_model_id must be a threat model UUID from zivis_list_threat_models, NOT a scan ID or agent instance ID.";
10
5
  export declare const GET_THREAT_MODEL_SCHEMA: {
11
6
  threat_model_id: z.ZodString;
12
- include_test_cases: z.ZodDefault<z.ZodBoolean>;
13
7
  };
14
8
  export declare function createGetThreatModelHandler(apiClient: ApiClient): (params: {
15
9
  threat_model_id: string;
16
- include_test_cases?: boolean;
17
10
  }) => Promise<{
18
11
  content: {
19
12
  type: "text";
@@ -1,51 +1,30 @@
1
- /**
2
- * zivis_get_threat_model — Get a threat model with all entities
3
- *
4
- * Maps to: GET /api/threat-models/:id
5
- */
6
1
  import { z } from "zod";
7
2
  import { sanitizeResponse } from "../../sanitize.js";
8
3
  export const GET_THREAT_MODEL_NAME = "zivis_get_threat_model";
9
- export const GET_THREAT_MODEL_DESCRIPTION = `Get a threat model with ALL its entities — actors, components, data flows, attack scenarios, security controls, data assets, test cases, findings, AND any linked diagrams.
4
+ export const GET_THREAT_MODEL_DESCRIPTION = `Get a threat model — its metadata, status, owning application, and linked diagrams.
10
5
 
11
- Returns the complete threat model including:
12
- - **Actors**: Who interacts with the system (external users, attackers, internal services)
13
- - **Components**: System parts (APIs, databases, frontends, services) with technology and trust level
14
- - **Data Flows**: How data moves between components (protocol, encryption, auth mechanism)
15
- - **Attack Scenarios**: STRIDE-categorized threats with severity, likelihood, attack vectors
16
- - **Security Controls**: Existing mitigations (preventive, detective, corrective) with effectiveness
17
- - **Data Assets**: What sensitive data exists and how it's classified
18
- - **Test Cases**: Security tests with results (pass/fail/partial/not_tested)
19
- - **Findings**: Discovered vulnerabilities with severity and remediation recommendations
20
- - **Linked Diagrams**: Architecture, data flow, trust boundary, and other diagrams associated with this threat model
6
+ Returns:
7
+ - The threat model row (name, status, application association, timestamps)
8
+ - **Linked Diagrams** (\`linked_diagrams\`): first-class \`Diagram\` entities linked to this threat model. Use \`zivis_get_diagram\` for full content.
9
+ - Threat-model documents are listed via \`zivis_list_documents\` with \`threat_model_id\`.
21
10
 
22
- IMPORTANT: The threat_model_id must be a threat model UUID from zivis_list_threat_models, NOT a scan ID or agent instance ID.
23
-
24
- Use this to understand the full security posture before making changes, adding entities, or running pen tests.
25
- After viewing, use zivis_manage_actor, zivis_manage_component, zivis_manage_data_flow, etc. to add or update entities.
26
- Use zivis_get_diagram with a diagram_id from the linked_diagrams to view full diagram details (nodes, connections, boundaries).`;
11
+ IMPORTANT: The threat_model_id must be a threat model UUID from zivis_list_threat_models, NOT a scan ID or agent instance ID.`;
27
12
  export const GET_THREAT_MODEL_SCHEMA = {
28
13
  threat_model_id: z
29
14
  .string()
30
15
  .describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
31
- include_test_cases: z
32
- .boolean()
33
- .default(true)
34
- .describe("Whether to include test cases in the response"),
35
16
  };
36
17
  export function createGetThreatModelHandler(apiClient) {
37
18
  return async (params) => {
38
19
  try {
39
- // Fetch threat model and linked diagrams in parallel
40
20
  const [threatModelData, diagramsData] = await Promise.all([
41
- apiClient.get(`/api/threat-models/${params.threat_model_id}?include=all`),
21
+ apiClient.get(`/api/threat-models/${params.threat_model_id}`),
42
22
  apiClient
43
23
  .get(`/api/diagrams?linkedThreatModelId=${params.threat_model_id}&take=50`)
44
24
  .catch(() => ({ diagrams: [], total: 0 })),
45
25
  ]);
46
26
  const sanitized = sanitizeResponse(threatModelData);
47
- // Attach linked diagrams summary to the response
48
- const diagrams = Array.isArray(diagramsData.diagrams)
27
+ const linkedDiagrams = Array.isArray(diagramsData.diagrams)
49
28
  ? diagramsData.diagrams.map((d) => ({
50
29
  diagram_id: d.id,
51
30
  name: d.name,
@@ -59,7 +38,7 @@ export function createGetThreatModelHandler(apiClient) {
59
38
  : [];
60
39
  const result = {
61
40
  ...sanitized,
62
- linked_diagrams: diagrams,
41
+ linked_diagrams: linkedDiagrams,
63
42
  linked_diagrams_count: diagramsData.total,
64
43
  };
65
44
  return {
@@ -80,4 +59,3 @@ export function createGetThreatModelHandler(apiClient) {
80
59
  }
81
60
  };
82
61
  }
83
- //# sourceMappingURL=get-threat-model.js.map
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import type { ApiClient } from "../../api-client.js";
3
+ export declare const LIST_ATTACK_SCENARIOS_NAME = "zivis_list_attack_scenarios";
4
+ export declare const LIST_ATTACK_SCENARIOS_DESCRIPTION = "List attack scenarios for a threat model, including their path steps.\n\nUse this when you need scenario IDs or attack path step IDs for follow-up tools (for example, step-level library test mappings).\n\nIMPORTANT: threat_model_id must be a threat model UUID (from zivis_list_threat_models), not a scan ID.";
5
+ export declare const LIST_ATTACK_SCENARIOS_SCHEMA: {
6
+ threat_model_id: z.ZodString;
7
+ limit: z.ZodDefault<z.ZodNumber>;
8
+ };
9
+ export declare function createListAttackScenariosHandler(apiClient: ApiClient): (params: {
10
+ threat_model_id: string;
11
+ limit?: number;
12
+ }) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ isError?: undefined;
18
+ } | {
19
+ content: {
20
+ type: "text";
21
+ text: string;
22
+ }[];
23
+ isError: boolean;
24
+ }>;
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { sanitizeResponse } from "../../sanitize.js";
3
+ export const LIST_ATTACK_SCENARIOS_NAME = "zivis_list_attack_scenarios";
4
+ export const LIST_ATTACK_SCENARIOS_DESCRIPTION = `List attack scenarios for a threat model, including their path steps.
5
+
6
+ Use this when you need scenario IDs or attack path step IDs for follow-up tools (for example, step-level library test mappings).
7
+
8
+ IMPORTANT: threat_model_id must be a threat model UUID (from zivis_list_threat_models), not a scan ID.`;
9
+ export const LIST_ATTACK_SCENARIOS_SCHEMA = {
10
+ threat_model_id: z
11
+ .string()
12
+ .describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID)"),
13
+ limit: z
14
+ .number()
15
+ .min(1)
16
+ .max(200)
17
+ .default(50)
18
+ .describe("Maximum scenarios to return (1-200, default 50)"),
19
+ };
20
+ export function createListAttackScenariosHandler(apiClient) {
21
+ return async (params) => {
22
+ try {
23
+ const data = await apiClient.get(`/api/threat-models/${params.threat_model_id}/attack-scenarios`);
24
+ const limit = params.limit ?? 50;
25
+ const scenarios = (data.attackScenarios || []).slice(0, limit).map((scenario) => ({
26
+ scenario_id: scenario.id,
27
+ display_id: scenario.displayId,
28
+ title: scenario.title,
29
+ severity: scenario.severity,
30
+ likelihood: scenario.likelihood,
31
+ status: scenario.status,
32
+ review_status: scenario.reviewStatus,
33
+ risk_score: scenario.riskScore,
34
+ test_case_count: scenario._count?.testCases ?? 0,
35
+ step_count: scenario.pathSteps?.length ?? 0,
36
+ path_steps: (scenario.pathSteps || []).map((step) => ({
37
+ step_id: step.id,
38
+ step_order: step.stepOrder,
39
+ action: step.action,
40
+ library_test_count: step._count?.libraryTests ?? 0,
41
+ })),
42
+ created_at: scenario.createdAt,
43
+ updated_at: scenario.updatedAt,
44
+ }));
45
+ const sanitized = sanitizeResponse({
46
+ is_analyzing: data.isAnalyzing ?? false,
47
+ is_fallback_version: data.isFallback ?? false,
48
+ total_returned: scenarios.length,
49
+ scenarios,
50
+ });
51
+ return {
52
+ content: [{ type: "text", text: JSON.stringify(sanitized, null, 2) }],
53
+ };
54
+ }
55
+ catch (err) {
56
+ const message = err instanceof Error ? err.message : "Failed to list attack scenarios";
57
+ return {
58
+ content: [{ type: "text", text: `Error: ${message}` }],
59
+ isError: true,
60
+ };
61
+ }
62
+ };
63
+ }
@@ -1,12 +1,7 @@
1
- /**
2
- * zivis_list_threat_models — List threat models for the org
3
- *
4
- * Maps to: GET /api/threat-models
5
- */
6
1
  import { z } from "zod";
7
2
  import type { ApiClient } from "../../api-client.js";
8
3
  export declare const LIST_THREAT_MODELS_NAME = "zivis_list_threat_models";
9
- export declare const LIST_THREAT_MODELS_DESCRIPTION = "List all threat models for your organization. Returns name, status, summary info, and linked diagram counts for each threat model.\n\nAlso fetches any diagrams linked to each threat model, so you can see which threat models have associated architecture, data flow, or trust boundary diagrams. Use zivis_get_threat_model to see full diagram details.\n\nIMPORTANT: Threat models are NOT scans and NOT agents. They are separate entities:\n- A **threat model** (returned here) has its own UUID and contains components, data flows, actors, findings, etc.\n- A **scan** is an agent execution run (from zivis_list_scans) \u2014 scans may CREATE or UPDATE threat models, but scan IDs \u2260 threat model IDs.\n- An **agent instance** is a configured agent (from the UI) \u2014 agents RUN scans which produce threat models.\n\nUse the threat model ID (from this tool's response) when calling zivis_get_threat_model, zivis_manage_component, zivis_manage_finding, etc. Do NOT pass scan IDs or agent instance IDs to those tools.";
4
+ export declare const LIST_THREAT_MODELS_DESCRIPTION = "List all threat models for your organization. Returns name, status, summary info, and linked diagram counts for each threat model.\n\nAlso fetches any diagrams linked to each threat model, so you can see which threat models have associated architecture, data flow, or trust boundary diagrams. Use zivis_get_threat_model to see full diagram details.\n\nIMPORTANT: Threat models are NOT scans and NOT agents. They are separate entities:\n- A **threat model** (returned here) has its own UUID and contains components, data flows, actors, findings, etc.\n- A **scan** is an agent execution run (from zivis_list_scans) \u2014 scans may CREATE or UPDATE threat models, but scan IDs \u2260 threat model IDs.\n- An **agent instance** is a configured agent (from the UI) \u2014 agents RUN scans which produce threat models.\n\nUse the threat model ID (from this tool's response) when calling zivis_get_threat_model, zivis_manage_actor, zivis_manage_attack_scenario, etc. Do NOT pass scan IDs or agent instance IDs to those tools.";
10
5
  export declare const LIST_THREAT_MODELS_SCHEMA: {
11
6
  status: z.ZodOptional<z.ZodEnum<{
12
7
  draft: "draft";
@@ -1,8 +1,3 @@
1
- /**
2
- * zivis_list_threat_models — List threat models for the org
3
- *
4
- * Maps to: GET /api/threat-models
5
- */
6
1
  import { z } from "zod";
7
2
  import { sanitizeResponse } from "../../sanitize.js";
8
3
  export const LIST_THREAT_MODELS_NAME = "zivis_list_threat_models";
@@ -15,7 +10,7 @@ IMPORTANT: Threat models are NOT scans and NOT agents. They are separate entitie
15
10
  - A **scan** is an agent execution run (from zivis_list_scans) — scans may CREATE or UPDATE threat models, but scan IDs ≠ threat model IDs.
16
11
  - An **agent instance** is a configured agent (from the UI) — agents RUN scans which produce threat models.
17
12
 
18
- Use the threat model ID (from this tool's response) when calling zivis_get_threat_model, zivis_manage_component, zivis_manage_finding, etc. Do NOT pass scan IDs or agent instance IDs to those tools.`;
13
+ Use the threat model ID (from this tool's response) when calling zivis_get_threat_model, zivis_manage_actor, zivis_manage_attack_scenario, etc. Do NOT pass scan IDs or agent instance IDs to those tools.`;
19
14
  export const LIST_THREAT_MODELS_SCHEMA = {
20
15
  status: z
21
16
  .enum(["draft", "analyzing", "analyzed", "reviewed", "approved", "archived"])
@@ -40,13 +35,11 @@ export function createListThreatModelsHandler(apiClient) {
40
35
  const path = `/api/threat-models${queryStr ? `?${queryStr}` : ""}`;
41
36
  const data = await apiClient.get(path);
42
37
  const sanitized = sanitizeResponse(data);
43
- // Fetch diagram counts for each threat model in parallel
44
38
  const threatModels = Array.isArray(sanitized) ? sanitized : [];
45
39
  const diagramCounts = await Promise.all(threatModels.map((tm) => apiClient
46
40
  .get(`/api/diagrams?linkedThreatModelId=${tm.id}&take=1`)
47
41
  .then((res) => res.total ?? 0)
48
42
  .catch(() => 0)));
49
- // Format with clear ID labeling to prevent confusion with scan/agent IDs
50
43
  const summary = Array.isArray(sanitized)
51
44
  ? sanitized.map((tm, i) => ({
52
45
  threat_model_id: tm.id,
@@ -79,4 +72,3 @@ export function createListThreatModelsHandler(apiClient) {
79
72
  }
80
73
  };
81
74
  }
82
- //# sourceMappingURL=list-threat-models.js.map