@zivis/mcp 0.1.19 → 0.2.2

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 (83) hide show
  1. package/dist/matcher/index.js +1 -1
  2. package/dist/matcher/inference-candidates.js +1 -1
  3. package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +1 -1
  4. package/dist/server.js +22 -143
  5. package/dist/tools/application.d.ts +53 -0
  6. package/dist/tools/application.js +232 -0
  7. package/dist/tools/artifacts.d.ts +21 -57
  8. package/dist/tools/artifacts.js +116 -150
  9. package/dist/tools/devx-run.d.ts +15 -37
  10. package/dist/tools/devx-run.js +66 -77
  11. package/dist/tools/diagram.d.ts +55 -0
  12. package/dist/tools/diagram.js +209 -0
  13. package/dist/tools/document.d.ts +48 -0
  14. package/dist/tools/document.js +137 -0
  15. package/dist/tools/finding.d.ts +133 -0
  16. package/dist/tools/finding.js +211 -0
  17. package/dist/tools/get-started.d.ts +1 -1
  18. package/dist/tools/get-started.js +15 -33
  19. package/dist/tools/security-memory.d.ts +21 -55
  20. package/dist/tools/security-memory.js +93 -138
  21. package/dist/tools/threat-library.d.ts +27 -0
  22. package/dist/tools/threat-library.js +266 -0
  23. package/package.json +1 -1
  24. package/dist/tools/create-diagram.d.ts +0 -39
  25. package/dist/tools/create-diagram.js +0 -74
  26. package/dist/tools/create-document.d.ts +0 -23
  27. package/dist/tools/create-document.js +0 -47
  28. package/dist/tools/create-finding.d.ts +0 -85
  29. package/dist/tools/create-finding.js +0 -136
  30. package/dist/tools/delete-finding.d.ts +0 -19
  31. package/dist/tools/delete-finding.js +0 -36
  32. package/dist/tools/discover-local-infra.d.ts +0 -14
  33. package/dist/tools/discover-local-infra.js +0 -686
  34. package/dist/tools/explain-signal-for-diff.d.ts +0 -34
  35. package/dist/tools/explain-signal-for-diff.js +0 -75
  36. package/dist/tools/get-application-overview.d.ts +0 -22
  37. package/dist/tools/get-application-overview.js +0 -137
  38. package/dist/tools/get-application.d.ts +0 -22
  39. package/dist/tools/get-application.js +0 -77
  40. package/dist/tools/get-diagram.d.ts +0 -22
  41. package/dist/tools/get-diagram.js +0 -49
  42. package/dist/tools/get-document.d.ts +0 -17
  43. package/dist/tools/get-document.js +0 -37
  44. package/dist/tools/get-signal.d.ts +0 -24
  45. package/dist/tools/get-signal.js +0 -75
  46. package/dist/tools/import-openapi-endpoints.d.ts +0 -28
  47. package/dist/tools/import-openapi-endpoints.js +0 -87
  48. package/dist/tools/inspect.d.ts +0 -21
  49. package/dist/tools/inspect.js +0 -222
  50. package/dist/tools/list-applications.d.ts +0 -29
  51. package/dist/tools/list-applications.js +0 -68
  52. package/dist/tools/list-diagrams.d.ts +0 -37
  53. package/dist/tools/list-diagrams.js +0 -74
  54. package/dist/tools/list-documents.d.ts +0 -19
  55. package/dist/tools/list-documents.js +0 -44
  56. package/dist/tools/list-endpoints.d.ts +0 -42
  57. package/dist/tools/list-endpoints.js +0 -92
  58. package/dist/tools/list-signals.d.ts +0 -37
  59. package/dist/tools/list-signals.js +0 -83
  60. package/dist/tools/manage-application.d.ts +0 -64
  61. package/dist/tools/manage-application.js +0 -129
  62. package/dist/tools/manage-diagram.d.ts +0 -41
  63. package/dist/tools/manage-diagram.js +0 -91
  64. package/dist/tools/manage-endpoint-lifecycle.d.ts +0 -80
  65. package/dist/tools/manage-endpoint-lifecycle.js +0 -180
  66. package/dist/tools/security-review.d.ts +0 -40
  67. package/dist/tools/security-review.js +0 -199
  68. package/dist/tools/threat-get-capsule.d.ts +0 -15
  69. package/dist/tools/threat-get-capsule.js +0 -53
  70. package/dist/tools/threat-get-inference-prompt.d.ts +0 -15
  71. package/dist/tools/threat-get-inference-prompt.js +0 -73
  72. package/dist/tools/threat-list-relevant-capsules.d.ts +0 -17
  73. package/dist/tools/threat-list-relevant-capsules.js +0 -158
  74. package/dist/tools/threat-run-matcher.d.ts +0 -17
  75. package/dist/tools/threat-run-matcher.js +0 -145
  76. package/dist/tools/update-document.d.ts +0 -23
  77. package/dist/tools/update-document.js +0 -57
  78. package/dist/tools/update-endpoint.d.ts +0 -60
  79. package/dist/tools/update-endpoint.js +0 -138
  80. package/dist/tools/update-finding.d.ts +0 -61
  81. package/dist/tools/update-finding.js +0 -80
  82. package/dist/tools/update-mermaid-source.d.ts +0 -21
  83. package/dist/tools/update-mermaid-source.js +0 -60
