@convisoappsec/mcp 0.3.1 → 0.6.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 +28 -18
- package/package.json +8 -4
- package/src/conviso_mcp/filters.js +54 -0
- package/src/conviso_mcp/graphql_client.js +538 -162
- package/src/conviso_mcp/mutations.js +126 -0
- package/src/conviso_mcp/mutations_catalog.json +3174 -0
- package/src/conviso_mcp/operation_allowlist.js +74 -0
- package/src/conviso_mcp/server.js +552 -326
- package/src/conviso_mcp/feed_gateway.js +0 -80
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Conviso MCP Server
|
|
4
4
|
|
|
5
|
-
This
|
|
5
|
+
This `node/` folder contains the Conviso MCP server (Node.js). It is published to npm as `@convisoappsec/mcp` and packaged into the `.mcpb` bundle for MCP clients.
|
|
6
6
|
|
|
7
7
|
## 🛠 Available Tools (Capabilities)
|
|
8
8
|
|
|
@@ -24,12 +24,31 @@ The server exposes the following tools to the LLM (see `node/manifest.json` for
|
|
|
24
24
|
| **Utilities** | `get_today_date` | Return current day/month/year (utility). |
|
|
25
25
|
| **Metrics** | `get_mttr_over_time` | Get Mean Time To Resolution (MTTR) metrics over time for a company. Returns resolution times by severity level. |
|
|
26
26
|
| **Metrics** | `get_overall_risk_score_history` | Get overall risk score history for a company, including current score and difference from last period. |
|
|
27
|
+
| **Tickets** | `get_tickets` / `get_ticket` | List or fetch support/bug tickets. |
|
|
28
|
+
| **Requirements** | `get_requirements` / `get_requirement` / `get_project_requirements` | Browse security requirements/checklists. |
|
|
29
|
+
| **Applications** | `get_applications` / `get_application` | List or fetch applications and their assets. |
|
|
30
|
+
| **Scans** | `get_scan_histories` / `get_asset_scans_count` | Scan execution history and coverage counts. |
|
|
31
|
+
| **Supply chain** | `get_sbom_components` | SBOM / dependency components per company. |
|
|
32
|
+
| **AI-Pentest** | `get_pentest_artifacts` / `get_pentest_artifact` / `get_pentest_execution` | Pentest artifacts, scope and execution results. |
|
|
33
|
+
| **Threat Modeling** | `get_threat_model_artifacts` / `get_threat_model_artifact` | Threat model artifacts and versions. |
|
|
34
|
+
| **Writes — engine** | `list_mutations` / `describe_mutation` / `execute_mutation` | Discover, describe and run the permitted write operations below. |
|
|
35
|
+
| **Writes — Issues** | `execute_mutation` | Create, update, delete and change status of vulnerabilities/issues. |
|
|
36
|
+
| **Writes — Assets** | `execute_mutation` | Create and update assets; run a DAST scan. |
|
|
37
|
+
| **Writes — Tickets** | `execute_mutation` | Create tickets. |
|
|
38
|
+
| **Writes — Projects** | `execute_mutation` | Create, update, change status and remove projects. |
|
|
39
|
+
| **Writes — Requirements** | `execute_mutation` | Create and update requirements. |
|
|
40
|
+
| **Writes — AI-Pentest** | `execute_mutation` | Create artifacts, schedule, trigger executions and retests. |
|
|
41
|
+
| **Writes — Applications** | `execute_mutation` | Create and update applications. |
|
|
42
|
+
| **Writes — Threat Modeling** | `execute_mutation` | Create and update threat-model artifacts and versions. |
|
|
43
|
+
|
|
44
|
+
> Write tools are **Node-only** and limited to the supported client-facing capabilities; see
|
|
45
|
+
> the root `README.md` for the write workflow.
|
|
27
46
|
|
|
28
47
|
## 🚀 Installation and Configuration (Node.js bundle)
|
|
29
48
|
|
|
30
49
|
### Prerequisites
|
|
31
50
|
|
|
32
|
-
* Node.js
|
|
51
|
+
* Node.js 20.10 or later.
|
|
33
52
|
* A Conviso Platform API Key (obtained from your profile settings).
|
|
34
53
|
* An MCP-compatible client (e.g., Claude Desktop, Cursor, etc.).
|
|
35
54
|
|
|
@@ -48,20 +67,6 @@ export CONVISO_API_KEY=your_api_key_here
|
|
|
48
67
|
npm start
|
|
49
68
|
```
|
|
50
69
|
|
|
51
|
-
## Staging (optional)
|
|
52
|
-
|
|
53
|
-
Set the `STAGING` environment variable to `true` to make the server use
|
|
54
|
-
`https://staging.convisoappsec.com` instead of the production API.
|
|
55
|
-
|
|
56
|
-
Example:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
# staging (testing only)
|
|
60
|
-
export STAGING=true
|
|
61
|
-
npm start
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
|
|
65
70
|
## Client configuration examples
|
|
66
71
|
|
|
67
72
|
Below are quick examples showing how to configure Claude Desktop to run the Node bundle locally or via Docker. Paste the appropriate JSON into your Claude Desktop configuration file (see Claude docs for exact path on your OS).
|
|
@@ -119,6 +124,11 @@ docker build -t conviso-mcp-node-image .
|
|
|
119
124
|
|
|
120
125
|
---
|
|
121
126
|
|
|
122
|
-
## Privacy
|
|
127
|
+
## Privacy Policy
|
|
128
|
+
|
|
129
|
+
This connector communicates only with the Conviso Platform API (`https://app.convisoappsec.com`)
|
|
130
|
+
using the API key you provide. It does not collect, store, or share your data with any third
|
|
131
|
+
party — requests and responses stay between your MCP client and the Conviso Platform. Error
|
|
132
|
+
logs go to `stderr` only.
|
|
123
133
|
|
|
124
|
-
|
|
134
|
+
Full privacy policy: https://www.iubenda.com/privacy-policy/55589285
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@convisoappsec/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "MCP Server for Conviso Platform integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/conviso_mcp/server.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "node src/conviso_mcp/server.js",
|
|
9
9
|
"dev": "node src/conviso_mcp/server.js",
|
|
10
|
-
"
|
|
10
|
+
"gen:mutations": "node scripts/generate_mutation_catalog.mjs",
|
|
11
|
+
"test": "node --test"
|
|
11
12
|
},
|
|
12
13
|
"bin": {
|
|
13
14
|
"conviso-mcp": "src/conviso_mcp/server.js"
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
"src"
|
|
17
18
|
],
|
|
18
19
|
"engines": {
|
|
19
|
-
"node": ">=
|
|
20
|
+
"node": ">=20.10.0"
|
|
20
21
|
},
|
|
21
22
|
"publishConfig": {
|
|
22
23
|
"access": "public"
|
|
@@ -43,8 +44,11 @@
|
|
|
43
44
|
"dependencies": {
|
|
44
45
|
"@hono/node-server": "^1.19.11",
|
|
45
46
|
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
46
|
-
"axios": "^1.
|
|
47
|
+
"axios": "^1.16.1",
|
|
47
48
|
"dotenv": "^16.6.1",
|
|
48
49
|
"zod": "^4.3.6"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"graphql": "^16.9.0"
|
|
49
53
|
}
|
|
50
54
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// node/src/conviso_mcp/filters.js
|
|
2
|
+
// Pure helpers for building GraphQL filter/sort variables. No network.
|
|
3
|
+
|
|
4
|
+
export const SEVERITIES = ['NOTIFICATION', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
|
|
5
|
+
export const ISSUE_STATUSES = ['CREATED', 'DRAFT', 'IDENTIFIED', 'IN_PROGRESS', 'AWAITING_VALIDATION', 'FIX_ACCEPTED', 'RISK_ACCEPTED', 'FALSE_POSITIVE', 'SUPPRESSED'];
|
|
6
|
+
export const SLA_STATES = ['ON_TRACK', 'APPROACHING', 'BREACHED', 'RESOLVED', 'NOT_TRACKED', 'NOT_PARAMETERIZED'];
|
|
7
|
+
export const BUSINESS_IMPACT = ['LOW', 'MEDIUM', 'HIGH', 'NOT_DEFINED'];
|
|
8
|
+
export const EXPLOITABILITY = ['INTERNET_FACING', 'INTERNAL', 'NOT_DEFINED'];
|
|
9
|
+
export const REACHABILITY = ['STATIC_ANALYSIS', 'DYNAMIC_ANALYSIS'];
|
|
10
|
+
export const ISSUE_SORT_BY = ['RISK_SCORE', 'SEVERITY', 'ID', 'CREATED_AT', 'UPDATED_AT', 'SLA_DUE_AT'];
|
|
11
|
+
export const ASSET_SORT_BY = ['updated_at', 'name', 'business_impact', 'risk_score'];
|
|
12
|
+
export const ORDER = ['ASC', 'DESC'];
|
|
13
|
+
|
|
14
|
+
export function normalizeEnum(value, allowed, upper = true) {
|
|
15
|
+
if (value === null || value === undefined) return null;
|
|
16
|
+
let s = String(value).trim();
|
|
17
|
+
s = upper ? s.toUpperCase() : s.toLowerCase();
|
|
18
|
+
return allowed.includes(s) ? s : null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function normalizeEnumList(values, allowed, upper = true) {
|
|
22
|
+
if (!values || values.length === 0) return [];
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const v of values) {
|
|
25
|
+
const s = normalizeEnum(v, allowed, upper);
|
|
26
|
+
if (s !== null) out.push(s);
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function buildDateRange(after, before) {
|
|
32
|
+
const rng = {};
|
|
33
|
+
if (after) rng.startDate = after;
|
|
34
|
+
if (before) rng.endDate = before;
|
|
35
|
+
return Object.keys(rng).length ? rng : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function buildIssueSortOptions(sortBy, order) {
|
|
39
|
+
const sb = normalizeEnum(sortBy, ISSUE_SORT_BY);
|
|
40
|
+
if (sb === null) return [];
|
|
41
|
+
const ord = normalizeEnum(order, ORDER) || 'DESC';
|
|
42
|
+
return [{ sortBy: sb, order: ord }];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function prune(obj) {
|
|
46
|
+
const out = {};
|
|
47
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
48
|
+
if (v === null || v === undefined || v === '') continue;
|
|
49
|
+
if (Array.isArray(v) && v.length === 0) continue;
|
|
50
|
+
if (typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length === 0) continue;
|
|
51
|
+
out[k] = v;
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|