@convisoappsec/mcp 0.6.4 → 0.7.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 +1 -1
- package/package.json +1 -1
- package/src/conviso_mcp/graphql_client.js +53 -0
- package/src/conviso_mcp/server.js +26 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ The server exposes the following tools to the LLM (see `node/manifest.json` for
|
|
|
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
27
|
| **Tickets** | `get_tickets` / `get_ticket` | List or fetch support/bug tickets. |
|
|
28
|
-
| **Requirements** | `get_requirements` / `get_requirement` / `get_project_requirements` | Browse
|
|
28
|
+
| **Requirements** | `get_requirements` / `get_requirement` / `get_project_requirements` / `get_project_requirement_activities` | Browse requirements/checklists and the instantiated activities of a requirement within a project. When only the project is known, use `get_project_requirements` first to discover the required `project_requirement_id`. |
|
|
29
29
|
| **Applications** | `get_applications` / `get_application` | List or fetch applications and their assets. |
|
|
30
30
|
| **Scans** | `get_scan_histories` / `get_asset_scans_count` | Scan execution history and coverage counts. |
|
|
31
31
|
| **Supply chain** | `get_sbom_components` | SBOM / dependency components per company. |
|
package/package.json
CHANGED
|
@@ -454,6 +454,29 @@ export function buildProjectsVariables(companyId, page = 1, limit = 1000, opts =
|
|
|
454
454
|
return { page, limit, params, sortBy, descending };
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
+
export function buildProjectRequirementActivitiesVariables(projectId, projectRequirementId, {
|
|
458
|
+
page = 1,
|
|
459
|
+
limit = 10,
|
|
460
|
+
title = '',
|
|
461
|
+
sortBy = 'SORT',
|
|
462
|
+
descending = false,
|
|
463
|
+
attachmentActionsOnly,
|
|
464
|
+
} = {}) {
|
|
465
|
+
return {
|
|
466
|
+
page,
|
|
467
|
+
limit,
|
|
468
|
+
sortBy,
|
|
469
|
+
descending,
|
|
470
|
+
historyPagination: { page: 1, perPage: limit },
|
|
471
|
+
attachmentActionsOnly,
|
|
472
|
+
params: compact({
|
|
473
|
+
projectId,
|
|
474
|
+
projectRequirementId,
|
|
475
|
+
title,
|
|
476
|
+
}),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
457
480
|
// Shared HTTP client: keep-alive reuses the TLS connection across the many sequential
|
|
458
481
|
// calls an agent session makes; the timeout stops a hung upstream from hanging a tool
|
|
459
482
|
// call (and the MCP client) forever.
|
|
@@ -911,6 +934,36 @@ class GraphQLClient {
|
|
|
911
934
|
return this.execute(query, { projectId: project_id });
|
|
912
935
|
}
|
|
913
936
|
|
|
937
|
+
async get_project_requirement_activities(project_id, project_requirement_id, options = {}) {
|
|
938
|
+
const query = `
|
|
939
|
+
query GetProjectRequirementActivities(
|
|
940
|
+
$page: Int
|
|
941
|
+
$limit: Int
|
|
942
|
+
$sortBy: ActivitySortByEnum
|
|
943
|
+
$descending: Boolean
|
|
944
|
+
$historyPagination: PaginationInput!
|
|
945
|
+
$attachmentActionsOnly: Boolean
|
|
946
|
+
$params: ActivitiesSearch!
|
|
947
|
+
) {
|
|
948
|
+
activities(page: $page, limit: $limit, params: $params, sortBy: $sortBy, descending: $descending) {
|
|
949
|
+
collection {
|
|
950
|
+
id title status permittedStatus description reference updatedAt reason
|
|
951
|
+
history(pagination: $historyPagination, attachmentActionsOnly: $attachmentActionsOnly) {
|
|
952
|
+
metadata { totalCount }
|
|
953
|
+
}
|
|
954
|
+
portalUser { avatarUrl email name }
|
|
955
|
+
check { description id label }
|
|
956
|
+
assignedUsers { avatarUrl name email }
|
|
957
|
+
}
|
|
958
|
+
metadata { currentPage limitValue totalCount totalPages }
|
|
959
|
+
}
|
|
960
|
+
}`;
|
|
961
|
+
return this.execute(
|
|
962
|
+
query,
|
|
963
|
+
buildProjectRequirementActivitiesVariables(project_id, project_requirement_id, options),
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
|
|
914
967
|
async get_applications(company_id, search = null) {
|
|
915
968
|
const query = `
|
|
916
969
|
query GetApplications($companyId: ID!, $search: String) {
|
|
@@ -400,10 +400,35 @@ function buildServer() {
|
|
|
400
400
|
|
|
401
401
|
tool('get_project_requirements', {
|
|
402
402
|
title: 'Project Requirements',
|
|
403
|
-
desc: 'List the requirements/checklists attached to a project.',
|
|
403
|
+
desc: 'List the requirements/checklists attached to a project. The returned project-requirement id is the project_requirement_id used by get_project_requirement_activities. When the user knows only the project, call this tool first, choose the requested requirement from the results (ask only if ambiguous), then call get_project_requirement_activities.',
|
|
404
404
|
schema: z.object({ project_id: z.number() }),
|
|
405
405
|
}, ({ project_id }) => gql.get_project_requirements(project_id));
|
|
406
406
|
|
|
407
|
+
tool('get_project_requirement_activities', {
|
|
408
|
+
title: 'Project Requirement Activities',
|
|
409
|
+
desc: 'List the instantiated activities for one requirement/checklist within a project, including status, permitted transitions, assignees, references, reason, and history count. Requires the project-requirement association id, not the requirement template id. If the user provides only a project, first call get_project_requirements(project_id) to discover project_requirement_id, then call this tool for the relevant requirement; repeat for each returned requirement when the user asks for all project checklist activities.',
|
|
410
|
+
schema: z.object({
|
|
411
|
+
project_id: z.number(),
|
|
412
|
+
project_requirement_id: z.number(),
|
|
413
|
+
page: z.number().optional(),
|
|
414
|
+
limit: z.number().optional(),
|
|
415
|
+
title: z.string().optional(),
|
|
416
|
+
sort_by: z.string().optional().describe('ActivitySortByEnum value; defaults to SORT.'),
|
|
417
|
+
descending: z.boolean().optional(),
|
|
418
|
+
attachment_actions_only: z.boolean().optional(),
|
|
419
|
+
}),
|
|
420
|
+
}, ({
|
|
421
|
+
project_id, project_requirement_id, page, limit, title, sort_by,
|
|
422
|
+
descending, attachment_actions_only,
|
|
423
|
+
}) => gql.get_project_requirement_activities(project_id, project_requirement_id, {
|
|
424
|
+
page,
|
|
425
|
+
limit,
|
|
426
|
+
title,
|
|
427
|
+
sortBy: sort_by,
|
|
428
|
+
descending,
|
|
429
|
+
attachmentActionsOnly: attachment_actions_only,
|
|
430
|
+
}));
|
|
431
|
+
|
|
407
432
|
tool('get_applications', {
|
|
408
433
|
title: 'List Applications',
|
|
409
434
|
desc: 'List a company\'s applications (name, url, riskScore, assetsCount). Optional: search by name.',
|