@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 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 security requirements/checklists. |
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@convisoappsec/mcp",
3
- "version": "0.6.4",
3
+ "version": "0.7.0",
4
4
  "description": "MCP Server for Conviso Platform integration",
5
5
  "type": "module",
6
6
  "main": "src/conviso_mcp/server.js",
@@ -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.',