@@ -0,0 +1,209 @@
1
+ import { z } from "zod";
2
+ import { sanitizeResponse } from "../sanitize.js";
3
+ export const DIAGRAM_NAME = "zivis_diagram";
4
+ const DIAGRAM_TYPE_ENUM = [
5
+ "architecture",
6
+ "data_flow",
7
+ "attack_chain",
8
+ "sequence",
9
+ "trust_boundary",
10
+ "network",
11
+ "deployment",
12
+ "custom",
13
+ ];
14
+ export const DIAGRAM_DESCRIPTION = `CRUD + link management for Mermaid diagrams (architecture, data flow, attack chain, sequence, trust boundary, network, deployment).
15
+
16
+ action:
17
+ - create: requires name, diagram_type, content (Mermaid source). Optional description, linked_threat_model_id.
18
+ - get: requires diagram_id. Full Mermaid source + metadata — call before update_source.
19
+ - list: optional diagram_type, search, linked_threat_model_id filters; limit (default 20, max 100).
20
+ - update_metadata: requires diagram_id. Optional name/description/diagram_type.
21
+ - update_source: requires diagram_id, mermaid_source (COMPLETE replacement source — get first, preserve unrelated nodes/edges/styles). Optional description of the change.
22
+ - delete: requires diagram_id.
23
+ - link_threat_model / unlink_threat_model: requires diagram_id, threat_model_id.`;
24
+ export const DIAGRAM_SCHEMA = {
25
+ action: z
26
+ .enum([
27
+ "create",
28
+ "get",
29
+ "list",
30
+ "update_metadata",
31
+ "update_source",
32
+ "delete",
33
+ "link_threat_model",
34
+ "unlink_threat_model",
35
+ ])
36
+ .describe("Which diagram operation to perform"),
37
+ diagram_id: z.string().optional().describe("Diagram UUID. Required for every action except create/list."),
38
+ name: z.string().optional().describe("Diagram name. Required for create."),
39
+ description: z
40
+ .string()
41
+ .optional()
42
+ .describe("Diagram description (create/update_metadata), or a short note of what changed (update_source) — both write the same field."),
43
+ diagram_type: z.enum(DIAGRAM_TYPE_ENUM).optional().describe("Diagram type. Required for create; optional filter for list; optional for update_metadata."),
44
+ content: z.string().optional().describe("Mermaid diagram source. Required for create."),
45
+ linked_threat_model_id: z.string().optional().describe("Threat model UUID to link this diagram to right after creation (create only)."),
46
+ search: z.string().optional().describe("Search by diagram name or description (list)."),
47
+ limit: z.number().min(1).max(100).optional().describe("Maximum results, 1-100, default 20 (list)."),
48
+ mermaid_source: z.string().min(1).optional().describe("Full replacement Mermaid syntax. Required for update_source — replaces the entire content atomically."),
49
+ threat_model_id: z.string().optional().describe("Threat model UUID. Required for link_threat_model and unlink_threat_model."),
50
+ };
51
+ function errorResult(message) {
52
+ return {
53
+ content: [{ type: "text", text: `Error: ${message}` }],
54
+ isError: true,
55
+ };
56
+ }
57
+ function successResult(data) {
58
+ return {
59
+ content: [{ type: "text", text: JSON.stringify(sanitizeResponse(data), null, 2) }],
60
+ };
61
+ }
62
+ export function createDiagramHandler(apiClient) {
63
+ return async (params) => {
64
+ try {
65
+ switch (params.action) {
66
+ case "create": {
67
+ if (!params.name)
68
+ return errorResult("name is required for create");
69
+ if (!params.diagram_type)
70
+ return errorResult("diagram_type is required for create");
71
+ if (!params.content)
72
+ return errorResult("content is required for create");
73
+ const data = await apiClient.post("/api/diagrams", {
74
+ name: params.name,
75
+ description: params.description,
76
+ diagramType: params.diagram_type,
77
+ contentType: "mermaid",
78
+ content: params.content,
79
+ sourceType: "manual",
80
+ });
81
+ const sanitized = sanitizeResponse(data);
82
+ const diagramId = sanitized.id;
83
+ let linkedThreatModelId = null;
84
+ if (params.linked_threat_model_id && diagramId) {
85
+ try {
86
+ await apiClient.post(`/api/diagrams/${diagramId}/link`, {
87
+ threatModelId: params.linked_threat_model_id,
88
+ });
89
+ linkedThreatModelId = params.linked_threat_model_id;
90
+ }
91
+ catch {
92
+ }
93
+ }
94
+ return successResult({
95
+ diagram_id: diagramId,
96
+ name: sanitized.name,
97
+ diagram_type: sanitized.diagramType,
98
+ linked_threat_model_id: linkedThreatModelId,
99
+ _instruction: "Diagram created. Use zivis_diagram(action=get) to see full content, action=update_metadata to change metadata/links, or action=update_source to change the Mermaid source.",
100
+ });
101
+ }
102
+ case "get": {
103
+ if (!params.diagram_id)
104
+ return errorResult("diagram_id is required for get");
105
+ const data = await apiClient.get(`/api/diagrams/${params.diagram_id}`);
106
+ const sanitized = sanitizeResponse(data);
107
+ const linkedThreatModelIds = Array.isArray(sanitized.threatModelLinks)
108
+ ? sanitized.threatModelLinks.map((l) => l.threatModelId)
109
+ : [];
110
+ return successResult({
111
+ diagram_id: sanitized.id,
112
+ name: sanitized.name,
113
+ description: sanitized.description || null,
114
+ diagram_type: sanitized.diagramType,
115
+ content_type: sanitized.contentType,
116
+ content: sanitized.content || null,
117
+ source_type: sanitized.sourceType,
118
+ created_at: sanitized.createdAt,
119
+ updated_at: sanitized.updatedAt,
120
+ linked_threat_model_ids: linkedThreatModelIds,
121
+ });
122
+ }
123
+ case "list": {
124
+ const query = new URLSearchParams();
125
+ if (params.diagram_type)
126
+ query.set("diagramType", params.diagram_type);
127
+ if (params.search)
128
+ query.set("search", params.search);
129
+ if (params.linked_threat_model_id)
130
+ query.set("linkedThreatModelId", params.linked_threat_model_id);
131
+ if (params.limit)
132
+ query.set("take", String(params.limit));
133
+ const queryStr = query.toString();
134
+ const path = `/api/diagrams${queryStr ? `?${queryStr}` : ""}`;
135
+ const data = await apiClient.get(path);
136
+ const sanitized = sanitizeResponse(data);
137
+ const summary = Array.isArray(sanitized.diagrams)
138
+ ? sanitized.diagrams.map((d) => ({
139
+ diagram_id: d.id,
140
+ name: d.name,
141
+ diagram_type: d.diagramType,
142
+ content_type: d.contentType,
143
+ source_type: d.sourceType,
144
+ description: d.description || null,
145
+ created_at: d.createdAt,
146
+ updated_at: d.updatedAt,
147
+ }))
148
+ : sanitized.diagrams;
149
+ return successResult({ total: sanitized.total, diagrams: summary });
150
+ }
151
+ case "update_metadata": {
152
+ if (!params.diagram_id)
153
+ return errorResult("diagram_id is required for update_metadata");
154
+ const body = {};
155
+ if (params.name)
156
+ body.name = params.name;
157
+ if (params.description !== undefined)
158
+ body.description = params.description;
159
+ if (params.diagram_type)
160
+ body.diagramType = params.diagram_type;
161
+ const data = await apiClient.patch(`/api/diagrams/${params.diagram_id}`, body);
162
+ return successResult(data);
163
+ }
164
+ case "update_source": {
165
+ if (!params.diagram_id)
166
+ return errorResult("diagram_id is required for update_source");
167
+ if (!params.mermaid_source || params.mermaid_source.trim().length === 0) {
168
+ return errorResult("mermaid_source is required and cannot be empty for update_source");
169
+ }
170
+ const body = { content: params.mermaid_source };
171
+ if (params.description)
172
+ body.description = params.description;
173
+ const updated = await apiClient.patch(`/api/diagrams/${params.diagram_id}`, body);
174
+ return successResult({ ok: true, diagram_id: params.diagram_id, updated });
175
+ }
176
+ case "delete": {
177
+ if (!params.diagram_id)
178
+ return errorResult("diagram_id is required for delete");
179
+ await apiClient.del(`/api/diagrams/${params.diagram_id}`);
180
+ return successResult({ action: "deleted", diagram_id: params.diagram_id });
181
+ }
182
+ case "link_threat_model": {
183
+ if (!params.diagram_id)
184
+ return errorResult("diagram_id is required for link_threat_model");
185
+ if (!params.threat_model_id)
186
+ return errorResult("threat_model_id is required for link_threat_model");
187
+ const data = await apiClient.post(`/api/diagrams/${params.diagram_id}/link`, {
188
+ threatModelId: params.threat_model_id,
189
+ });
190
+ return successResult(data);
191
+ }
192
+ case "unlink_threat_model": {
193
+ if (!params.diagram_id)
194
+ return errorResult("diagram_id is required for unlink_threat_model");
195
+ if (!params.threat_model_id)
196
+ return errorResult("threat_model_id is required for unlink_threat_model");
197
+ await apiClient.del(`/api/diagrams/${params.diagram_id}/link/threat-model/${params.threat_model_id}`);
198
+ return successResult({ action: "unlinked", diagram_id: params.diagram_id, threat_model_id: params.threat_model_id });
199
+ }
200
+ default:
201
+ return errorResult(`Unknown action: ${params.action}`);
202
+ }
203
+ }
204
+ catch (err) {
205
+ const message = err instanceof Error ? err.message : `Failed to perform diagram action`;
206
+ return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
207
+ }
208
+ };
209
+ }
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import type { ApiClient } from "../api-client.js";
3
+ export declare const DOCUMENT_NAME = "zivis_document";
4
+ export declare const DOCUMENT_DESCRIPTION = "CRUD for narrative markdown documents under a ThreatModel (exec summaries, remediation plans, architecture narratives). Can embed Diagrams (see zivis_diagram) via ```mermaid or ```zivis:diagram (UUID) fenced blocks.\n\naction:\n- create: requires title, exactly one of threat_model_id or entity_type+entity_id \u2014 or omit both threat_model_id and entity_type/entity_id entirely to attach to the current workspace's bound Application automatically. entity_type \"application\" with no entity_id also auto-resolves from that binding. Optional content, tags.\n- get: requires document_id. Full markdown + metadata.\n- list: optional threat_model_id or entity_type+entity_id, search filters.\n- update: requires document_id + at least one of title/content/tags. content REPLACES the whole document \u2014 get first, then send the complete edited markdown, preserving unrelated structure.";
5
+ export declare const DOCUMENT_SCHEMA: {
6
+ action: z.ZodEnum<{
7
+ list: "list";
8
+ get: "get";
9
+ create: "create";
10
+ update: "update";
11
+ }>;
12
+ threat_model_id: z.ZodOptional<z.ZodString>;
13
+ title: z.ZodOptional<z.ZodString>;
14
+ content: z.ZodOptional<z.ZodString>;
15
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
+ document_id: z.ZodOptional<z.ZodString>;
17
+ entity_type: z.ZodOptional<z.ZodEnum<{
18
+ threat_model: "threat_model";
19
+ application: "application";
20
+ agent_instance: "agent_instance";
21
+ scan: "scan";
22
+ finding: "finding";
23
+ attack_scenario: "attack_scenario";
24
+ component: "component";
25
+ trust_room: "trust_room";
26
+ campaign: "campaign";
27
+ }>>;
28
+ entity_id: z.ZodOptional<z.ZodString>;
29
+ search: z.ZodOptional<z.ZodString>;
30
+ };
31
+ type DocumentParams = {
32
+ action: "create" | "get" | "list" | "update";
33
+ threat_model_id?: string;
34
+ title?: string;
35
+ content?: string;
36
+ tags?: string[];
37
+ document_id?: string;
38
+ entity_type?: string;
39
+ entity_id?: string;
40
+ search?: string;
41
+ };
42
+ export declare function createDocumentHandler(apiClient: ApiClient): (params: DocumentParams) => Promise<{
43
+ content: {
44
+ type: "text";
45
+ text: string;
46
+ }[];
47
+ }>;
48
+ export {};
@@ -0,0 +1,137 @@
1
+ import { z } from "zod";
2
+ import { sanitizeResponse, sanitizeInboundText } from "../sanitize.js";
3
+ import { requireApplicationId } from "../resolve-application-id.js";
4
+ export const DOCUMENT_NAME = "zivis_document";
5
+ export const DOCUMENT_DESCRIPTION = `CRUD for narrative markdown documents under a ThreatModel (exec summaries, remediation plans, architecture narratives). Can embed Diagrams (see zivis_diagram) via \`\`\`mermaid or \`\`\`zivis:diagram (UUID) fenced blocks.
6
+
7
+ action:
8
+ - create: requires title, exactly one of threat_model_id or entity_type+entity_id — or omit both threat_model_id and entity_type/entity_id entirely to attach to the current workspace's bound Application automatically. entity_type "application" with no entity_id also auto-resolves from that binding. Optional content, tags.
9
+ - get: requires document_id. Full markdown + metadata.
10
+ - list: optional threat_model_id or entity_type+entity_id, search filters.
11
+ - update: requires document_id + at least one of title/content/tags. content REPLACES the whole document — get first, then send the complete edited markdown, preserving unrelated structure.`;
12
+ const ENTITY_TYPE_ENUM = [
13
+ "application",
14
+ "threat_model",
15
+ "agent_instance",
16
+ "scan",
17
+ "finding",
18
+ "attack_scenario",
19
+ "component",
20
+ "trust_room",
21
+ "campaign",
22
+ ];
23
+ export const DOCUMENT_SCHEMA = {
24
+ action: z.enum(["create", "get", "list", "update"]).describe("Which document operation to perform"),
25
+ threat_model_id: z.string().optional().describe("UUID of the parent threat model. For create, alternative to entity_type+entity_id — provide exactly one, not both. Optional filter for list."),
26
+ title: z.string().optional().describe("Document title. Required for create."),
27
+ content: z.string().optional().describe("Markdown content. For update, REPLACES the entire document."),
28
+ tags: z.array(z.string()).optional().describe("Tags. For update, replaces existing tags."),
29
+ document_id: z.string().optional().describe("UUID of the document. Required for get and update."),
30
+ entity_type: z.enum(ENTITY_TYPE_ENUM).optional().describe("Polymorphic parent entity type, for attaching a document directly to something other than a ThreatModel (e.g. an Application with no ThreatModel). For create, alternative to threat_model_id — provide exactly one, not both. Must be paired with entity_id. Optional filter for list (also paired with entity_id)."),
31
+ entity_id: z.string().optional().describe("UUID of the entity_type target. Must be paired with entity_type."),
32
+ search: z.string().optional().describe("Filter by title (case-insensitive substring) or tag. Used by list."),
33
+ };
34
+ function errorResult(message) {
35
+ return {
36
+ content: [{ type: "text", text: `Error: ${message}` }],
37
+ isError: true,
38
+ };
39
+ }
40
+ function successResult(data) {
41
+ return {
42
+ content: [{ type: "text", text: JSON.stringify(sanitizeResponse(data), null, 2) }],
43
+ };
44
+ }
45
+ export function createDocumentHandler(apiClient) {
46
+ return async (params) => {
47
+ try {
48
+ switch (params.action) {
49
+ case "create": {
50
+ const { threat_model_id, title, content, tags, entity_type, entity_id } = params;
51
+ if (!title || !title.trim())
52
+ return errorResult("title is required for create");
53
+ const hasTm = !!threat_model_id;
54
+ let hasEntityType = !!entity_type;
55
+ let hasEntityId = !!entity_id;
56
+ let resolvedEntityType = entity_type;
57
+ let resolvedEntityId = entity_id;
58
+ if (!hasTm && !hasEntityType && !hasEntityId) {
59
+ const req = requireApplicationId(undefined);
60
+ if (!req.ok)
61
+ return errorResult(req.message);
62
+ resolvedEntityType = "application";
63
+ resolvedEntityId = req.id;
64
+ hasEntityType = true;
65
+ hasEntityId = true;
66
+ }
67
+ else if (!hasTm && entity_type === "application" && !hasEntityId) {
68
+ const req = requireApplicationId(undefined);
69
+ if (!req.ok)
70
+ return errorResult(req.message);
71
+ resolvedEntityId = req.id;
72
+ hasEntityId = true;
73
+ }
74
+ if (hasEntityType !== hasEntityId) {
75
+ return errorResult("entity_type and entity_id must be provided together");
76
+ }
77
+ const hasEntity = hasEntityType && hasEntityId;
78
+ if (hasTm && hasEntity) {
79
+ return errorResult("Provide either threat_model_id or entity_type+entity_id, not both");
80
+ }
81
+ if (!hasTm && !hasEntity) {
82
+ return errorResult("Provide either threat_model_id or entity_type+entity_id");
83
+ }
84
+ const data = await apiClient.post(`/api/documents`, {
85
+ ...(hasTm ? { threatModelId: threat_model_id } : { entityType: resolvedEntityType, entityId: resolvedEntityId }),
86
+ title: sanitizeInboundText(title, 500),
87
+ content: sanitizeInboundText(content ?? "", 200_000),
88
+ tags: tags ?? [],
89
+ });
90
+ return successResult(data);
91
+ }
92
+ case "get": {
93
+ if (!params.document_id)
94
+ return errorResult("document_id is required for get");
95
+ const data = await apiClient.get(`/api/documents/${params.document_id}`);
96
+ return successResult(data);
97
+ }
98
+ case "list": {
99
+ const qs = new URLSearchParams();
100
+ if (params.threat_model_id)
101
+ qs.set("threatModelId", params.threat_model_id);
102
+ if (params.entity_type && params.entity_id) {
103
+ qs.set("entityType", params.entity_type);
104
+ qs.set("entityId", params.entity_id);
105
+ }
106
+ if (params.search)
107
+ qs.set("search", params.search);
108
+ const path = `/api/documents${qs.toString() ? `?${qs.toString()}` : ""}`;
109
+ const data = await apiClient.get(path);
110
+ return successResult(data);
111
+ }
112
+ case "update": {
113
+ const { document_id, title, content, tags } = params;
114
+ if (!document_id)
115
+ return errorResult("document_id is required for update");
116
+ if (title === undefined && content === undefined && tags === undefined) {
117
+ return errorResult("At least one of title, content, or tags must be provided for update");
118
+ }
119
+ const body = {};
120
+ if (title !== undefined)
121
+ body.title = sanitizeInboundText(title, 500);
122
+ if (content !== undefined)
123
+ body.content = sanitizeInboundText(content, 200_000);
124
+ if (tags !== undefined)
125
+ body.tags = tags;
126
+ const data = await apiClient.patch(`/api/documents/${document_id}`, body);
127
+ return successResult({ ok: true, document_id, updated: data });
128
+ }
129
+ default:
130
+ return errorResult(`Unknown action: ${params.action}`);
131
+ }
132
+ }
133
+ catch (err) {
134
+ return errorResult(err?.message ?? `Failed to ${params.action} document`);
135
+ }
136
+ };
137
+ }
@@ -0,0 +1,133 @@
1
+ import { z } from "zod";
2
+ import type { ApiClient } from "../api-client.js";
3
+ export declare const FINDING_NAME = "zivis_finding";
4
+ export declare const FINDING_DESCRIPTION = "Create, update, or delete a tracked security finding authored by hand (not from a scanner). Every change is audited.\n\naction:\n- create: requires title, severity. For service-delivered results (pen test/red team/ZRT), pass source_type + producer (requires run_agents permission).\n- update: requires finding_id. Two kinds of change, never mixed in one call:\n 1. Direct edit: title/severity/description/category/remediation_steps/cwe_id/owasp_id, and non-closing status (open|triaged|in_progress).\n 2. Disposition (`disposition`: open|fixed|accepted_by_design|accepted_risk_based|planned|not_applicable, + rationale/ref/owner_name/target_date/review_date/compensating_controls/residual_severity/note) \u2014 records the customer's claim/decision. disposition=fixed does NOT close the finding: status is only ever derived from (disposition, independent verification) \u2014 a claim never closes a finding, only an independent ZIVIS verdict does. Closing values (resolved/dismissed/suppressed) are REJECTED on the direct-edit path; use `disposition` instead.\n- delete: requires finding_id. Soft-delete, manual findings only.";
5
+ export declare const FINDING_SCHEMA: {
6
+ action: z.ZodEnum<{
7
+ create: "create";
8
+ delete: "delete";
9
+ update: "update";
10
+ }>;
11
+ title: z.ZodOptional<z.ZodString>;
12
+ severity: z.ZodOptional<z.ZodEnum<{
13
+ critical: "critical";
14
+ high: "high";
15
+ medium: "medium";
16
+ low: "low";
17
+ info: "info";
18
+ }>>;
19
+ description: z.ZodOptional<z.ZodString>;
20
+ category: z.ZodOptional<z.ZodEnum<{
21
+ vulnerability: "vulnerability";
22
+ misconfiguration: "misconfiguration";
23
+ secret: "secret";
24
+ anomaly: "anomaly";
25
+ other: "other";
26
+ }>>;
27
+ confidence: z.ZodOptional<z.ZodEnum<{
28
+ high: "high";
29
+ medium: "medium";
30
+ low: "low";
31
+ }>>;
32
+ application_id: z.ZodOptional<z.ZodString>;
33
+ source_document_id: z.ZodOptional<z.ZodString>;
34
+ excerpt: z.ZodOptional<z.ZodString>;
35
+ evidence_location: z.ZodOptional<z.ZodString>;
36
+ cwe_id: z.ZodOptional<z.ZodString>;
37
+ owasp_id: z.ZodOptional<z.ZodString>;
38
+ remediation_steps: z.ZodOptional<z.ZodString>;
39
+ source_type: z.ZodOptional<z.ZodEnum<{
40
+ threat_model: "threat_model";
41
+ manual: "manual";
42
+ pen_test: "pen_test";
43
+ red_team: "red_team";
44
+ }>>;
45
+ producer: z.ZodOptional<z.ZodObject<{
46
+ kind: z.ZodEnum<{
47
+ human: "human";
48
+ zrt: "zrt";
49
+ frontier_tool: "frontier_tool";
50
+ third_party: "third_party";
51
+ }>;
52
+ id: z.ZodOptional<z.ZodString>;
53
+ name: z.ZodOptional<z.ZodString>;
54
+ toolVersion: z.ZodOptional<z.ZodString>;
55
+ engagementId: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>;
57
+ scenario_id: z.ZodOptional<z.ZodString>;
58
+ attack_step_id: z.ZodOptional<z.ZodString>;
59
+ finding_id: z.ZodOptional<z.ZodString>;
60
+ status: z.ZodOptional<z.ZodEnum<{
61
+ open: "open";
62
+ triaged: "triaged";
63
+ in_progress: "in_progress";
64
+ }>>;
65
+ note: z.ZodOptional<z.ZodString>;
66
+ disposition: z.ZodOptional<z.ZodEnum<{
67
+ fixed: "fixed";
68
+ open: "open";
69
+ accepted_by_design: "accepted_by_design";
70
+ accepted_risk_based: "accepted_risk_based";
71
+ planned: "planned";
72
+ not_applicable: "not_applicable";
73
+ }>>;
74
+ rationale: z.ZodOptional<z.ZodString>;
75
+ ref: z.ZodOptional<z.ZodString>;
76
+ owner_name: z.ZodOptional<z.ZodString>;
77
+ target_date: z.ZodOptional<z.ZodString>;
78
+ review_date: z.ZodOptional<z.ZodString>;
79
+ compensating_controls: z.ZodOptional<z.ZodString>;
80
+ residual_severity: z.ZodOptional<z.ZodEnum<{
81
+ critical: "critical";
82
+ high: "high";
83
+ medium: "medium";
84
+ low: "low";
85
+ info: "info";
86
+ }>>;
87
+ reason: z.ZodOptional<z.ZodString>;
88
+ };
89
+ type Producer = {
90
+ kind: "human" | "zrt" | "frontier_tool" | "third_party";
91
+ id?: string;
92
+ name?: string;
93
+ toolVersion?: string;
94
+ engagementId?: string;
95
+ };
96
+ type FindingParams = {
97
+ action: "create" | "update" | "delete";
98
+ title?: string;
99
+ severity?: "critical" | "high" | "medium" | "low" | "info";
100
+ description?: string;
101
+ category?: "vulnerability" | "misconfiguration" | "secret" | "anomaly" | "other";
102
+ confidence?: "high" | "medium" | "low";
103
+ application_id?: string;
104
+ source_document_id?: string;
105
+ excerpt?: string;
106
+ evidence_location?: string;
107
+ cwe_id?: string;
108
+ owasp_id?: string;
109
+ remediation_steps?: string;
110
+ source_type?: "manual" | "pen_test" | "red_team" | "threat_model";
111
+ producer?: Producer;
112
+ scenario_id?: string;
113
+ attack_step_id?: string;
114
+ finding_id?: string;
115
+ status?: "open" | "triaged" | "in_progress";
116
+ note?: string;
117
+ disposition?: "open" | "fixed" | "accepted_by_design" | "accepted_risk_based" | "planned" | "not_applicable";
118
+ rationale?: string;
119
+ ref?: string;
120
+ owner_name?: string;
121
+ target_date?: string;
122
+ review_date?: string;
123
+ compensating_controls?: string;
124
+ residual_severity?: "critical" | "high" | "medium" | "low" | "info";
125
+ reason?: string;
126
+ };
127
+ export declare function createFindingHandler(apiClient: ApiClient): (params: FindingParams) => Promise<{
128
+ content: {
129
+ type: "text";
130
+ text: string;
131
+ }[];
132
+ }>;
133
+ export {};