@zivis/mcp 0.1.6 → 0.1.7

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.
@@ -3,7 +3,7 @@
3
3
  "pack_id": "zivis-public",
4
4
  "pack_name": "ZIVIS Public Pattern Pack",
5
5
  "version": "0.2.0",
6
- "built_at": "2026-08-25T22:25:05.314Z",
6
+ "built_at": "2026-08-27T22:39:07.661Z",
7
7
  "tier": "customer_safe",
8
8
  "description": "ZIVIS-curated public pattern pack — capsules + inference prompts evaluated locally on the user's machine.",
9
9
  "capsules": [
package/dist/server.js CHANGED
@@ -89,13 +89,6 @@ import { DELETE_FINDING_NAME, DELETE_FINDING_DESCRIPTION, DELETE_FINDING_SCHEMA,
89
89
  import { UPDATE_DOCUMENT_NAME, UPDATE_DOCUMENT_DESCRIPTION, UPDATE_DOCUMENT_SCHEMA, createUpdateDocumentHandler, } from "./tools/update-document.js";
90
90
  import { SECURITY_REVIEW_NAME, SECURITY_REVIEW_DESCRIPTION, SECURITY_REVIEW_SCHEMA, createSecurityReviewHandler, } from "./tools/security-review.js";
91
91
  import { CHECK_PROJECT_NAME, CHECK_PROJECT_DESCRIPTION, CHECK_PROJECT_SCHEMA, createCheckProjectHandler, } from "./tools/check-project.js";
92
- import { GET_THREAT_MODEL_NAME, GET_THREAT_MODEL_DESCRIPTION, GET_THREAT_MODEL_SCHEMA, createGetThreatModelHandler } from "./tools/enterprise/get-threat-model.js";
93
- import { LIST_THREAT_MODELS_NAME, LIST_THREAT_MODELS_DESCRIPTION, LIST_THREAT_MODELS_SCHEMA, createListThreatModelsHandler } from "./tools/enterprise/list-threat-models.js";
94
- import { LIST_ATTACK_SCENARIOS_NAME, LIST_ATTACK_SCENARIOS_DESCRIPTION, LIST_ATTACK_SCENARIOS_SCHEMA, createListAttackScenariosHandler } from "./tools/enterprise/list-attack-scenarios.js";
95
- import { MANAGE_ACTOR_NAME, MANAGE_ACTOR_DESCRIPTION, MANAGE_ACTOR_SCHEMA, createManageActorHandler } from "./tools/enterprise/manage-actor.js";
96
- import { MANAGE_ATTACK_SCENARIO_NAME, MANAGE_ATTACK_SCENARIO_DESCRIPTION, MANAGE_ATTACK_SCENARIO_SCHEMA, createManageAttackScenarioHandler } from "./tools/enterprise/manage-attack-scenario.js";
97
- import { MANAGE_SECURITY_CONTROL_NAME, MANAGE_SECURITY_CONTROL_DESCRIPTION, MANAGE_SECURITY_CONTROL_SCHEMA, createManageSecurityControlHandler } from "./tools/enterprise/manage-security-control.js";
98
- import { MANAGE_DATA_ASSET_NAME, MANAGE_DATA_ASSET_DESCRIPTION, MANAGE_DATA_ASSET_SCHEMA, createManageDataAssetHandler } from "./tools/enterprise/manage-data-asset.js";
99
92
  import { GET_ORG_ZAT_NAME, GET_ORG_ZAT_DESCRIPTION, GET_ORG_ZAT_SCHEMA, createGetOrgZatHandler } from "./tools/enterprise/get-org-zat.js";
100
93
  import { OPEN_IN_IDE_NAME, OPEN_IN_IDE_DESCRIPTION, OPEN_IN_IDE_SCHEMA, createOpenInIdeHandler, } from "./tools/open-in-ide.js";
101
94
  export async function startServer(incoming = DEFAULT_CONFIG) {
@@ -290,13 +283,6 @@ export async function startServer(incoming = DEFAULT_CONFIG) {
290
283
  };
291
284
  }
292
285
  const enterpriseTools = [
293
- [GET_THREAT_MODEL_NAME, GET_THREAT_MODEL_DESCRIPTION, GET_THREAT_MODEL_SCHEMA, createGetThreatModelHandler(apiClient)],
294
- [LIST_THREAT_MODELS_NAME, LIST_THREAT_MODELS_DESCRIPTION, LIST_THREAT_MODELS_SCHEMA, createListThreatModelsHandler(apiClient)],
295
- [LIST_ATTACK_SCENARIOS_NAME, LIST_ATTACK_SCENARIOS_DESCRIPTION, LIST_ATTACK_SCENARIOS_SCHEMA, createListAttackScenariosHandler(apiClient)],
296
- [MANAGE_ACTOR_NAME, MANAGE_ACTOR_DESCRIPTION, MANAGE_ACTOR_SCHEMA, createManageActorHandler(apiClient)],
297
- [MANAGE_ATTACK_SCENARIO_NAME, MANAGE_ATTACK_SCENARIO_DESCRIPTION, MANAGE_ATTACK_SCENARIO_SCHEMA, createManageAttackScenarioHandler(apiClient)],
298
- [MANAGE_SECURITY_CONTROL_NAME, MANAGE_SECURITY_CONTROL_DESCRIPTION, MANAGE_SECURITY_CONTROL_SCHEMA, createManageSecurityControlHandler(apiClient)],
299
- [MANAGE_DATA_ASSET_NAME, MANAGE_DATA_ASSET_DESCRIPTION, MANAGE_DATA_ASSET_SCHEMA, createManageDataAssetHandler(apiClient)],
300
286
  [GET_ORG_ZAT_NAME, GET_ORG_ZAT_DESCRIPTION, GET_ORG_ZAT_SCHEMA, createGetOrgZatHandler(apiClient)],
301
287
  ];
302
288
  for (const [name, description, schema, handler] of enterpriseTools) {
@@ -2,16 +2,13 @@ import { z } from "zod";
2
2
  import type { ApiClient } from "../api-client.js";
3
3
  import type { ZivisConfig } from "../types.js";
4
4
  export declare const SECURITY_REVIEW_NAME = "zivis_security_review";
5
- export declare const SECURITY_REVIEW_DESCRIPTION = "Gather ZIVIS security intelligence for an AI-powered code review.\n\nPulls historical findings, open vulnerabilities, threat model controls, and attack scenarios to give you comprehensive security context. Use this BEFORE reviewing code to understand:\n\n1. **Regression risks** \u2014 Previously fixed vulnerabilities that could be reintroduced\n2. **Known vulnerabilities** \u2014 Open findings that may be relevant to the code being reviewed\n3. **Security controls** \u2014 What controls are expected (input validation, auth, rate limiting, etc.)\n4. **Attack scenarios** \u2014 Known attack vectors for this application (STRIDE-categorized)\n5. **Dependency risks** \u2014 OSS trust scores for dependencies in the code\n\nReturns structured security context that you should reference during code review. Focus on:\n- Code that touches areas where historical findings were fixed (regression check)\n- Missing or weak implementations of expected security controls\n- Code patterns that match known attack scenarios\n- Use of low-trust dependencies\n\nProvide at least one of: repo, application_id, threat_model_id, or campaign_id.";
5
+ export declare const SECURITY_REVIEW_DESCRIPTION = "Gather ZIVIS security intelligence for an AI-powered code review.\n\nPulls historical findings and open vulnerabilities to give you comprehensive security context. Use this BEFORE reviewing code to understand:\n\n1. **Regression risks** \u2014 Previously fixed vulnerabilities that could be reintroduced\n2. **Known vulnerabilities** \u2014 Open findings that may be relevant to the code being reviewed\n3. **Dependency risks** \u2014 OSS trust scores for dependencies in the code\n\nReturns structured security context that you should reference during code review. Focus on:\n- Code that touches areas where historical findings were fixed (regression check)\n- Use of low-trust dependencies\n\nProvide at least one of: repo, application_id, or campaign_id.";
6
6
  export declare const SECURITY_REVIEW_SCHEMA: {
7
7
  repo: z.ZodOptional<z.ZodString>;
8
8
  application_id: z.ZodOptional<z.ZodString>;
9
- threat_model_id: z.ZodOptional<z.ZodString>;
10
9
  campaign_id: z.ZodOptional<z.ZodString>;
11
10
  focus_areas: z.ZodOptional<z.ZodArray<z.ZodEnum<{
12
11
  regression: "regression";
13
- controls: "controls";
14
- attack_scenarios: "attack_scenarios";
15
12
  dependencies: "dependencies";
16
13
  all: "all";
17
14
  }>>>;
@@ -28,7 +25,6 @@ export declare const SECURITY_REVIEW_SCHEMA: {
28
25
  export declare function createSecurityReviewHandler(apiClient: ApiClient, config: ZivisConfig): (params: {
29
26
  repo?: string;
30
27
  application_id?: string;
31
- threat_model_id?: string;
32
28
  campaign_id?: string;
33
29
  focus_areas?: string[];
34
30
  severity_threshold?: string;
@@ -4,31 +4,26 @@ import { sanitizeResponse } from "../sanitize.js";
4
4
  export const SECURITY_REVIEW_NAME = "zivis_security_review";
5
5
  export const SECURITY_REVIEW_DESCRIPTION = `Gather ZIVIS security intelligence for an AI-powered code review.
6
6
 
7
- Pulls historical findings, open vulnerabilities, threat model controls, and attack scenarios to give you comprehensive security context. Use this BEFORE reviewing code to understand:
7
+ Pulls historical findings and open vulnerabilities to give you comprehensive security context. Use this BEFORE reviewing code to understand:
8
8
 
9
9
  1. **Regression risks** — Previously fixed vulnerabilities that could be reintroduced
10
10
  2. **Known vulnerabilities** — Open findings that may be relevant to the code being reviewed
11
- 3. **Security controls** — What controls are expected (input validation, auth, rate limiting, etc.)
12
- 4. **Attack scenarios** — Known attack vectors for this application (STRIDE-categorized)
13
- 5. **Dependency risks** — OSS trust scores for dependencies in the code
11
+ 3. **Dependency risks** — OSS trust scores for dependencies in the code
14
12
 
15
13
  Returns structured security context that you should reference during code review. Focus on:
16
14
  - Code that touches areas where historical findings were fixed (regression check)
17
- - Missing or weak implementations of expected security controls
18
- - Code patterns that match known attack scenarios
19
15
  - Use of low-trust dependencies
20
16
 
21
- Provide at least one of: repo, application_id, threat_model_id, or campaign_id.`;
17
+ Provide at least one of: repo, application_id, or campaign_id.`;
22
18
  export const SECURITY_REVIEW_SCHEMA = {
23
19
  repo: z.string().optional().describe("Repository name (owner/repo) — pulls findings and OSS trust data"),
24
20
  application_id: z
25
21
  .string()
26
22
  .optional()
27
23
  .describe("Application UUID — pulls findings scoped to this app. If omitted, uses applicationId from .zivis/project.json when set."),
28
- threat_model_id: z.string().optional().describe("Threat model UUID — pulls controls, attack scenarios, and findings"),
29
24
  campaign_id: z.string().optional().describe("Campaign UUID — pulls campaign-specific findings"),
30
25
  focus_areas: z
31
- .array(z.enum(["regression", "controls", "attack_scenarios", "dependencies", "all"]))
26
+ .array(z.enum(["regression", "dependencies", "all"]))
32
27
  .optional()
33
28
  .describe("Which intelligence to gather (default: all)"),
34
29
  severity_threshold: z
@@ -53,13 +48,13 @@ const SEVERITY_ORDER = {
53
48
  };
54
49
  export function createSecurityReviewHandler(apiClient, config) {
55
50
  return async (params) => {
56
- const { repo, application_id: application_idParam, threat_model_id, campaign_id, focus_areas = ["all"], severity_threshold = "low", include_resolved = true, dependency_list, } = params;
51
+ const { repo, application_id: application_idParam, campaign_id, focus_areas = ["all"], severity_threshold = "low", include_resolved = true, dependency_list, } = params;
57
52
  const application_id = resolveApplicationId(application_idParam);
58
- if (!repo && !application_id && !threat_model_id && !campaign_id) {
53
+ if (!repo && !application_id && !campaign_id) {
59
54
  return {
60
55
  content: [{
61
56
  type: "text",
62
- text: "Error: Provide at least one of: repo, application_id, threat_model_id, or campaign_id " +
57
+ text: "Error: Provide at least one of: repo, application_id, or campaign_id " +
63
58
  "(or set applicationId in .zivis/project.json for default app scope)",
64
59
  }],
65
60
  isError: true,
@@ -69,7 +64,7 @@ export function createSecurityReviewHandler(apiClient, config) {
69
64
  const context = {
70
65
  _description: "ZIVIS Security Review Context — use this intelligence during code review",
71
66
  generatedAt: new Date().toISOString(),
72
- parameters: { repo, application_id, threat_model_id, campaign_id },
67
+ parameters: { repo, application_id, campaign_id },
73
68
  };
74
69
  const errors = [];
75
70
  if (shouldInclude("regression") && (repo || application_id)) {
@@ -117,76 +112,6 @@ export function createSecurityReviewHandler(apiClient, config) {
117
112
  errors.push(`Open findings: ${err instanceof Error ? err.message : "failed"}`);
118
113
  }
119
114
  }
120
- if ((shouldInclude("controls") || shouldInclude("attack_scenarios")) && threat_model_id) {
121
- let tm = null;
122
- try {
123
- tm = await apiClient.get(`/api/threat-models/${threat_model_id}?include=all`);
124
- }
125
- catch (err) {
126
- errors.push(`Threat model fetch: ${err instanceof Error ? err.message : "failed"}`);
127
- }
128
- const versions = Array.isArray(tm?.versions) ? tm.versions : [];
129
- const latestVersion = versions[0] || {};
130
- if (tm && shouldInclude("controls")) {
131
- try {
132
- const controls = Array.isArray(latestVersion.securityControls)
133
- ? latestVersion.securityControls
134
- : [];
135
- const notImplemented = controls.filter((c) => c.status === "not_implemented");
136
- const partial = controls.filter((c) => c.status === "partial");
137
- const implemented = controls.filter((c) => c.status === "implemented");
138
- context.securityControls = {
139
- _instruction: "Verify that code implements these expected security controls. Flag missing or weak implementations.",
140
- summary: {
141
- implemented: implemented.length,
142
- partial: partial.length,
143
- notImplemented: notImplemented.length,
144
- },
145
- gapControls: [...notImplemented, ...partial].map((c) => ({
146
- name: c.name,
147
- type: c.controlType,
148
- status: c.status,
149
- description: c.description,
150
- effectiveness: c.effectivenessRating,
151
- })),
152
- implementedControls: implemented.map((c) => ({
153
- name: c.name,
154
- type: c.controlType,
155
- description: c.description,
156
- })),
157
- };
158
- }
159
- catch (err) {
160
- errors.push(`Security controls: ${err instanceof Error ? err.message : "failed"}`);
161
- }
162
- }
163
- if (tm && shouldInclude("attack_scenarios")) {
164
- try {
165
- const scenarios = Array.isArray(latestVersion.attackScenarios)
166
- ? latestVersion.attackScenarios
167
- : [];
168
- const minSeverity = SEVERITY_ORDER[severity_threshold] || 2;
169
- const filtered = scenarios.filter((s) => (SEVERITY_ORDER[s.severity] || 1) >= minSeverity);
170
- context.attackScenarios = {
171
- _instruction: "Review code for susceptibility to these known attack vectors. Check that mitigations are in place.",
172
- count: filtered.length,
173
- scenarios: filtered.map((s) => ({
174
- displayId: s.displayId,
175
- title: s.title,
176
- strideCategory: s.strideCategory,
177
- severity: s.severity,
178
- likelihood: s.likelihood,
179
- riskScore: s.riskScore,
180
- status: s.status,
181
- narrative: s.narrative,
182
- })),
183
- };
184
- }
185
- catch (err) {
186
- errors.push(`Attack scenarios: ${err instanceof Error ? err.message : "failed"}`);
187
- }
188
- }
189
- }
190
115
  if (shouldInclude("dependencies") && dependency_list && dependency_list.length > 0) {
191
116
  const depResults = [];
192
117
  const baseUrl = config.apiBaseUrl;
@@ -330,17 +255,6 @@ function buildReviewGuidance(context) {
330
255
  if (open?.count > 0) {
331
256
  guidance.push(`OPEN VULNS: ${open.count} known vulnerabilities (${open.bySeverity?.critical || 0} critical, ${open.bySeverity?.high || 0} high). Verify changes don't worsen these.`);
332
257
  }
333
- const controls = context.securityControls;
334
- if (controls) {
335
- const gaps = controls.summary?.notImplemented + controls.summary?.partial;
336
- if (gaps > 0) {
337
- guidance.push(`CONTROL GAPS: ${gaps} security controls are missing or partial. Check if code should implement them.`);
338
- }
339
- }
340
- const attacks = context.attackScenarios;
341
- if (attacks?.count > 0) {
342
- guidance.push(`ATTACK VECTORS: ${attacks.count} known attack scenarios. Verify code is resilient to these.`);
343
- }
344
258
  const deps = context.dependencyRisks;
345
259
  if (deps?.riskyCount > 0) {
346
260
  guidance.push(`RISKY DEPS: ${deps.riskyCount} dependencies with low trust scores. Consider alternatives.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zivis/mcp",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "ZIVIS MCP server — threat modeling, security scans, and AI red team tools for IDE integration",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://zivis.ai",
@@ -1,22 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const GET_THREAT_MODEL_NAME = "zivis_get_threat_model";
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.";
5
- export declare const GET_THREAT_MODEL_SCHEMA: {
6
- threat_model_id: z.ZodString;
7
- };
8
- export declare function createGetThreatModelHandler(apiClient: ApiClient): (params: {
9
- threat_model_id: string;
10
- }) => Promise<{
11
- content: {
12
- type: "text";
13
- text: string;
14
- }[];
15
- isError?: undefined;
16
- } | {
17
- content: {
18
- type: "text";
19
- text: string;
20
- }[];
21
- isError: boolean;
22
- }>;
@@ -1,61 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const GET_THREAT_MODEL_NAME = "zivis_get_threat_model";
4
- export const GET_THREAT_MODEL_DESCRIPTION = `Get a threat model — its metadata, status, owning application, and linked diagrams.
5
-
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\`.
10
-
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.`;
12
- export const GET_THREAT_MODEL_SCHEMA = {
13
- threat_model_id: z
14
- .string()
15
- .describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
16
- };
17
- export function createGetThreatModelHandler(apiClient) {
18
- return async (params) => {
19
- try {
20
- const [threatModelData, diagramsData] = await Promise.all([
21
- apiClient.get(`/api/threat-models/${params.threat_model_id}`),
22
- apiClient
23
- .get(`/api/diagrams?linkedThreatModelId=${params.threat_model_id}&take=50`)
24
- .catch(() => ({ diagrams: [], total: 0 })),
25
- ]);
26
- const sanitized = sanitizeResponse(threatModelData);
27
- const linkedDiagrams = Array.isArray(diagramsData.diagrams)
28
- ? diagramsData.diagrams.map((d) => ({
29
- diagram_id: d.id,
30
- name: d.name,
31
- diagram_type: d.diagramType,
32
- content_type: d.contentType,
33
- description: d.description || null,
34
- node_count: d._count?.nodes ?? null,
35
- connection_count: d._count?.connections ?? null,
36
- updated_at: d.updatedAt,
37
- }))
38
- : [];
39
- const result = {
40
- ...sanitized,
41
- linked_diagrams: linkedDiagrams,
42
- linked_diagrams_count: diagramsData.total,
43
- };
44
- return {
45
- content: [
46
- {
47
- type: "text",
48
- text: JSON.stringify(result, null, 2),
49
- },
50
- ],
51
- };
52
- }
53
- catch (err) {
54
- const message = err instanceof Error ? err.message : "Failed to get threat model";
55
- return {
56
- content: [{ type: "text", text: `Error: ${message}` }],
57
- isError: true,
58
- };
59
- }
60
- };
61
- }
@@ -1,24 +0,0 @@
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
- }>;
@@ -1,63 +0,0 @@
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,31 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const LIST_THREAT_MODELS_NAME = "zivis_list_threat_models";
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.";
5
- export declare const LIST_THREAT_MODELS_SCHEMA: {
6
- status: z.ZodOptional<z.ZodEnum<{
7
- draft: "draft";
8
- analyzing: "analyzing";
9
- analyzed: "analyzed";
10
- reviewed: "reviewed";
11
- approved: "approved";
12
- archived: "archived";
13
- }>>;
14
- limit: z.ZodDefault<z.ZodNumber>;
15
- };
16
- export declare function createListThreatModelsHandler(apiClient: ApiClient): (params: {
17
- status?: string;
18
- limit?: number;
19
- }) => Promise<{
20
- content: {
21
- type: "text";
22
- text: string;
23
- }[];
24
- isError?: undefined;
25
- } | {
26
- content: {
27
- type: "text";
28
- text: string;
29
- }[];
30
- isError: boolean;
31
- }>;
@@ -1,74 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const LIST_THREAT_MODELS_NAME = "zivis_list_threat_models";
4
- export 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.
5
-
6
- Also 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.
7
-
8
- IMPORTANT: Threat models are NOT scans and NOT agents. They are separate entities:
9
- - A **threat model** (returned here) has its own UUID and contains components, data flows, actors, findings, etc.
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.
11
- - An **agent instance** is a configured agent (from the UI) — agents RUN scans which produce threat models.
12
-
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.`;
14
- export const LIST_THREAT_MODELS_SCHEMA = {
15
- status: z
16
- .enum(["draft", "analyzing", "analyzed", "reviewed", "approved", "archived"])
17
- .optional()
18
- .describe("Filter by threat model status"),
19
- limit: z
20
- .number()
21
- .min(1)
22
- .max(100)
23
- .default(20)
24
- .describe("Maximum number of results (1-100, default 20)"),
25
- };
26
- export function createListThreatModelsHandler(apiClient) {
27
- return async (params) => {
28
- try {
29
- const query = new URLSearchParams();
30
- if (params.status)
31
- query.set("status", params.status);
32
- if (params.limit)
33
- query.set("limit", String(params.limit));
34
- const queryStr = query.toString();
35
- const path = `/api/threat-models${queryStr ? `?${queryStr}` : ""}`;
36
- const data = await apiClient.get(path);
37
- const sanitized = sanitizeResponse(data);
38
- const threatModels = Array.isArray(sanitized) ? sanitized : [];
39
- const diagramCounts = await Promise.all(threatModels.map((tm) => apiClient
40
- .get(`/api/diagrams?linkedThreatModelId=${tm.id}&take=1`)
41
- .then((res) => res.total ?? 0)
42
- .catch(() => 0)));
43
- const summary = Array.isArray(sanitized)
44
- ? sanitized.map((tm, i) => ({
45
- threat_model_id: tm.id,
46
- name: tm.name,
47
- status: tm.status,
48
- description: tm.description,
49
- application: tm.applicationName || null,
50
- campaign: tm.campaignName || null,
51
- latest_version: tm.latestVersion || null,
52
- linked_diagrams_count: diagramCounts[i],
53
- created_at: tm.createdAt,
54
- updated_at: tm.updatedAt,
55
- }))
56
- : sanitized;
57
- return {
58
- content: [
59
- {
60
- type: "text",
61
- text: JSON.stringify(summary, null, 2),
62
- },
63
- ],
64
- };
65
- }
66
- catch (err) {
67
- const message = err instanceof Error ? err.message : "Failed to list threat models";
68
- return {
69
- content: [{ type: "text", text: `Error: ${message}` }],
70
- isError: true,
71
- };
72
- }
73
- };
74
- }
@@ -1,53 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const MANAGE_ACTOR_NAME = "zivis_manage_actor";
4
- export declare const MANAGE_ACTOR_DESCRIPTION = "Create, update, or delete a threat actor in a threat model.\n\nWhen to use (plain English): call this when the user describes who interacts with or threatens the app. Common phrasings:\n- \"users / end users / customers / our users can ...\"\n- \"admins / support team / internal employees ...\"\n- \"attacker / adversary / bad actor / malicious user ...\"\n- \"insider / rogue employee ...\"\n- \"vendor / partner / integration partner ...\"\n- \"bot / scraper / automated agent ...\"\n- \"<external service> calls our API\" (the external service is an actor too)\n\n\nThreat actors represent entities that interact with or threaten the system. Each actor has a trust level, type, and capabilities.\n\nAfter create: ask which components this actor interacts with so a data flow can be modeled.\n\nActions:\n- create: Add a new threat actor (requires name, actor_type, trust_level)\n- update: Modify an existing actor (requires actor_id)\n- delete: Remove an actor (requires actor_id)";
5
- export declare const MANAGE_ACTOR_SCHEMA: {
6
- threat_model_id: z.ZodString;
7
- action: z.ZodEnum<{
8
- create: "create";
9
- update: "update";
10
- delete: "delete";
11
- }>;
12
- actor_id: z.ZodOptional<z.ZodString>;
13
- name: z.ZodOptional<z.ZodString>;
14
- actor_type: z.ZodOptional<z.ZodEnum<{
15
- third_party: "third_party";
16
- external: "external";
17
- internal: "internal";
18
- system: "system";
19
- }>>;
20
- trust_level: z.ZodOptional<z.ZodEnum<{
21
- high: "high";
22
- medium: "medium";
23
- low: "low";
24
- untrusted: "untrusted";
25
- privileged: "privileged";
26
- }>>;
27
- description: z.ZodOptional<z.ZodString>;
28
- motivation: z.ZodOptional<z.ZodString>;
29
- capabilities: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
- };
31
- export declare function createManageActorHandler(apiClient: ApiClient): (params: {
32
- threat_model_id: string;
33
- action: "create" | "update" | "delete";
34
- actor_id?: string;
35
- name?: string;
36
- actor_type?: string;
37
- trust_level?: string;
38
- description?: string;
39
- motivation?: string;
40
- capabilities?: string[];
41
- }) => Promise<{
42
- content: {
43
- type: "text";
44
- text: string;
45
- }[];
46
- isError: boolean;
47
- } | {
48
- content: {
49
- type: "text";
50
- text: string;
51
- }[];
52
- isError?: undefined;
53
- }>;
@@ -1,105 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const MANAGE_ACTOR_NAME = "zivis_manage_actor";
4
- export const MANAGE_ACTOR_DESCRIPTION = `Create, update, or delete a threat actor in a threat model.
5
-
6
- When to use (plain English): call this when the user describes who interacts with or threatens the app. Common phrasings:
7
- - "users / end users / customers / our users can ..."
8
- - "admins / support team / internal employees ..."
9
- - "attacker / adversary / bad actor / malicious user ..."
10
- - "insider / rogue employee ..."
11
- - "vendor / partner / integration partner ..."
12
- - "bot / scraper / automated agent ..."
13
- - "<external service> calls our API" (the external service is an actor too)
14
-
15
-
16
- Threat actors represent entities that interact with or threaten the system. Each actor has a trust level, type, and capabilities.
17
-
18
- After create: ask which components this actor interacts with so a data flow can be modeled.
19
-
20
- Actions:
21
- - create: Add a new threat actor (requires name, actor_type, trust_level)
22
- - update: Modify an existing actor (requires actor_id)
23
- - delete: Remove an actor (requires actor_id)`;
24
- export const MANAGE_ACTOR_SCHEMA = {
25
- threat_model_id: z.string().describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
26
- action: z.enum(["create", "update", "delete"]).describe("CRUD action to perform"),
27
- actor_id: z.string().optional().describe("Actor UUID (required for update/delete)"),
28
- name: z.string().optional().describe("Actor name (e.g., 'External Attacker', 'API Consumer')"),
29
- actor_type: z
30
- .enum(["external", "internal", "system", "third_party"])
31
- .optional()
32
- .describe("Type of threat actor"),
33
- trust_level: z
34
- .enum(["untrusted", "low", "medium", "high", "privileged"])
35
- .optional()
36
- .describe("Trust level assigned to this actor"),
37
- description: z.string().optional().describe("Description of the actor's role and intent"),
38
- motivation: z.string().optional().describe("Actor's motivation (e.g., financial gain, espionage)"),
39
- capabilities: z.array(z.string()).optional().describe("Actor capabilities (e.g., ['network_access', 'social_engineering'])"),
40
- };
41
- export function createManageActorHandler(apiClient) {
42
- return async (params) => {
43
- try {
44
- const { threat_model_id, action, actor_id } = params;
45
- if ((action === "update" || action === "delete") && !actor_id) {
46
- return {
47
- content: [{ type: "text", text: "Error: actor_id is required for update/delete" }],
48
- isError: true,
49
- };
50
- }
51
- let data;
52
- if (action === "create") {
53
- if (!params.name || !params.actor_type || !params.trust_level) {
54
- return {
55
- content: [{ type: "text", text: "Error: name, actor_type, and trust_level are required for create" }],
56
- isError: true,
57
- };
58
- }
59
- data = await apiClient.post(`/api/threat-models/${threat_model_id}/actors`, {
60
- name: params.name,
61
- actorType: params.actor_type,
62
- trustLevel: params.trust_level,
63
- description: params.description,
64
- motivation: params.motivation,
65
- capabilities: params.capabilities,
66
- });
67
- }
68
- else if (action === "update") {
69
- const body = {};
70
- if (params.name)
71
- body.name = params.name;
72
- if (params.actor_type)
73
- body.actorType = params.actor_type;
74
- if (params.trust_level)
75
- body.trustLevel = params.trust_level;
76
- if (params.description !== undefined)
77
- body.description = params.description;
78
- if (params.motivation !== undefined)
79
- body.motivation = params.motivation;
80
- if (params.capabilities)
81
- body.capabilities = params.capabilities;
82
- data = await apiClient.patch(`/api/threat-models/${threat_model_id}/actors/${actor_id}`, body);
83
- }
84
- else {
85
- data = await apiClient.del(`/api/threat-models/${threat_model_id}/actors/${actor_id}`);
86
- }
87
- const sanitized = sanitizeResponse(data);
88
- return {
89
- content: [
90
- {
91
- type: "text",
92
- text: JSON.stringify(sanitized, null, 2),
93
- },
94
- ],
95
- };
96
- }
97
- catch (err) {
98
- const message = err instanceof Error ? err.message : "Failed to manage actor";
99
- return {
100
- content: [{ type: "text", text: `Error: ${message}` }],
101
- isError: true,
102
- };
103
- }
104
- };
105
- }
@@ -1,65 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const MANAGE_ATTACK_SCENARIO_NAME = "zivis_manage_attack_scenario";
4
- export declare const MANAGE_ATTACK_SCENARIO_DESCRIPTION = "Create, update, or delete an attack scenario in a threat model.\n\nWhen to use (plain English): call this when the user describes a security worry, \"what if\" question, or specific failure mode. Common phrasings:\n- \"what if <bad thing happens>\"\n- \"could someone <attack action>\"\n- \"I'm worried about <X> being abused / leaked / hacked\"\n- \"how would an attacker <do X>\"\n- \"is <Y> safe from <Z>\"\n- mentions of: prompt injection, jailbreak, data exfiltration, privilege escalation, account takeover, supply chain, abuse\n\nBefore creating a scenario, the threat model needs at least one entry_point component (where the attack starts) and a target component (where the attacker wants to go). If either is missing, model components first.\n\nThe narrative should be a 2\u20135 sentence story: who attacks, where they enter, what they exploit, what they achieve. Don't write a textbook chapter.\n\n\nActions:\n- create: Add a new scenario (requires title, narrative, entry_point_id, target_id)\n- update: Update scenario status/notes (requires scenario_id)\n- delete: Remove a scenario (requires scenario_id)";
5
- export declare const MANAGE_ATTACK_SCENARIO_SCHEMA: {
6
- threat_model_id: z.ZodString;
7
- action: z.ZodEnum<{
8
- create: "create";
9
- update: "update";
10
- delete: "delete";
11
- }>;
12
- scenario_id: z.ZodOptional<z.ZodString>;
13
- title: z.ZodOptional<z.ZodString>;
14
- narrative: z.ZodOptional<z.ZodString>;
15
- entry_point_id: z.ZodOptional<z.ZodString>;
16
- target_id: z.ZodOptional<z.ZodString>;
17
- severity: z.ZodOptional<z.ZodEnum<{
18
- critical: "critical";
19
- high: "high";
20
- medium: "medium";
21
- low: "low";
22
- info: "info";
23
- }>>;
24
- likelihood: z.ZodOptional<z.ZodEnum<{
25
- almost_certain: "almost_certain";
26
- likely: "likely";
27
- possible: "possible";
28
- unlikely: "unlikely";
29
- }>>;
30
- actor_id: z.ZodOptional<z.ZodString>;
31
- goal_category: z.ZodOptional<z.ZodString>;
32
- goal_description: z.ZodOptional<z.ZodString>;
33
- business_impact: z.ZodOptional<z.ZodString>;
34
- status: z.ZodOptional<z.ZodString>;
35
- user_notes: z.ZodOptional<z.ZodString>;
36
- };
37
- export declare function createManageAttackScenarioHandler(apiClient: ApiClient): (params: {
38
- threat_model_id: string;
39
- action: "create" | "update" | "delete";
40
- scenario_id?: string;
41
- title?: string;
42
- narrative?: string;
43
- entry_point_id?: string;
44
- target_id?: string;
45
- severity?: string;
46
- likelihood?: string;
47
- actor_id?: string;
48
- goal_category?: string;
49
- goal_description?: string;
50
- business_impact?: string;
51
- status?: string;
52
- user_notes?: string;
53
- }) => Promise<{
54
- content: {
55
- type: "text";
56
- text: string;
57
- }[];
58
- isError: boolean;
59
- } | {
60
- content: {
61
- type: "text";
62
- text: string;
63
- }[];
64
- isError?: undefined;
65
- }>;
@@ -1,94 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const MANAGE_ATTACK_SCENARIO_NAME = "zivis_manage_attack_scenario";
4
- export const MANAGE_ATTACK_SCENARIO_DESCRIPTION = `Create, update, or delete an attack scenario in a threat model.
5
-
6
- When to use (plain English): call this when the user describes a security worry, "what if" question, or specific failure mode. Common phrasings:
7
- - "what if <bad thing happens>"
8
- - "could someone <attack action>"
9
- - "I'm worried about <X> being abused / leaked / hacked"
10
- - "how would an attacker <do X>"
11
- - "is <Y> safe from <Z>"
12
- - mentions of: prompt injection, jailbreak, data exfiltration, privilege escalation, account takeover, supply chain, abuse
13
-
14
- Before creating a scenario, the threat model needs at least one entry_point component (where the attack starts) and a target component (where the attacker wants to go). If either is missing, model components first.
15
-
16
- The narrative should be a 2–5 sentence story: who attacks, where they enter, what they exploit, what they achieve. Don't write a textbook chapter.
17
-
18
-
19
- Actions:
20
- - create: Add a new scenario (requires title, narrative, entry_point_id, target_id)
21
- - update: Update scenario status/notes (requires scenario_id)
22
- - delete: Remove a scenario (requires scenario_id)`;
23
- export const MANAGE_ATTACK_SCENARIO_SCHEMA = {
24
- threat_model_id: z.string().describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
25
- action: z.enum(["create", "update", "delete"]).describe("CRUD action to perform"),
26
- scenario_id: z.string().optional().describe("Scenario UUID (required for update/delete)"),
27
- title: z.string().optional().describe("Scenario title (e.g., 'Privilege Escalation via API') — required for create"),
28
- narrative: z.string().optional().describe("Detailed narrative of the attack path (markdown supported) — required for create"),
29
- entry_point_id: z.string().optional().describe("Entry point component UUID — required for create"),
30
- target_id: z.string().optional().describe("Target component UUID — required for create"),
31
- severity: z.enum(["critical", "high", "medium", "low", "info"]).optional().describe("Severity of this scenario (for create)"),
32
- likelihood: z.enum(["almost_certain", "likely", "possible", "unlikely"]).optional().describe("Likelihood of this scenario being exploited (for create)"),
33
- actor_id: z.string().optional().describe("Threat actor UUID who would execute this scenario (for create)"),
34
- goal_category: z.string().optional().describe("Terminal goal category (for create)"),
35
- goal_description: z.string().optional().describe("Description of the attacker's goal (for create)"),
36
- business_impact: z.string().optional().describe("Business impact if the attack succeeds (for create)"),
37
- status: z.string().optional().describe("Scenario status (for update)"),
38
- user_notes: z.string().optional().describe("Review notes (for update)"),
39
- };
40
- export function createManageAttackScenarioHandler(apiClient) {
41
- return async (params) => {
42
- try {
43
- const { threat_model_id, action, scenario_id } = params;
44
- if ((action === "update" || action === "delete") && !scenario_id) {
45
- return {
46
- content: [{ type: "text", text: "Error: scenario_id is required for update/delete" }],
47
- isError: true,
48
- };
49
- }
50
- let data;
51
- if (action === "create") {
52
- if (!params.title || !params.narrative || !params.entry_point_id || !params.target_id) {
53
- return {
54
- content: [{ type: "text", text: "Error: title, narrative, entry_point_id, and target_id are required for create" }],
55
- isError: true,
56
- };
57
- }
58
- data = await apiClient.post(`/api/threat-models/${threat_model_id}/attack-scenarios`, {
59
- title: params.title,
60
- narrative: params.narrative,
61
- entryPointId: params.entry_point_id,
62
- targetId: params.target_id,
63
- severity: params.severity,
64
- likelihood: params.likelihood,
65
- actorId: params.actor_id,
66
- goalCategory: params.goal_category,
67
- goalDescription: params.goal_description,
68
- businessImpact: params.business_impact,
69
- });
70
- }
71
- else if (action === "update") {
72
- const body = {};
73
- if (params.status !== undefined)
74
- body.status = params.status;
75
- if (params.user_notes !== undefined)
76
- body.userNotes = params.user_notes;
77
- data = await apiClient.patch(`/api/threat-models/${threat_model_id}/attack-scenarios/${scenario_id}`, body);
78
- }
79
- else {
80
- data = await apiClient.del(`/api/threat-models/${threat_model_id}/attack-scenarios/${scenario_id}`);
81
- }
82
- return {
83
- content: [{ type: "text", text: JSON.stringify(sanitizeResponse(data), null, 2) }],
84
- };
85
- }
86
- catch (err) {
87
- const message = err instanceof Error ? err.message : "Failed to manage attack scenario";
88
- return {
89
- content: [{ type: "text", text: `Error: ${message}` }],
90
- isError: true,
91
- };
92
- }
93
- };
94
- }
@@ -1,48 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const MANAGE_DATA_ASSET_NAME = "zivis_manage_data_asset";
4
- export declare const MANAGE_DATA_ASSET_DESCRIPTION = "Create, update, or delete a data asset in a threat model.\n\nWhen to use (plain English): call this when the user names something the app stores or processes. Common phrasings:\n- \"we store <PII / credit card / passwords / session tokens / api keys / audit logs>\"\n- \"the <user / customer / patient> data is in <storage>\"\n- \"we keep <emails / phone numbers / SSN / addresses>\"\n- \"<asset> is encrypted at rest\" \u2014 model the asset, then a security control on top of it\n- \"we hold cardholder data\" / \"we handle payment cards\" \u2192 classification=restricted, data_type=payment_data\n\nPick classification:\n- public \u2014 anyone can see (marketing copy)\n- internal \u2014 employees only (org chart, internal docs)\n- confidential \u2014 PII, business confidential\n- restricted \u2014 payment data, health records, anything regulated\n- critical \u2014 credentials, secrets, root keys, anything an attacker would target first\n\n\nAfter create: ask which components store, process, or transmit this asset so coverage can be linked. If the asset is sensitive (confidential or higher) and no security control covers it, surface that gap.\n\nActions:\n- create: Add a new data asset (requires name, classification)\n- update: Modify an existing data asset (requires asset_id)\n- delete: Remove a data asset (requires asset_id)";
5
- export declare const MANAGE_DATA_ASSET_SCHEMA: {
6
- threat_model_id: z.ZodString;
7
- action: z.ZodEnum<{
8
- create: "create";
9
- update: "update";
10
- delete: "delete";
11
- }>;
12
- asset_id: z.ZodOptional<z.ZodString>;
13
- name: z.ZodOptional<z.ZodString>;
14
- classification: z.ZodOptional<z.ZodEnum<{
15
- critical: "critical";
16
- public: "public";
17
- internal: "internal";
18
- confidential: "confidential";
19
- restricted: "restricted";
20
- }>>;
21
- description: z.ZodOptional<z.ZodString>;
22
- data_type: z.ZodOptional<z.ZodString>;
23
- storage_location: z.ZodOptional<z.ZodString>;
24
- retention_policy: z.ZodOptional<z.ZodString>;
25
- };
26
- export declare function createManageDataAssetHandler(apiClient: ApiClient): (params: {
27
- threat_model_id: string;
28
- action: "create" | "update" | "delete";
29
- asset_id?: string;
30
- name?: string;
31
- classification?: string;
32
- description?: string;
33
- data_type?: string;
34
- storage_location?: string;
35
- retention_policy?: string;
36
- }) => Promise<{
37
- content: {
38
- type: "text";
39
- text: string;
40
- }[];
41
- isError: boolean;
42
- } | {
43
- content: {
44
- type: "text";
45
- text: string;
46
- }[];
47
- isError?: undefined;
48
- }>;
@@ -1,99 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const MANAGE_DATA_ASSET_NAME = "zivis_manage_data_asset";
4
- export const MANAGE_DATA_ASSET_DESCRIPTION = `Create, update, or delete a data asset in a threat model.
5
-
6
- When to use (plain English): call this when the user names something the app stores or processes. Common phrasings:
7
- - "we store <PII / credit card / passwords / session tokens / api keys / audit logs>"
8
- - "the <user / customer / patient> data is in <storage>"
9
- - "we keep <emails / phone numbers / SSN / addresses>"
10
- - "<asset> is encrypted at rest" — model the asset, then a security control on top of it
11
- - "we hold cardholder data" / "we handle payment cards" → classification=restricted, data_type=payment_data
12
-
13
- Pick classification:
14
- - public — anyone can see (marketing copy)
15
- - internal — employees only (org chart, internal docs)
16
- - confidential — PII, business confidential
17
- - restricted — payment data, health records, anything regulated
18
- - critical — credentials, secrets, root keys, anything an attacker would target first
19
-
20
-
21
- After create: ask which components store, process, or transmit this asset so coverage can be linked. If the asset is sensitive (confidential or higher) and no security control covers it, surface that gap.
22
-
23
- Actions:
24
- - create: Add a new data asset (requires name, classification)
25
- - update: Modify an existing data asset (requires asset_id)
26
- - delete: Remove a data asset (requires asset_id)`;
27
- export const MANAGE_DATA_ASSET_SCHEMA = {
28
- threat_model_id: z.string().describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
29
- action: z.enum(["create", "update", "delete"]).describe("CRUD action to perform"),
30
- asset_id: z.string().optional().describe("Asset UUID (required for update/delete)"),
31
- name: z.string().optional().describe("Asset name (e.g., 'User PII', 'API Keys')"),
32
- classification: z
33
- .enum(["public", "internal", "confidential", "restricted", "critical"])
34
- .optional()
35
- .describe("Data classification level"),
36
- description: z.string().optional().describe("Description of the data asset"),
37
- data_type: z.string().optional().describe("Type of data (e.g., 'credentials', 'pii', 'financial')"),
38
- storage_location: z.string().optional().describe("Where this data is stored"),
39
- retention_policy: z.string().optional().describe("Data retention policy"),
40
- };
41
- export function createManageDataAssetHandler(apiClient) {
42
- return async (params) => {
43
- try {
44
- const { threat_model_id, action, asset_id } = params;
45
- if ((action === "update" || action === "delete") && !asset_id) {
46
- return {
47
- content: [{ type: "text", text: "Error: asset_id is required for update/delete" }],
48
- isError: true,
49
- };
50
- }
51
- let data;
52
- if (action === "create") {
53
- if (!params.name || !params.classification) {
54
- return {
55
- content: [{ type: "text", text: "Error: name and classification are required for create" }],
56
- isError: true,
57
- };
58
- }
59
- data = await apiClient.post(`/api/threat-models/${threat_model_id}/data-assets`, {
60
- name: params.name,
61
- classification: params.classification,
62
- description: params.description,
63
- dataType: params.data_type,
64
- storageLocation: params.storage_location,
65
- retentionPolicy: params.retention_policy,
66
- });
67
- }
68
- else if (action === "update") {
69
- const body = {};
70
- if (params.name)
71
- body.name = params.name;
72
- if (params.classification)
73
- body.classification = params.classification;
74
- if (params.description !== undefined)
75
- body.description = params.description;
76
- if (params.data_type)
77
- body.dataType = params.data_type;
78
- if (params.storage_location !== undefined)
79
- body.storageLocation = params.storage_location;
80
- if (params.retention_policy !== undefined)
81
- body.retentionPolicy = params.retention_policy;
82
- data = await apiClient.patch(`/api/threat-models/${threat_model_id}/data-assets/${asset_id}`, body);
83
- }
84
- else {
85
- data = await apiClient.del(`/api/threat-models/${threat_model_id}/data-assets/${asset_id}`);
86
- }
87
- return {
88
- content: [{ type: "text", text: JSON.stringify(sanitizeResponse(data), null, 2) }],
89
- };
90
- }
91
- catch (err) {
92
- const message = err instanceof Error ? err.message : "Failed to manage data asset";
93
- return {
94
- content: [{ type: "text", text: `Error: ${message}` }],
95
- isError: true,
96
- };
97
- }
98
- };
99
- }
@@ -1,54 +0,0 @@
1
- import { z } from "zod";
2
- import type { ApiClient } from "../../api-client.js";
3
- export declare const MANAGE_SECURITY_CONTROL_NAME = "zivis_manage_security_control";
4
- export declare const MANAGE_SECURITY_CONTROL_DESCRIPTION = "Create, update, or delete a security control in a threat model.\n\nWhen to use (plain English): call this when the user mentions a protective mechanism that's in place (or planned). Common phrasings:\n- \"we have <rate limiting / WAF / firewall / MFA / 2FA / encryption>\"\n- \"we sanitize / validate <inputs>\"\n- \"we encrypt <X> at rest / in transit\"\n- \"we audit log all <Y>\"\n- \"<Z> is behind auth / behind a VPN\"\n- \"we use TLS for everything\"\n\nPick control_type:\n- preventive \u2014 stops the threat before it happens (input validation, rate limiting, encryption, MFA)\n- detective \u2014 notices when something bad happens (audit logging, monitoring, alerts, anomaly detection)\n- responsive \u2014 reacts to a known incident (auto-block, key rotation, account lockout)\n\nSet component_id when the control applies to one specific component. Leave it blank for org-wide controls (e.g., \"we use a WAF in front of everything\").\n\n\nAfter create: if a sensitive data asset (PII / payment / credentials) exists with no controls covering it, that's a high-priority gap \u2014 flag it.\n\nActions:\n- create: Add a new control (requires name, control_type)\n- update: Modify an existing control (requires control_id)\n- delete: Remove a control (requires control_id)";
5
- export declare const MANAGE_SECURITY_CONTROL_SCHEMA: {
6
- threat_model_id: z.ZodString;
7
- action: z.ZodEnum<{
8
- create: "create";
9
- update: "update";
10
- delete: "delete";
11
- }>;
12
- control_id: z.ZodOptional<z.ZodString>;
13
- name: z.ZodOptional<z.ZodString>;
14
- control_type: z.ZodOptional<z.ZodEnum<{
15
- preventive: "preventive";
16
- detective: "detective";
17
- responsive: "responsive";
18
- }>>;
19
- description: z.ZodOptional<z.ZodString>;
20
- status: z.ZodOptional<z.ZodEnum<{
21
- not_implemented: "not_implemented";
22
- partial: "partial";
23
- implemented: "implemented";
24
- }>>;
25
- effectiveness_rating: z.ZodOptional<z.ZodEnum<{
26
- high: "high";
27
- medium: "medium";
28
- low: "low";
29
- }>>;
30
- component_id: z.ZodOptional<z.ZodString>;
31
- };
32
- export declare function createManageSecurityControlHandler(apiClient: ApiClient): (params: {
33
- threat_model_id: string;
34
- action: "create" | "update" | "delete";
35
- control_id?: string;
36
- name?: string;
37
- control_type?: string;
38
- description?: string;
39
- status?: string;
40
- effectiveness_rating?: string;
41
- component_id?: string;
42
- }) => Promise<{
43
- content: {
44
- type: "text";
45
- text: string;
46
- }[];
47
- isError: boolean;
48
- } | {
49
- content: {
50
- type: "text";
51
- text: string;
52
- }[];
53
- isError?: undefined;
54
- }>;
@@ -1,106 +0,0 @@
1
- import { z } from "zod";
2
- import { sanitizeResponse } from "../../sanitize.js";
3
- export const MANAGE_SECURITY_CONTROL_NAME = "zivis_manage_security_control";
4
- export const MANAGE_SECURITY_CONTROL_DESCRIPTION = `Create, update, or delete a security control in a threat model.
5
-
6
- When to use (plain English): call this when the user mentions a protective mechanism that's in place (or planned). Common phrasings:
7
- - "we have <rate limiting / WAF / firewall / MFA / 2FA / encryption>"
8
- - "we sanitize / validate <inputs>"
9
- - "we encrypt <X> at rest / in transit"
10
- - "we audit log all <Y>"
11
- - "<Z> is behind auth / behind a VPN"
12
- - "we use TLS for everything"
13
-
14
- Pick control_type:
15
- - preventive — stops the threat before it happens (input validation, rate limiting, encryption, MFA)
16
- - detective — notices when something bad happens (audit logging, monitoring, alerts, anomaly detection)
17
- - responsive — reacts to a known incident (auto-block, key rotation, account lockout)
18
-
19
- Set component_id when the control applies to one specific component. Leave it blank for org-wide controls (e.g., "we use a WAF in front of everything").
20
-
21
-
22
- After create: if a sensitive data asset (PII / payment / credentials) exists with no controls covering it, that's a high-priority gap — flag it.
23
-
24
- Actions:
25
- - create: Add a new control (requires name, control_type)
26
- - update: Modify an existing control (requires control_id)
27
- - delete: Remove a control (requires control_id)`;
28
- export const MANAGE_SECURITY_CONTROL_SCHEMA = {
29
- threat_model_id: z.string().describe("Threat model UUID (from zivis_list_threat_models, NOT a scan ID or agent ID)"),
30
- action: z.enum(["create", "update", "delete"]).describe("CRUD action to perform"),
31
- control_id: z.string().optional().describe("Control UUID (required for update/delete)"),
32
- name: z.string().optional().describe("Control name (e.g., 'Input Validation', 'Rate Limiting')"),
33
- control_type: z
34
- .enum(["preventive", "detective", "responsive"])
35
- .optional()
36
- .describe("Type of security control"),
37
- description: z.string().optional().describe("Description of how the control works"),
38
- status: z
39
- .enum(["not_implemented", "partial", "implemented"])
40
- .optional()
41
- .describe("Current implementation status"),
42
- effectiveness_rating: z
43
- .enum(["high", "medium", "low"])
44
- .optional()
45
- .describe("Estimated effectiveness of the control"),
46
- component_id: z.string().optional().describe("Component UUID this control applies to"),
47
- };
48
- export function createManageSecurityControlHandler(apiClient) {
49
- return async (params) => {
50
- try {
51
- const { threat_model_id, action, control_id } = params;
52
- if ((action === "update" || action === "delete") && !control_id) {
53
- return {
54
- content: [{ type: "text", text: "Error: control_id is required for update/delete" }],
55
- isError: true,
56
- };
57
- }
58
- let data;
59
- if (action === "create") {
60
- if (!params.name || !params.control_type) {
61
- return {
62
- content: [{ type: "text", text: "Error: name and control_type are required for create" }],
63
- isError: true,
64
- };
65
- }
66
- data = await apiClient.post(`/api/threat-models/${threat_model_id}/security-controls`, {
67
- name: params.name,
68
- controlType: params.control_type,
69
- description: params.description,
70
- status: params.status,
71
- effectivenessRating: params.effectiveness_rating,
72
- componentId: params.component_id,
73
- });
74
- }
75
- else if (action === "update") {
76
- const body = {};
77
- if (params.name)
78
- body.name = params.name;
79
- if (params.control_type)
80
- body.controlType = params.control_type;
81
- if (params.description !== undefined)
82
- body.description = params.description;
83
- if (params.status)
84
- body.status = params.status;
85
- if (params.effectiveness_rating)
86
- body.effectivenessRating = params.effectiveness_rating;
87
- if (params.component_id)
88
- body.componentId = params.component_id;
89
- data = await apiClient.patch(`/api/threat-models/${threat_model_id}/security-controls/${control_id}`, body);
90
- }
91
- else {
92
- data = await apiClient.del(`/api/threat-models/${threat_model_id}/security-controls/${control_id}`);
93
- }
94
- return {
95
- content: [{ type: "text", text: JSON.stringify(sanitizeResponse(data), null, 2) }],
96
- };
97
- }
98
- catch (err) {
99
- const message = err instanceof Error ? err.message : "Failed to manage security control";
100
- return {
101
- content: [{ type: "text", text: `Error: ${message}` }],
102
- isError: true,
103
- };
104
- }
105
- };
106
- }