cataam-mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # cataam-mcp-server
2
+
3
+ The MCP connector for Cataam. TypeScript, built on `@modelcontextprotocol/sdk`.
4
+ Exposes Cataam's `/api/audit/**` compliance surface as MCP tools.
5
+
6
+ ## Layout
7
+
8
+ ```
9
+ src/
10
+ config.ts — env-var config + auth-mode selection (apiKey | jwt)
11
+ client.ts — typed HTTP client for /api/audit (handles X-API-Key and JWT+refresh)
12
+ tools.ts — the 6 MCP tools (one-tool-per-action; write tools require confirm:true)
13
+ index.ts — entry point: stdio (default) or streamable-HTTP transport
14
+ test/
15
+ smoke.mjs — end-to-end test (spawns server over stdio, calls a read tool live)
16
+ ```
17
+
18
+ ## Develop
19
+
20
+ ```bash
21
+ npm install
22
+ npm run build # tsc → dist/
23
+ npm run dev # run from source via tsx (stdio)
24
+ npm run smoke # end-to-end smoke test (needs auth env vars + a built dist/)
25
+ ```
26
+
27
+ ## Configuration (env vars)
28
+
29
+ | Var | Purpose |
30
+ |---|---|
31
+ | `CATAAM_BASE_URL` | API base URL. Default `https://service.cataam.com`. |
32
+ | `CATAAM_API_KEY` | `X-API-Key` auth (preferred). |
33
+ | `CATAAM_USERNAME` / `CATAAM_PASSWORD` | JWT login auth (works today). |
34
+ | `MCP_TRANSPORT` | `stdio` (default) or `http`. |
35
+ | `PORT` | HTTP port (default 3000) when `MCP_TRANSPORT=http`. |
36
+
37
+ If `CATAAM_API_KEY` is set it wins; otherwise username+password are used. Startup fails
38
+ fast with a clear message if neither is configured.
39
+
40
+ ## Transports
41
+
42
+ - **stdio** — what the Claude plugin and `claude mcp add` use. Auth comes from env.
43
+ - **streamable-HTTP** — for remote/hosted SaaS deployment. Stateless: a fresh server is
44
+ built per request, and an incoming `X-API-Key` request header overrides the env key,
45
+ so one hosted process can serve many Cataam orgs. `GET`/`DELETE /mcp` return 405.
46
+
47
+ ## Auth scoping note
48
+
49
+ Cataam's `X-API-Key` filter only covers `/api/audit/**` (and a reserved `/api/iasm/**`).
50
+ All tools are intentionally scoped to `/api/audit/**` for **both** auth modes — even
51
+ though JWT could reach more — so migrating customers from JWT to API keys is seamless.
52
+
53
+ ## Tools
54
+
55
+ See [`../README.md`](../README.md#mcp-tools). Read tools: `list_compliance_tests`,
56
+ `get_compliance_overview`, `list_failing_alerts`. Write tools (require `confirm:true`):
57
+ `rerun_compliance_test`, `update_test_due_date`, `link_test_to_jira`.
package/dist/client.js ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Thin typed HTTP client for the CATAAM `/api/audit/**` compliance surface.
3
+ *
4
+ * Handles both auth modes:
5
+ * - apiKey: sends `X-API-Key` on every request.
6
+ * - jwt: logs in at POST /api/login, caches the token, and transparently
7
+ * re-authenticates once on a 401 (short-lived tokens expire).
8
+ */
9
+ import { authMode } from "./config.js";
10
+ export class CataamError extends Error {
11
+ status;
12
+ body;
13
+ constructor(message, status, body) {
14
+ super(message);
15
+ this.status = status;
16
+ this.body = body;
17
+ this.name = "CataamError";
18
+ }
19
+ }
20
+ export class CataamClient {
21
+ cfg;
22
+ token;
23
+ constructor(cfg) {
24
+ this.cfg = cfg;
25
+ }
26
+ // ---- auth -------------------------------------------------------------
27
+ async authHeaders() {
28
+ if (this.cfg.apiKey)
29
+ return { "X-API-Key": this.cfg.apiKey };
30
+ if (!this.token)
31
+ await this.login();
32
+ return { Authorization: `Bearer ${this.token}` };
33
+ }
34
+ async login() {
35
+ const res = await fetch(`${this.cfg.baseUrl}/api/login`, {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({
39
+ userName: this.cfg.username,
40
+ password: this.cfg.password,
41
+ }),
42
+ });
43
+ if (!res.ok) {
44
+ throw new CataamError(`Login failed for user "${this.cfg.username}"`, res.status, await safeText(res));
45
+ }
46
+ const data = (await res.json());
47
+ if (!data.token) {
48
+ throw new CataamError("Login response missing token", res.status);
49
+ }
50
+ this.token = data.token;
51
+ }
52
+ // ---- core request -----------------------------------------------------
53
+ async request(method, path, opts = {}) {
54
+ const url = new URL(this.cfg.baseUrl + path);
55
+ if (opts.query) {
56
+ for (const [k, v] of Object.entries(opts.query)) {
57
+ if (v !== undefined && v !== "")
58
+ url.searchParams.set(k, String(v));
59
+ }
60
+ }
61
+ const headers = { ...(await this.authHeaders()) };
62
+ let body;
63
+ if (opts.body !== undefined) {
64
+ headers["Content-Type"] = "application/json";
65
+ body = JSON.stringify(opts.body);
66
+ }
67
+ const res = await fetch(url, { method, headers, body });
68
+ // JWT expired mid-session — re-login once and retry.
69
+ if (res.status === 401 &&
70
+ authMode(this.cfg) === "jwt" &&
71
+ opts.retryOn401 !== false) {
72
+ this.token = undefined;
73
+ await this.login();
74
+ return this.request(method, path, { ...opts, retryOn401: false });
75
+ }
76
+ if (!res.ok) {
77
+ throw new CataamError(`${method} ${path} → ${res.status}`, res.status, await safeText(res));
78
+ }
79
+ if (res.status === 204)
80
+ return undefined;
81
+ const text = await res.text();
82
+ return (text ? JSON.parse(text) : undefined);
83
+ }
84
+ // ---- read endpoints ---------------------------------------------------
85
+ /** GET /api/audit/tests — paginated compliance tests + aggregate stats. */
86
+ listComplianceTests(params) {
87
+ return this.request("GET", "/api/audit/tests", { query: { ...params } });
88
+ }
89
+ /** GET /api/audit/{frameworkId}/audit-progress — per-framework progress stats. */
90
+ getFrameworkProgress(frameworkId) {
91
+ return this.request("GET", `/api/audit/${frameworkId}/audit-progress`);
92
+ }
93
+ /** GET /api/audit/compliance-summary — per-framework totals & pass rate. */
94
+ getComplianceSummary() {
95
+ return this.request("GET", "/api/audit/compliance-summary");
96
+ }
97
+ /** GET /api/audit/readiness-score — overall readiness score breakdown. */
98
+ getReadinessScore() {
99
+ return this.request("GET", "/api/audit/readiness-score");
100
+ }
101
+ /** GET /api/audit/latest-failed-tests-alert — most recent failing-test alerts. */
102
+ getFailedTestAlerts() {
103
+ return this.request("GET", "/api/audit/latest-failed-tests-alert");
104
+ }
105
+ /** GET /api/audit/ccm-alerts — continuous control monitoring alerts. */
106
+ getCcmAlerts() {
107
+ return this.request("GET", "/api/audit/ccm-alerts");
108
+ }
109
+ // ---- write endpoints (callers must confirm first) ---------------------
110
+ /** POST /api/audit/tests/{auditProgressId}/rerun — re-execute one compliance test. */
111
+ rerunTest(auditProgressId) {
112
+ return this.request("POST", `/api/audit/tests/${auditProgressId}/rerun`);
113
+ }
114
+ /**
115
+ * PUT /api/audit/tests/{auditProgressId}/update-due-date?newDueDate=...
116
+ * The backend parses the value with Instant.parse(), so it requires a full
117
+ * ISO-8601 instant. A bare YYYY-MM-DD is expanded to UTC midnight.
118
+ */
119
+ updateDueDate(auditProgressId, newDueDate) {
120
+ const instant = /^\d{4}-\d{2}-\d{2}$/.test(newDueDate)
121
+ ? `${newDueDate}T00:00:00Z`
122
+ : newDueDate;
123
+ return this.request("PUT", `/api/audit/tests/${auditProgressId}/update-due-date`, { query: { newDueDate: instant } });
124
+ }
125
+ /** PATCH /api/audit/tests/{auditProgressId}/jira-link — body { jiraId }. */
126
+ linkToJira(auditProgressId, jiraId) {
127
+ return this.request("PATCH", `/api/audit/tests/${auditProgressId}/jira-link`, { body: { jiraId } });
128
+ }
129
+ }
130
+ async function safeText(res) {
131
+ try {
132
+ return await res.text();
133
+ }
134
+ catch {
135
+ return undefined;
136
+ }
137
+ }
138
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Runtime configuration for the CATAAM MCP connector.
3
+ *
4
+ * Two auth modes are supported (see README "Authentication"):
5
+ * 1. API key — `X-API-Key` header. Preferred long-term integration path.
6
+ * Set CATAAM_API_KEY. (Backend supports it; UI provisioning is WIP.)
7
+ * 2. JWT login — username/password exchanged at POST /api/login for a short-lived
8
+ * bearer token. Works today. Set CATAAM_USERNAME + CATAAM_PASSWORD.
9
+ *
10
+ * Secrets are NEVER hardcoded — they are read from env vars only.
11
+ */
12
+ /**
13
+ * Build config from env vars, with optional per-request overrides
14
+ * (used by the HTTP transport to pass a per-request X-API-Key).
15
+ */
16
+ export function loadConfig(overrides = {}) {
17
+ const baseUrl = (overrides.baseUrl ??
18
+ process.env.CATAAM_BASE_URL ??
19
+ "https://service.cataam.com").replace(/\/+$/, "");
20
+ const apiKey = overrides.apiKey ?? process.env.CATAAM_API_KEY ?? undefined;
21
+ const username = overrides.username ?? process.env.CATAAM_USERNAME ?? undefined;
22
+ const password = overrides.password ?? process.env.CATAAM_PASSWORD ?? undefined;
23
+ if (!apiKey && !(username && password)) {
24
+ throw new Error("CATAAM auth not configured. Set CATAAM_API_KEY (recommended), " +
25
+ "or CATAAM_USERNAME and CATAAM_PASSWORD for JWT login.");
26
+ }
27
+ return { baseUrl, apiKey, username, password };
28
+ }
29
+ export function authMode(cfg) {
30
+ return cfg.apiKey ? "apiKey" : "jwt";
31
+ }
32
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,YAAmC,EAAE;IAC9D,MAAM,OAAO,GAAG,CACd,SAAS,CAAC,OAAO;QACjB,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,4BAA4B,CAC7B,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEtB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;IAC3E,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;IAChF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;IAEhF,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,gEAAgE;YAC9D,uDAAuD,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAiB;IACxC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CATAAM MCP connector — entry point.
4
+ *
5
+ * Transports (select with MCP_TRANSPORT):
6
+ * - stdio (default) — used by the Claude plugin / `claude mcp add`.
7
+ * - http (streamable-HTTP) — used for remote/hosted SaaS deployment.
8
+ * Reads a per-request `X-API-Key` header so a single
9
+ * hosted server can serve many CATAAM orgs.
10
+ */
11
+ import express from "express";
12
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
13
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
15
+ import { loadConfig } from "./config.js";
16
+ import { CataamClient } from "./client.js";
17
+ import { registerTools } from "./tools.js";
18
+ const NAME = "cataam";
19
+ const VERSION = "0.1.0";
20
+ function buildServer(overrides = {}) {
21
+ const cfg = loadConfig(overrides);
22
+ const client = new CataamClient(cfg);
23
+ const server = new McpServer({ name: NAME, version: VERSION });
24
+ registerTools(server, client);
25
+ return server;
26
+ }
27
+ async function runStdio() {
28
+ // Validate env auth up front so misconfig fails fast with a clear message.
29
+ loadConfig();
30
+ const server = buildServer();
31
+ const transport = new StdioServerTransport();
32
+ await server.connect(transport);
33
+ console.error(`[cataam-mcp] stdio transport ready`);
34
+ }
35
+ async function runHttp(port) {
36
+ const app = express();
37
+ app.use(express.json());
38
+ app.get("/healthz", (_req, res) => res.json({ status: "ok", server: NAME }));
39
+ // Stateless: a fresh server+transport per request, so each can use its own
40
+ // X-API-Key without cross-request session state.
41
+ app.post("/mcp", async (req, res) => {
42
+ try {
43
+ const headerKey = req.header("x-api-key");
44
+ const server = buildServer(headerKey ? { apiKey: headerKey } : {});
45
+ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
46
+ res.on("close", () => {
47
+ transport.close();
48
+ server.close();
49
+ });
50
+ await server.connect(transport);
51
+ await transport.handleRequest(req, res, req.body);
52
+ }
53
+ catch (err) {
54
+ if (!res.headersSent) {
55
+ res.status(500).json({
56
+ jsonrpc: "2.0",
57
+ error: { code: -32603, message: `Internal error: ${err.message}` },
58
+ id: null,
59
+ });
60
+ }
61
+ }
62
+ });
63
+ const methodNotAllowed = (_req, res) => res.status(405).json({
64
+ jsonrpc: "2.0",
65
+ error: { code: -32000, message: "Method not allowed (stateless server; use POST)." },
66
+ id: null,
67
+ });
68
+ app.get("/mcp", methodNotAllowed);
69
+ app.delete("/mcp", methodNotAllowed);
70
+ app.listen(port, () => console.error(`[cataam-mcp] streamable-http transport on :${port}/mcp`));
71
+ }
72
+ async function main() {
73
+ const transport = (process.env.MCP_TRANSPORT ?? "stdio").toLowerCase();
74
+ if (transport === "http" || transport === "streamable-http") {
75
+ await runHttp(Number(process.env.PORT ?? 3000));
76
+ }
77
+ else {
78
+ await runStdio();
79
+ }
80
+ }
81
+ main().catch((err) => {
82
+ console.error(`[cataam-mcp] fatal: ${err.message}`);
83
+ process.exit(1);
84
+ });
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/tools.js ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * MCP tool definitions for the CATAAM connector.
3
+ *
4
+ * Design: one-tool-per-action (the API surface is small — ~ a dozen
5
+ * `/api/audit` endpoints — so search+execute would add overhead for no gain).
6
+ * Tools follow a list → context → act shape.
7
+ *
8
+ * Write tools (rerun / due-date / jira-link) require an explicit `confirm: true`
9
+ * argument. The server refuses the call without it, so a model cannot mutate
10
+ * compliance state without a deliberate, logged decision. The slash-command
11
+ * skills instruct the model to confirm with the human before passing it.
12
+ */
13
+ import { z } from "zod";
14
+ import { CataamError } from "./client.js";
15
+ /** Wrap a handler so CataamErrors become readable MCP error results. */
16
+ function ok(data) {
17
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
18
+ }
19
+ function fail(message) {
20
+ return { isError: true, content: [{ type: "text", text: message }] };
21
+ }
22
+ async function guard(fn) {
23
+ try {
24
+ return ok(await fn());
25
+ }
26
+ catch (e) {
27
+ if (e instanceof CataamError) {
28
+ return fail(`CATAAM API error (${e.status}): ${e.message}\n${e.body ?? ""}`.trim());
29
+ }
30
+ return fail(`Unexpected error: ${e.message}`);
31
+ }
32
+ }
33
+ const CONFIRM = z
34
+ .boolean()
35
+ .describe("Must be true to execute this state-changing action. Confirm intent with the user before setting.");
36
+ export function registerTools(server, client) {
37
+ // ---- LIST -------------------------------------------------------------
38
+ server.registerTool("list_compliance_tests", {
39
+ title: "List compliance tests",
40
+ description: "List CATAAM compliance tests (controls) with their pass/fail status and aggregate " +
41
+ "stats, paginated. Use this to see which automated and manual checks exist for a " +
42
+ "framework (SOC2, GDPR, ISO27001) and which are passing or failing. Returns the " +
43
+ "auditProgressId for each test — needed by the write tools.",
44
+ inputSchema: {
45
+ page: z.number().int().min(0).default(0).describe("0-based page index."),
46
+ size: z.number().int().min(1).max(500).default(20).describe("Page size (max 500)."),
47
+ testName: z.string().optional().describe("Filter by test name substring."),
48
+ frameWork: z
49
+ .string()
50
+ .optional()
51
+ .describe("Filter by framework, e.g. 'SOC2', 'GDPR', 'ISO27001'."),
52
+ category: z.string().optional().describe("Filter by requirement category, e.g. 'CC1'."),
53
+ status: z
54
+ .enum(["PASS", "FAIL", "IN_PROGRESS", "COMPLETED"])
55
+ .optional()
56
+ .describe("Filter by last audit status."),
57
+ auditId: z.string().optional().describe("Filter by a specific audit id."),
58
+ },
59
+ }, async (args) => guard(() => client.listComplianceTests(args)));
60
+ // ---- CONTEXT / OVERVIEW ----------------------------------------------
61
+ server.registerTool("get_compliance_overview", {
62
+ title: "Get compliance overview",
63
+ description: "Get a high-level compliance posture for the organization: overall readiness score " +
64
+ "(with test/policy/evidence breakdown), per-framework pass-rate summary, and — when a " +
65
+ "frameworkId is given — that framework's detailed audit-progress stats. Use this to " +
66
+ "answer 'how compliant are we?' or 'are we audit-ready for SOC2?'.",
67
+ inputSchema: {
68
+ frameworkId: z
69
+ .number()
70
+ .int()
71
+ .positive()
72
+ .optional()
73
+ .describe("Optional framework id to include detailed per-framework progress."),
74
+ },
75
+ }, async ({ frameworkId }) => guard(async () => {
76
+ const [readiness, summary, progress] = await Promise.all([
77
+ client.getReadinessScore(),
78
+ client.getComplianceSummary(),
79
+ frameworkId ? client.getFrameworkProgress(frameworkId) : Promise.resolve(null),
80
+ ]);
81
+ return { readinessScore: readiness, complianceSummary: summary, frameworkProgress: progress };
82
+ }));
83
+ // ---- ALERTS -----------------------------------------------------------
84
+ server.registerTool("list_failing_alerts", {
85
+ title: "List failing / monitoring alerts",
86
+ description: "List the organization's open compliance problems: the latest failing-test alerts plus " +
87
+ "continuous-control-monitoring (CCM) alerts. Use this to triage what needs remediation. " +
88
+ "Each failing test includes its auditProgressId for use with rerun_compliance_test.",
89
+ inputSchema: {},
90
+ }, async () => guard(async () => {
91
+ const [failedTests, ccmAlerts] = await Promise.all([
92
+ client.getFailedTestAlerts(),
93
+ client.getCcmAlerts(),
94
+ ]);
95
+ return { failedTests, ccmAlerts };
96
+ }));
97
+ // ---- ACT: rerun (the "fix/verify" action) -----------------------------
98
+ server.registerTool("rerun_compliance_test", {
99
+ title: "Re-run a compliance test",
100
+ description: "Re-execute a single compliance test to verify a remediation. This MUTATES compliance " +
101
+ "state: it runs the underlying automated check and updates the test's pass/fail status. " +
102
+ "Requires confirm=true. Returns { id, status, passed }. Find auditProgressId via " +
103
+ "list_compliance_tests or list_failing_alerts.",
104
+ inputSchema: {
105
+ auditProgressId: z.number().int().positive().describe("The test's auditProgressId."),
106
+ confirm: CONFIRM,
107
+ },
108
+ }, async ({ auditProgressId, confirm }) => {
109
+ if (!confirm)
110
+ return fail("Refused: rerun_compliance_test requires confirm=true.");
111
+ return guard(() => client.rerunTest(auditProgressId));
112
+ });
113
+ // ---- ACT: update due date --------------------------------------------
114
+ server.registerTool("update_test_due_date", {
115
+ title: "Update a compliance test's due date",
116
+ description: "Set the remediation due date for a compliance test. This MUTATES the record. " +
117
+ "Requires confirm=true.",
118
+ inputSchema: {
119
+ auditProgressId: z.number().int().positive().describe("The test's auditProgressId."),
120
+ newDueDate: z
121
+ .string()
122
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "Use ISO date YYYY-MM-DD.")
123
+ .describe("New due date, ISO format YYYY-MM-DD."),
124
+ confirm: CONFIRM,
125
+ },
126
+ }, async ({ auditProgressId, newDueDate, confirm }) => {
127
+ if (!confirm)
128
+ return fail("Refused: update_test_due_date requires confirm=true.");
129
+ return guard(() => client.updateDueDate(auditProgressId, newDueDate));
130
+ });
131
+ // ---- ACT: link to Jira ------------------------------------------------
132
+ server.registerTool("link_test_to_jira", {
133
+ title: "Link a compliance test to a Jira issue",
134
+ description: "Associate a compliance test with a Jira issue key (e.g. 'SEC-123') for remediation " +
135
+ "tracking. This MUTATES the record. Requires confirm=true.",
136
+ inputSchema: {
137
+ auditProgressId: z.number().int().positive().describe("The test's auditProgressId."),
138
+ jiraId: z.string().min(1).describe("Jira issue key, e.g. 'SEC-123'."),
139
+ confirm: CONFIRM,
140
+ },
141
+ }, async ({ auditProgressId, jiraId, confirm }) => {
142
+ if (!confirm)
143
+ return fail("Refused: link_test_to_jira requires confirm=true.");
144
+ return guard(() => client.linkToJira(auditProgressId, jiraId));
145
+ });
146
+ }
147
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,wEAAwE;AACxE,SAAS,EAAE,CAAC,IAAa;IACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACvF,CAAC;AACD,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,EAA0B;IAC7C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,IAAI,CAAC,qBAAsB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,CAAC;KACd,OAAO,EAAE;KACT,QAAQ,CACP,kGAAkG,CACnG,CAAC;AAEJ,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,MAAoB;IACnE,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,oFAAoF;YACpF,kFAAkF;YAClF,iFAAiF;YACjF,4DAA4D;QAC9D,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YACxE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAC1E,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uDAAuD,CAAC;YACpE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACvF,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;iBAClD,QAAQ,EAAE;iBACV,QAAQ,CAAC,8BAA8B,CAAC;YAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;SAC1E;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAC9D,CAAC;IAEF,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,oFAAoF;YACpF,uFAAuF;YACvF,qFAAqF;YACrF,mEAAmE;QACrE,WAAW,EAAE;YACX,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;SACjF;KACF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CACxB,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvD,MAAM,CAAC,iBAAiB,EAAE;YAC1B,MAAM,CAAC,oBAAoB,EAAE;YAC7B,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;SAC/E,CAAC,CAAC;QACH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAChG,CAAC,CAAC,CACL,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,wFAAwF;YACxF,yFAAyF;YACzF,oFAAoF;QACtF,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE,CACT,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,MAAM,CAAC,mBAAmB,EAAE;YAC5B,MAAM,CAAC,YAAY,EAAE;SACtB,CAAC,CAAC;QACH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IACpC,CAAC,CAAC,CACL,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,uFAAuF;YACvF,yFAAyF;YACzF,kFAAkF;YAClF,+CAA+C;QACjD,WAAW,EAAE;YACX,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpF,OAAO,EAAE,OAAO;SACjB;KACF,EACD,KAAK,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,EAAE;QACrC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACnF,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC;IACxD,CAAC,CACF,CAAC;IAEF,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EACT,+EAA+E;YAC/E,wBAAwB;QAC1B,WAAW,EAAE;YACX,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpF,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;iBACxD,QAAQ,CAAC,sCAAsC,CAAC;YACnD,OAAO,EAAE,OAAO;SACjB;KACF,EACD,KAAK,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE;QACjD,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,sDAAsD,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;IACxE,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,wCAAwC;QAC/C,WAAW,EACT,qFAAqF;YACrF,2DAA2D;QAC7D,WAAW,EAAE;YACX,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YACrE,OAAO,EAAE,OAAO;SACjB;KACF,EACD,KAAK,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC/E,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACjE,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "cataam-mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "MCP connector for Cataam — the GRC/compliance-automation platform (SOC2, GDPR, ISO27001). Exposes the /api/audit compliance surface as MCP tools.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "cataam-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/themarkups/claude-plugin.git",
17
+ "directory": "mcp-server"
18
+ },
19
+ "homepage": "https://github.com/themarkups/claude-plugin#readme",
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.json",
25
+ "start": "node dist/index.js",
26
+ "dev": "node --import tsx src/index.ts",
27
+ "smoke": "node test/smoke.mjs",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "^1.18.0",
32
+ "express": "^4.21.2",
33
+ "zod": "^3.25.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/express": "^4.17.21",
37
+ "@types/node": "^22.10.0",
38
+ "tsx": "^4.19.0",
39
+ "typescript": "^5.7.0"
40
+ }
41
+ }