@transcend-io/mcp-server-assessment 0.3.8 → 0.3.12
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 +6 -5
- package/dist/cli.mjs +4 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/{graphql-7PovZAly.mjs → graphql-DMh8AG9n.mjs} +140 -43
- package/dist/graphql-DMh8AG9n.mjs.map +1 -0
- package/dist/index.d.mts +29 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +4 -4
- package/dist/graphql-7PovZAly.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -66,11 +66,12 @@ See [CONTRIBUTING.md](../../../CONTRIBUTING.md#mcp-servers) for workspace layout
|
|
|
66
66
|
|
|
67
67
|
### Environment variables
|
|
68
68
|
|
|
69
|
-
| Variable
|
|
70
|
-
|
|
|
71
|
-
| `TRANSCEND_API_KEY`
|
|
72
|
-
| `TRANSCEND_API_URL`
|
|
73
|
-
| `SOMBRA_URL`
|
|
69
|
+
| Variable | Required | Default | Description |
|
|
70
|
+
| ------------------------- | -------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `TRANSCEND_API_KEY` | Yes | — | Transcend API key |
|
|
72
|
+
| `TRANSCEND_API_URL` | No | `https://api.transcend.io` | GraphQL backend API URL (matches CLI convention) |
|
|
73
|
+
| `SOMBRA_URL` | No | `https://multi-tenant.sombra.transcend.io` | Sombra REST API URL (matches CLI / SDK convention) |
|
|
74
|
+
| `TRANSCEND_DASHBOARD_URL` | No | `https://app.transcend.io` | Override the admin-dashboard base URL used for deep links returned by tool responses. Intended for local development against staging / fake hosts |
|
|
74
75
|
|
|
75
76
|
**Monorepo:** keep these in root **`secret.env`** (from [`secret.env.example`](../../../secret.env.example)); see **Run from the monorepo**.
|
|
76
77
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as getAssessmentTools, t as AssessmentsMixin } from "./graphql-
|
|
2
|
+
import { n as getAssessmentTools, t as AssessmentsMixin } from "./graphql-DMh8AG9n.mjs";
|
|
3
3
|
import { TranscendRestClient, createMCPServer } from "@transcend-io/mcp-server-base";
|
|
4
4
|
//#region src/cli.ts
|
|
5
5
|
createMCPServer({
|
|
6
6
|
name: "transcend-mcp-assessment",
|
|
7
7
|
version: "1.0.0",
|
|
8
8
|
getTools: getAssessmentTools,
|
|
9
|
-
createClients: (auth, sombraUrl, graphqlUrl) => ({
|
|
9
|
+
createClients: ({ auth, sombraUrl, graphqlUrl, dashboardUrl }) => ({
|
|
10
10
|
rest: new TranscendRestClient(auth, sombraUrl),
|
|
11
|
-
graphql: new AssessmentsMixin(auth, graphqlUrl)
|
|
11
|
+
graphql: new AssessmentsMixin(auth, graphqlUrl),
|
|
12
|
+
dashboardUrl
|
|
12
13
|
})
|
|
13
14
|
});
|
|
14
15
|
//#endregion
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createMCPServer, TranscendRestClient } from '@transcend-io/mcp-server-base';\n\nimport { AssessmentsMixin } from './graphql.js';\nimport { getAssessmentTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-assessment',\n version: '1.0.0',\n getTools: getAssessmentTools,\n createClients: (auth, sombraUrl, graphqlUrl) => ({\n rest: new TranscendRestClient(auth, sombraUrl),\n graphql: new AssessmentsMixin(auth, graphqlUrl),\n }),\n});\n"],"mappings":";;;;AAMA,gBAAgB;CACd,MAAM;CACN,SAAS;CACT,UAAU;CACV,gBAAgB,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createMCPServer, TranscendRestClient } from '@transcend-io/mcp-server-base';\n\nimport { AssessmentsMixin } from './graphql.js';\nimport { getAssessmentTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-assessment',\n version: '1.0.0',\n getTools: getAssessmentTools,\n createClients: ({ auth, sombraUrl, graphqlUrl, dashboardUrl }) => ({\n rest: new TranscendRestClient(auth, sombraUrl),\n graphql: new AssessmentsMixin(auth, graphqlUrl),\n dashboardUrl,\n }),\n});\n"],"mappings":";;;;AAMA,gBAAgB;CACd,MAAM;CACN,SAAS;CACT,UAAU;CACV,gBAAgB,EAAE,MAAM,WAAW,YAAY,oBAAoB;EACjE,MAAM,IAAI,oBAAoB,MAAM,UAAU;EAC9C,SAAS,IAAI,iBAAiB,MAAM,WAAW;EAC/C;EACD;CACF,CAAC"}
|
|
@@ -69,6 +69,23 @@ function createAssessmentsAnswerQuestionTool(clients) {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
//#endregion
|
|
72
|
+
//#region src/helpers/buildAssessmentLinks.ts
|
|
73
|
+
/**
|
|
74
|
+
* Build the canonical admin-dashboard deep link for an assessment.
|
|
75
|
+
*
|
|
76
|
+
* Always points at `/assessments/forms/:id/response`, mirroring the
|
|
77
|
+
* dashboard's own "View Responses" row action. The fillable
|
|
78
|
+
* `/assessments/forms/:id/view` route is intentionally not emitted —
|
|
79
|
+
* it only resolves for the form's assignee, which the MCP can't verify.
|
|
80
|
+
*/
|
|
81
|
+
function buildAssessmentLinks({ dashboardUrl, assessmentFormId }) {
|
|
82
|
+
return { url: `${dashboardUrl.replace(/\/$/, "")}/assessments/forms/${assessmentFormId}/response` };
|
|
83
|
+
}
|
|
84
|
+
/** Build a link to the assessment-group page (for group-level tools). */
|
|
85
|
+
function buildAssessmentGroupUrl(dashboardUrl, assessmentGroupId) {
|
|
86
|
+
return `${dashboardUrl.replace(/\/$/, "")}/assessments/groups/${assessmentGroupId}`;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
72
89
|
//#region src/tools/_helpers.ts
|
|
73
90
|
/**
|
|
74
91
|
* Resolves a template_id to an assessment group ID by searching through all groups.
|
|
@@ -90,9 +107,10 @@ const CreateAssessmentSchema = z.object({
|
|
|
90
107
|
});
|
|
91
108
|
function createAssessmentsCreateTool(clients) {
|
|
92
109
|
const graphql = clients.graphql;
|
|
110
|
+
const { dashboardUrl } = clients;
|
|
93
111
|
return defineTool({
|
|
94
112
|
name: "assessments_create",
|
|
95
|
-
description: "Create a new privacy assessment within an assessment group. Assessment groups are linked to templates. You can provide either an assessment_group_id directly, or a template_id to auto-resolve the first matching group. Use assessments_list_groups to find available groups.",
|
|
113
|
+
description: "Create a new privacy assessment within an assessment group. Assessment groups are linked to templates. You can provide either an assessment_group_id directly, or a template_id to auto-resolve the first matching group. Use assessments_list_groups to find available groups. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
|
|
96
114
|
category: "Assessments",
|
|
97
115
|
readOnly: false,
|
|
98
116
|
confirmationHint: "Creates a new privacy assessment",
|
|
@@ -110,13 +128,22 @@ function createAssessmentsCreateTool(clients) {
|
|
|
110
128
|
assessmentGroupId = resolved.groupId;
|
|
111
129
|
}
|
|
112
130
|
if (!assessmentGroupId) return createToolResult(false, void 0, "Either assessment_group_id or template_id must be provided. Use assessments_list_groups to find available groups.");
|
|
131
|
+
const result = await graphql.createAssessment({
|
|
132
|
+
title,
|
|
133
|
+
assessmentGroupId,
|
|
134
|
+
assigneeIds: assignee_ids
|
|
135
|
+
});
|
|
136
|
+
const links = buildAssessmentLinks({
|
|
137
|
+
dashboardUrl,
|
|
138
|
+
assessmentFormId: result.id
|
|
139
|
+
});
|
|
113
140
|
return createToolResult(true, {
|
|
114
|
-
assessment:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
message: `Assessment "${title}" created successfully`
|
|
141
|
+
assessment: {
|
|
142
|
+
...result,
|
|
143
|
+
...links
|
|
144
|
+
},
|
|
145
|
+
...links,
|
|
146
|
+
message: `Assessment "${title}" created successfully. Open it at ${links.url}`
|
|
120
147
|
});
|
|
121
148
|
}
|
|
122
149
|
});
|
|
@@ -131,9 +158,10 @@ const CreateGroupSchema = z.object({
|
|
|
131
158
|
});
|
|
132
159
|
function createAssessmentsCreateGroupTool(clients) {
|
|
133
160
|
const graphql = clients.graphql;
|
|
161
|
+
const { dashboardUrl } = clients;
|
|
134
162
|
return defineTool({
|
|
135
163
|
name: "assessments_create_group",
|
|
136
|
-
description: "Create a new assessment group linked to a template. Assessment groups are containers for assessments.",
|
|
164
|
+
description: "Create a new assessment group linked to a template. Assessment groups are containers for assessments. The response includes a `groupUrl` field with the canonical admin-dashboard link to the group — surface that to the user verbatim.",
|
|
137
165
|
category: "Assessments",
|
|
138
166
|
readOnly: false,
|
|
139
167
|
confirmationHint: "Creates a new assessment group",
|
|
@@ -144,14 +172,20 @@ function createAssessmentsCreateGroupTool(clients) {
|
|
|
144
172
|
},
|
|
145
173
|
zodSchema: CreateGroupSchema,
|
|
146
174
|
handler: async ({ title, template_id, description, reviewer_ids }) => {
|
|
175
|
+
const result = await graphql.createAssessmentGroup({
|
|
176
|
+
title,
|
|
177
|
+
assessmentFormTemplateId: template_id,
|
|
178
|
+
description,
|
|
179
|
+
reviewerIds: reviewer_ids
|
|
180
|
+
});
|
|
181
|
+
const groupUrl = buildAssessmentGroupUrl(dashboardUrl, result.id);
|
|
147
182
|
return createToolResult(true, {
|
|
148
|
-
assessmentGroup:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
message: `Assessment group "${title}" created successfully`
|
|
183
|
+
assessmentGroup: {
|
|
184
|
+
...result,
|
|
185
|
+
groupUrl
|
|
186
|
+
},
|
|
187
|
+
groupUrl,
|
|
188
|
+
message: `Assessment group "${title}" created successfully. View it at ${groupUrl}`
|
|
155
189
|
});
|
|
156
190
|
}
|
|
157
191
|
});
|
|
@@ -246,9 +280,10 @@ const GetAssessmentSchema = z.object({
|
|
|
246
280
|
});
|
|
247
281
|
function createAssessmentsGetTool(clients) {
|
|
248
282
|
const graphql = clients.graphql;
|
|
283
|
+
const { dashboardUrl } = clients;
|
|
249
284
|
return defineTool({
|
|
250
285
|
name: "assessments_get",
|
|
251
|
-
description: "Get detailed information about a specific assessment including questions and responses",
|
|
286
|
+
description: "Get detailed information about a specific assessment including questions and responses. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
|
|
252
287
|
category: "Assessments",
|
|
253
288
|
readOnly: true,
|
|
254
289
|
annotations: {
|
|
@@ -258,7 +293,15 @@ function createAssessmentsGetTool(clients) {
|
|
|
258
293
|
},
|
|
259
294
|
zodSchema: GetAssessmentSchema,
|
|
260
295
|
handler: async ({ assessment_id }) => {
|
|
261
|
-
|
|
296
|
+
const result = await graphql.getAssessment(assessment_id);
|
|
297
|
+
const links = buildAssessmentLinks({
|
|
298
|
+
dashboardUrl,
|
|
299
|
+
assessmentFormId: result.id
|
|
300
|
+
});
|
|
301
|
+
return createToolResult(true, {
|
|
302
|
+
...result,
|
|
303
|
+
...links
|
|
304
|
+
});
|
|
262
305
|
}
|
|
263
306
|
});
|
|
264
307
|
}
|
|
@@ -268,9 +311,10 @@ const AssessmentStatusEnum = z.nativeEnum(AssessmentFormStatus);
|
|
|
268
311
|
const ListAssessmentsSchema = z.object({ status: AssessmentStatusEnum.optional().describe("Filter by assessment status") }).merge(PaginationSchema);
|
|
269
312
|
function createAssessmentsListTool(clients) {
|
|
270
313
|
const graphql = clients.graphql;
|
|
314
|
+
const { dashboardUrl } = clients;
|
|
271
315
|
return defineTool({
|
|
272
316
|
name: "assessments_list",
|
|
273
|
-
description: "List all privacy assessments in your organization. Supports filtering by status. Note: Cursor pagination is not supported (max 100 results).",
|
|
317
|
+
description: "List all privacy assessments in your organization. Supports filtering by status. Each row includes a `url` field with the canonical admin-dashboard link for that assessment — surface those to the user verbatim and do not construct assessment URLs from raw IDs. Note: Cursor pagination is not supported (max 100 results).",
|
|
274
318
|
category: "Assessments",
|
|
275
319
|
readOnly: true,
|
|
276
320
|
annotations: {
|
|
@@ -285,7 +329,13 @@ function createAssessmentsListTool(clients) {
|
|
|
285
329
|
after: cursor,
|
|
286
330
|
filterBy: status ? { statuses: [status] } : void 0
|
|
287
331
|
});
|
|
288
|
-
return createListResult(result.nodes
|
|
332
|
+
return createListResult(result.nodes.map((node) => ({
|
|
333
|
+
...node,
|
|
334
|
+
...buildAssessmentLinks({
|
|
335
|
+
dashboardUrl,
|
|
336
|
+
assessmentFormId: node.id
|
|
337
|
+
})
|
|
338
|
+
})), {
|
|
289
339
|
totalCount: result.totalCount,
|
|
290
340
|
hasNextPage: result.pageInfo?.hasNextPage
|
|
291
341
|
});
|
|
@@ -297,9 +347,10 @@ function createAssessmentsListTool(clients) {
|
|
|
297
347
|
const ListGroupsSchema = PaginationSchema;
|
|
298
348
|
function createAssessmentsListGroupsTool(clients) {
|
|
299
349
|
const graphql = clients.graphql;
|
|
350
|
+
const { dashboardUrl } = clients;
|
|
300
351
|
return defineTool({
|
|
301
352
|
name: "assessments_list_groups",
|
|
302
|
-
description: "List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments.",
|
|
353
|
+
description: "List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments. Each row includes a `groupUrl` field with the canonical admin-dashboard link — surface those to the user verbatim.",
|
|
303
354
|
category: "Assessments",
|
|
304
355
|
readOnly: true,
|
|
305
356
|
annotations: {
|
|
@@ -313,7 +364,10 @@ function createAssessmentsListGroupsTool(clients) {
|
|
|
313
364
|
first: limit,
|
|
314
365
|
after: cursor
|
|
315
366
|
});
|
|
316
|
-
return createListResult(result.nodes
|
|
367
|
+
return createListResult(result.nodes.map((node) => ({
|
|
368
|
+
...node,
|
|
369
|
+
groupUrl: buildAssessmentGroupUrl(dashboardUrl, node.id)
|
|
370
|
+
})), {
|
|
317
371
|
totalCount: result.totalCount,
|
|
318
372
|
hasNextPage: result.pageInfo?.hasNextPage
|
|
319
373
|
});
|
|
@@ -518,9 +572,10 @@ const SubmitResponseSchema = z.object({
|
|
|
518
572
|
});
|
|
519
573
|
function createAssessmentsSubmitResponseTool(clients) {
|
|
520
574
|
const graphql = clients.graphql;
|
|
575
|
+
const { dashboardUrl } = clients;
|
|
521
576
|
return defineTool({
|
|
522
577
|
name: "assessments_submit_response",
|
|
523
|
-
description: "Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status.",
|
|
578
|
+
description: "Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status. The response includes a `url` field pointing at the assessment-group page where reviewers can find the submitted form — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
|
|
524
579
|
category: "Assessments",
|
|
525
580
|
readOnly: false,
|
|
526
581
|
confirmationHint: "Submits assessment for review — cannot be undone",
|
|
@@ -531,12 +586,21 @@ function createAssessmentsSubmitResponseTool(clients) {
|
|
|
531
586
|
},
|
|
532
587
|
zodSchema: SubmitResponseSchema,
|
|
533
588
|
handler: async ({ assessment_id, assessment_section_ids }) => {
|
|
589
|
+
const result = await graphql.submitAssessmentForReview({
|
|
590
|
+
id: assessment_id,
|
|
591
|
+
assessmentSectionIds: assessment_section_ids
|
|
592
|
+
});
|
|
593
|
+
const links = buildAssessmentLinks({
|
|
594
|
+
dashboardUrl,
|
|
595
|
+
assessmentFormId: result.id
|
|
596
|
+
});
|
|
534
597
|
return createToolResult(true, {
|
|
535
|
-
assessment:
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
|
|
598
|
+
assessment: {
|
|
599
|
+
...result,
|
|
600
|
+
...links
|
|
601
|
+
},
|
|
602
|
+
...links,
|
|
603
|
+
message: `Assessment submitted for review successfully. View it at ${links.url}`
|
|
540
604
|
});
|
|
541
605
|
}
|
|
542
606
|
});
|
|
@@ -553,9 +617,10 @@ const UpdateAssessmentSchema = z.object({
|
|
|
553
617
|
});
|
|
554
618
|
function createAssessmentsUpdateTool(clients) {
|
|
555
619
|
const graphql = clients.graphql;
|
|
620
|
+
const { dashboardUrl } = clients;
|
|
556
621
|
return defineTool({
|
|
557
622
|
name: "assessments_update",
|
|
558
|
-
description: "Update an existing assessment",
|
|
623
|
+
description: "Update an existing assessment. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
|
|
559
624
|
category: "Assessments",
|
|
560
625
|
readOnly: false,
|
|
561
626
|
confirmationHint: "Updates the assessment",
|
|
@@ -566,16 +631,25 @@ function createAssessmentsUpdateTool(clients) {
|
|
|
566
631
|
},
|
|
567
632
|
zodSchema: UpdateAssessmentSchema,
|
|
568
633
|
handler: async ({ assessment_id, title, description, reviewer_ids, due_date, status }) => {
|
|
634
|
+
const result = await graphql.updateAssessment({
|
|
635
|
+
id: assessment_id,
|
|
636
|
+
title,
|
|
637
|
+
description,
|
|
638
|
+
reviewerIds: reviewer_ids,
|
|
639
|
+
dueDate: due_date,
|
|
640
|
+
status
|
|
641
|
+
});
|
|
642
|
+
const links = buildAssessmentLinks({
|
|
643
|
+
dashboardUrl,
|
|
644
|
+
assessmentFormId: result.id
|
|
645
|
+
});
|
|
569
646
|
return createToolResult(true, {
|
|
570
|
-
assessment:
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
status
|
|
577
|
-
}),
|
|
578
|
-
message: "Assessment updated successfully"
|
|
647
|
+
assessment: {
|
|
648
|
+
...result,
|
|
649
|
+
...links
|
|
650
|
+
},
|
|
651
|
+
...links,
|
|
652
|
+
message: `Assessment updated successfully. View it at ${links.url}`
|
|
579
653
|
});
|
|
580
654
|
}
|
|
581
655
|
});
|
|
@@ -675,6 +749,9 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
675
749
|
title
|
|
676
750
|
status
|
|
677
751
|
createdAt
|
|
752
|
+
assessmentGroup {
|
|
753
|
+
id
|
|
754
|
+
}
|
|
678
755
|
}
|
|
679
756
|
totalCount
|
|
680
757
|
}
|
|
@@ -684,7 +761,10 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
684
761
|
filterBy: options?.filterBy?.statuses ? { statuses: options.filterBy.statuses } : void 0
|
|
685
762
|
});
|
|
686
763
|
return {
|
|
687
|
-
nodes: data.assessmentForms.nodes,
|
|
764
|
+
nodes: data.assessmentForms.nodes.map(({ assessmentGroup, ...rest }) => ({
|
|
765
|
+
...rest,
|
|
766
|
+
assessmentGroupId: assessmentGroup?.id
|
|
767
|
+
})),
|
|
688
768
|
pageInfo: {
|
|
689
769
|
hasNextPage: data.assessmentForms.nodes.length < data.assessmentForms.totalCount,
|
|
690
770
|
hasPreviousPage: false
|
|
@@ -704,6 +784,9 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
704
784
|
submittedAt
|
|
705
785
|
createdAt
|
|
706
786
|
updatedAt
|
|
787
|
+
assessmentGroup {
|
|
788
|
+
id
|
|
789
|
+
}
|
|
707
790
|
sections {
|
|
708
791
|
id
|
|
709
792
|
title
|
|
@@ -735,7 +818,11 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
735
818
|
}
|
|
736
819
|
`, { ids: [id] })).assessmentForms.nodes[0];
|
|
737
820
|
if (!node) throw new Error(`Assessment with id ${id} not found`);
|
|
738
|
-
|
|
821
|
+
const { assessmentGroup, ...rest } = node;
|
|
822
|
+
return {
|
|
823
|
+
...rest,
|
|
824
|
+
assessmentGroupId: assessmentGroup?.id
|
|
825
|
+
};
|
|
739
826
|
}
|
|
740
827
|
async selectAssessmentQuestionAnswers(input) {
|
|
741
828
|
return (await this.makeRequest(`
|
|
@@ -820,10 +907,13 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
820
907
|
}] };
|
|
821
908
|
const created = (await this.makeRequest(mutation, { input: batchInput })).createAssessmentForms.assessmentForms[0];
|
|
822
909
|
if (!created) throw new Error("createAssessmentForms returned an empty array");
|
|
823
|
-
return
|
|
910
|
+
return {
|
|
911
|
+
...created,
|
|
912
|
+
assessmentGroupId: input.assessmentGroupId
|
|
913
|
+
};
|
|
824
914
|
}
|
|
825
915
|
async updateAssessment(input) {
|
|
826
|
-
|
|
916
|
+
const { assessmentGroup, ...rest } = (await this.makeRequest(`
|
|
827
917
|
mutation UpdateAssessmentForm($input: UpdateAssessmentFormInput!) {
|
|
828
918
|
updateAssessmentForm(input: $input) {
|
|
829
919
|
assessmentForm {
|
|
@@ -833,10 +923,17 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
833
923
|
status
|
|
834
924
|
dueDate
|
|
835
925
|
updatedAt
|
|
926
|
+
assessmentGroup {
|
|
927
|
+
id
|
|
928
|
+
}
|
|
836
929
|
}
|
|
837
930
|
}
|
|
838
931
|
}
|
|
839
932
|
`, { input })).updateAssessmentForm.assessmentForm;
|
|
933
|
+
return {
|
|
934
|
+
...rest,
|
|
935
|
+
assessmentGroupId: assessmentGroup?.id
|
|
936
|
+
};
|
|
840
937
|
}
|
|
841
938
|
async listAssessmentTemplates(options) {
|
|
842
939
|
const data = await this.makeRequest(`
|
|
@@ -1015,6 +1112,6 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
|
|
|
1015
1112
|
}
|
|
1016
1113
|
};
|
|
1017
1114
|
//#endregion
|
|
1018
|
-
export {
|
|
1115
|
+
export { buildAssessmentLinks as _, SubmitResponseSchema as a, AddSectionSchema as b, ListGroupsSchema as c, GetAssessmentSchema as d, ExportTemplateSchema as f, buildAssessmentGroupUrl as g, CreateAssessmentSchema as h, UpdateAssessmentSchema as i, AssessmentStatusEnum as l, CreateGroupSchema as m, getAssessmentTools as n, PrefillSchema as o, CreateTemplateSchema as p, UpdateAssigneesSchema as r, ListTemplatesSchema as s, AssessmentsMixin as t, ListAssessmentsSchema as u, AnswerQuestionSchema as v, AnswerQuestionValueSchema as y };
|
|
1019
1116
|
|
|
1020
|
-
//# sourceMappingURL=graphql-
|
|
1117
|
+
//# sourceMappingURL=graphql-DMh8AG9n.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-DMh8AG9n.mjs","names":[],"sources":["../src/tools/assessments_add_section.ts","../src/tools/assessments_answer_question.ts","../src/helpers/buildAssessmentLinks.ts","../src/tools/_helpers.ts","../src/tools/assessments_create.ts","../src/tools/assessments_create_group.ts","../src/tools/assessments_create_template.ts","../src/tools/assessments_export_template.ts","../src/tools/assessments_get.ts","../src/tools/assessments_list.ts","../src/tools/assessments_list_groups.ts","../src/tools/assessments_list_templates.ts","../src/tools/assessments_prefill.ts","../src/tools/assessments_submit_response.ts","../src/tools/assessments_update.ts","../src/tools/assessments_update_assignees.ts","../src/tools/index.ts","../src/graphql.ts"],"sourcesContent":["import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type AssessmentSectionInput,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const AddSectionSchema = z.object({\n template_id: z.string().describe('ID of the assessment form template to add the section to'),\n title: z.string().describe('Title of the new section'),\n questions: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe(\n 'Array of question objects: [{title, type, subType?, description?, placeholder?, isRequired?, referenceId?, answerOptions?: [{value}], allowSelectOther?, requireRiskEvaluation?}]',\n ),\n});\nexport type AddSectionInput = z.infer<typeof AddSectionSchema>;\n\nexport function createAssessmentsAddSectionTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_add_section',\n description:\n 'Add a new section (with optional inline questions) to an existing assessment form template. ' +\n 'Useful for building templates incrementally or adding sections to imported templates. ' +\n 'Same auto-corrections as assessments_create_template apply to questions.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Adds a section to the assessment template',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: AddSectionSchema,\n handler: async ({ template_id, title, questions }) => {\n const result = await graphql.createAssessmentSection({\n assessmentFormTemplateId: template_id,\n title,\n questions: questions as AssessmentSectionInput['questions'],\n });\n\n return createToolResult(true, {\n section: result,\n message: `Section \"${title}\" added to template successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const AnswerQuestionValueSchema = z.object({\n value: z.string(),\n isUserCreated: z.boolean(),\n});\nexport type AnswerQuestionValueInput = z.infer<typeof AnswerQuestionValueSchema>;\n\nexport const AnswerQuestionSchema = z.object({\n assessment_question_id: z.string().describe('ID of the assessment question to answer'),\n assessment_answer_ids: z\n .array(z.string())\n .optional()\n .describe(\n 'IDs of existing answer options to select (for SINGLE_SELECT/MULTI_SELECT questions)',\n ),\n assessment_answer_values: z\n .array(AnswerQuestionValueSchema)\n .optional()\n .describe(\n 'Free-text answer values to create and select (for text questions). Each item: {value: string, isUserCreated: boolean}',\n ),\n});\nexport type AnswerQuestionInput = z.infer<typeof AnswerQuestionSchema>;\n\nexport function createAssessmentsAnswerQuestionTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_answer_question',\n description:\n 'Answer an assessment question by selecting existing answer options or providing free-text values. For SINGLE_SELECT/MULTI_SELECT questions, provide assessmentAnswerIds from the answerOptions. For SHORT_ANSWER_TEXT/LONG_ANSWER_TEXT, provide assessmentAnswerValues with {value, isUserCreated: true}.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Records answer to the assessment question',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: AnswerQuestionSchema,\n handler: async ({\n assessment_question_id,\n assessment_answer_ids,\n assessment_answer_values,\n }) => {\n const input: {\n assessmentQuestionId: string;\n assessmentAnswerIds?: string[];\n assessmentAnswerValues?: { value: string; isUserCreated: boolean }[];\n } = {\n assessmentQuestionId: assessment_question_id,\n };\n\n if (assessment_answer_ids) {\n input.assessmentAnswerIds = assessment_answer_ids;\n }\n if (assessment_answer_values) {\n input.assessmentAnswerValues = assessment_answer_values;\n }\n\n const result = await graphql.selectAssessmentQuestionAnswers(input);\n\n return createToolResult(true, {\n selectedAnswers: result,\n message: 'Assessment question answered successfully',\n });\n },\n });\n}\n","/** Inputs to {@link buildAssessmentLinks}. */\nexport interface BuildAssessmentLinksInput {\n /** Base admin-dashboard URL (e.g. `https://app.transcend.io`) */\n dashboardUrl: string;\n /** The assessment form ID */\n assessmentFormId: string;\n}\n\n/** Deep link into the Transcend admin dashboard for a given assessment. */\nexport interface AssessmentLinks {\n /** Read-only response page for the assessment. */\n url: string;\n}\n\n/**\n * Build the canonical admin-dashboard deep link for an assessment.\n *\n * Always points at `/assessments/forms/:id/response`, mirroring the\n * dashboard's own \"View Responses\" row action. The fillable\n * `/assessments/forms/:id/view` route is intentionally not emitted —\n * it only resolves for the form's assignee, which the MCP can't verify.\n */\nexport function buildAssessmentLinks({\n dashboardUrl,\n assessmentFormId,\n}: BuildAssessmentLinksInput): AssessmentLinks {\n const base = dashboardUrl.replace(/\\/$/, '');\n return { url: `${base}/assessments/forms/${assessmentFormId}/response` };\n}\n\n/** Build a link to the assessment-group page (for group-level tools). */\nexport function buildAssessmentGroupUrl(dashboardUrl: string, assessmentGroupId: string): string {\n return `${dashboardUrl.replace(/\\/$/, '')}/assessments/groups/${assessmentGroupId}`;\n}\n","import { createToolResult } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\n/**\n * Resolves a template_id to an assessment group ID by searching through all groups.\n * Returns either the group ID or an error result.\n */\nexport async function resolveTemplateToGroupId(\n graphql: AssessmentsMixin,\n templateId: string,\n): Promise<{ groupId: string } | { error: ReturnType<typeof createToolResult> }> {\n const groups = await graphql.listAssessmentGroups({ first: 100 });\n const matchingGroups = groups.nodes.filter((g) => g.assessmentFormTemplate?.id === templateId);\n\n if (matchingGroups.length === 0) {\n return {\n error: createToolResult(\n false,\n undefined,\n `No assessment group found for template_id \"${templateId}\". Use assessments_list_groups to see available groups.`,\n ),\n };\n }\n\n if (matchingGroups.length > 1) {\n const ids = matchingGroups.map((g) => g.id).join(', ');\n return {\n error: createToolResult(\n false,\n undefined,\n `Multiple assessment groups found for template_id \"${templateId}\" (group IDs: ${ids}). ` +\n `Please specify assessment_group_id explicitly. Use assessments_list_groups to find available groups.`,\n ),\n };\n }\n\n return { groupId: matchingGroups[0]!.id };\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentLinks } from '../helpers/buildAssessmentLinks.js';\nimport { resolveTemplateToGroupId } from './_helpers.js';\n\nexport const CreateAssessmentSchema = z.object({\n title: z.string().describe('Title of the assessment'),\n assessment_group_id: z\n .string()\n .optional()\n .describe(\n 'ID of the assessment group to create the assessment in (preferred). Use assessments_list_groups to find available groups.',\n ),\n template_id: z\n .string()\n .optional()\n .describe(\n 'ID of the assessment template. If assessment_group_id is not provided, the first group using this template will be used.',\n ),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Array of user IDs to assign the assessment to'),\n});\nexport type CreateAssessmentInput = z.infer<typeof CreateAssessmentSchema>;\n\nexport function createAssessmentsCreateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_create',\n description:\n 'Create a new privacy assessment within an assessment group. Assessment groups are linked to templates. You can provide either an assessment_group_id directly, or a template_id to auto-resolve the first matching group. Use assessments_list_groups to find available groups. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new privacy assessment',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateAssessmentSchema,\n handler: async ({ title, assessment_group_id, template_id, assignee_ids }) => {\n let assessmentGroupId = assessment_group_id;\n\n if (!assessmentGroupId && template_id) {\n const resolved = await resolveTemplateToGroupId(graphql, template_id);\n if ('error' in resolved) return resolved.error;\n assessmentGroupId = resolved.groupId;\n }\n\n if (!assessmentGroupId) {\n return createToolResult(\n false,\n undefined,\n 'Either assessment_group_id or template_id must be provided. Use assessments_list_groups to find available groups.',\n );\n }\n\n const result = await graphql.createAssessment({\n title,\n assessmentGroupId,\n assigneeIds: assignee_ids,\n });\n\n const links = buildAssessmentLinks({ dashboardUrl, assessmentFormId: result.id });\n\n return createToolResult(true, {\n assessment: { ...result, ...links },\n ...links,\n message: `Assessment \"${title}\" created successfully. Open it at ${links.url}`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentGroupUrl } from '../helpers/buildAssessmentLinks.js';\n\nexport const CreateGroupSchema = z.object({\n title: z.string().describe('Title of the assessment group'),\n template_id: z.string().describe('ID of the assessment template to link this group to'),\n description: z.string().optional().describe('Description of the assessment group (optional)'),\n reviewer_ids: z\n .array(z.string())\n .optional()\n .describe('IDs of users assigned to review new assessments in this group (optional)'),\n});\nexport type CreateGroupInput = z.infer<typeof CreateGroupSchema>;\n\nexport function createAssessmentsCreateGroupTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_create_group',\n description:\n 'Create a new assessment group linked to a template. Assessment groups are containers for assessments. The response includes a `groupUrl` field with the canonical admin-dashboard link to the group — surface that to the user verbatim.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new assessment group',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateGroupSchema,\n handler: async ({ title, template_id, description, reviewer_ids }) => {\n const result = await graphql.createAssessmentGroup({\n title,\n assessmentFormTemplateId: template_id,\n description,\n reviewerIds: reviewer_ids,\n });\n\n const groupUrl = buildAssessmentGroupUrl(dashboardUrl, result.id);\n\n return createToolResult(true, {\n assessmentGroup: { ...result, groupUrl },\n groupUrl,\n message: `Assessment group \"${title}\" created successfully. View it at ${groupUrl}`,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type AssessmentTemplateCreateInput,\n type AssessmentSectionInput,\n} from '@transcend-io/mcp-server-base';\nimport { AssessmentFormTemplateStatus } from '@transcend-io/privacy-types';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const CreateTemplateSchema = z.object({\n title: z.string().describe('Title of the assessment form template'),\n description: z.string().optional().describe('Description of the template'),\n status: z\n .nativeEnum(AssessmentFormTemplateStatus)\n .optional()\n .describe('Template status: DRAFT or PUBLISHED (default: DRAFT)'),\n sections: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe('Array of section objects with title and optional questions array'),\n});\nexport type CreateTemplateInput = z.infer<typeof CreateTemplateSchema>;\n\nexport function createAssessmentsCreateTemplateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_create_template',\n description:\n 'Create a new assessment form template with sections and questions inline. ' +\n 'This is the \"import\" side of the JSON import/export workflow. ' +\n 'You can provide the full template structure (sections with questions and answer options) in a single call. ' +\n 'Question types: LONG_ANSWER_TEXT, SHORT_ANSWER_TEXT, SINGLE_SELECT, MULTI_SELECT, FILE. ' +\n 'SubTypes: NONE, CUSTOM, USER, TEAM, DATA_SUB_CATEGORY, HAS_PERSONAL_DATA, ATTRIBUTE_KEY, SENSITIVE_CATEGORY. ' +\n 'Auto-corrections: referenceId is auto-generated as UUID if missing or not UUID format; ' +\n 'subType is auto-set to CUSTOM when allowSelectOther is true; ' +\n 'requireRiskEvaluation is ignored when no riskFrameworkId is provided.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new assessment form template',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateTemplateSchema,\n handler: async ({ title, description, status, sections }) => {\n const input: AssessmentTemplateCreateInput = {\n title,\n description,\n status: status ?? 'DRAFT',\n sections: sections as AssessmentSectionInput[] | undefined,\n };\n\n const result = await graphql.createAssessmentFormTemplate(input);\n\n return createToolResult(true, {\n template: result,\n message: `Assessment template \"${title}\" created successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const ExportTemplateSchema = z.object({\n template_id: z.string().describe('ID of the assessment form template to export'),\n});\nexport type ExportTemplateInput = z.infer<typeof ExportTemplateSchema>;\n\nexport function createAssessmentsExportTemplateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_export_template',\n description:\n 'Export a full assessment form template as JSON, including all sections, questions, answer options, ' +\n 'and configuration. This is the \"export\" side of the JSON import/export workflow. ' +\n 'The output can be used as input for assessments_create_template to recreate the template elsewhere.',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ExportTemplateSchema,\n handler: async ({ template_id }) => {\n const template = await graphql.getAssessmentFormTemplate(template_id);\n\n const exportData = {\n _exportedAt: new Date().toISOString(),\n _format: 'transcend-assessment-template-v1',\n template: {\n title: template.title,\n description: template.description,\n status: template.status,\n sections: template.sections.map((section) => ({\n title: section.title,\n questions: section.questions.map((q) => ({\n title: q.title,\n type: q.type,\n subType: q.subType,\n description: q.description,\n placeholder: q.placeholder,\n isRequired: q.isRequired,\n referenceId: q.referenceId,\n allowSelectOther: q.allowSelectOther,\n requireRiskEvaluation: q.requireRiskEvaluation,\n answerOptions: q.answerOptions.map((opt) => ({\n value: opt.value,\n })),\n })),\n })),\n },\n _raw: template,\n };\n\n return createToolResult(true, exportData);\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentLinks } from '../helpers/buildAssessmentLinks.js';\n\nexport const GetAssessmentSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to retrieve'),\n assessment_name: z\n .string()\n .optional()\n .describe(\n 'Optional human-readable name (e.g. title) for the tool call in chat; not sent to the API.',\n ),\n});\nexport type GetAssessmentInput = z.infer<typeof GetAssessmentSchema>;\n\nexport function createAssessmentsGetTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_get',\n description:\n 'Get detailed information about a specific assessment including questions and responses. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetAssessmentSchema,\n handler: async ({ assessment_id }) => {\n const result = await graphql.getAssessment(assessment_id);\n const links = buildAssessmentLinks({ dashboardUrl, assessmentFormId: result.id });\n return createToolResult(true, { ...result, ...links });\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n z,\n PaginationSchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\nimport { AssessmentFormStatus } from '@transcend-io/privacy-types';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentLinks } from '../helpers/buildAssessmentLinks.js';\n\nexport const AssessmentStatusEnum = z.nativeEnum(AssessmentFormStatus);\nexport type AssessmentStatusEnumInput = z.infer<typeof AssessmentStatusEnum>;\n\nexport const ListAssessmentsSchema = z\n .object({\n status: AssessmentStatusEnum.optional().describe('Filter by assessment status'),\n })\n .merge(PaginationSchema);\nexport type ListAssessmentsInput = z.infer<typeof ListAssessmentsSchema>;\n\nexport function createAssessmentsListTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_list',\n description:\n 'List all privacy assessments in your organization. Supports filtering by status. Each row includes a `url` field with the canonical admin-dashboard link for that assessment — surface those to the user verbatim and do not construct assessment URLs from raw IDs. Note: Cursor pagination is not supported (max 100 results).',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListAssessmentsSchema,\n handler: async ({ status, limit, cursor }) => {\n const result = await graphql.listAssessments({\n first: limit,\n after: cursor,\n filterBy: status ? { statuses: [status] } : undefined,\n });\n\n const nodesWithLinks = result.nodes.map((node) => ({\n ...node,\n ...buildAssessmentLinks({ dashboardUrl, assessmentFormId: node.id }),\n }));\n\n return createListResult(nodesWithLinks, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n PaginationSchema,\n z,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentGroupUrl } from '../helpers/buildAssessmentLinks.js';\n\nexport const ListGroupsSchema = PaginationSchema;\nexport type ListGroupsInput = z.infer<typeof ListGroupsSchema>;\n\nexport function createAssessmentsListGroupsTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_list_groups',\n description:\n 'List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments. Each row includes a `groupUrl` field with the canonical admin-dashboard link — surface those to the user verbatim.',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListGroupsSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listAssessmentGroups({\n first: limit,\n after: cursor,\n });\n\n const nodesWithLinks = result.nodes.map((node) => ({\n ...node,\n groupUrl: buildAssessmentGroupUrl(dashboardUrl, node.id),\n }));\n\n return createListResult(nodesWithLinks, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n PaginationSchema,\n z,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const ListTemplatesSchema = PaginationSchema;\nexport type ListTemplatesInput = z.infer<typeof ListTemplatesSchema>;\n\nexport function createAssessmentsListTemplatesTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_list_templates',\n description:\n 'List all available assessment templates. Note: Cursor pagination is not supported by the Transcend API for templates - use limit to control results (max 100).',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListTemplatesSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listAssessmentTemplates({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type Assessment,\n type AssessmentSection,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { resolveTemplateToGroupId } from './_helpers.js';\n\nexport const PrefillSchema = z.object({\n title: z.string().describe('Title for the new assessment form'),\n template_id: z\n .string()\n .optional()\n .describe(\n 'Template ID to create the form from. Will auto-resolve to the first matching assessment group.',\n ),\n assessment_group_id: z\n .string()\n .optional()\n .describe('Assessment group ID (alternative to template_id)'),\n answers: z\n .record(z.string(), z.union([z.string(), z.array(z.string())]))\n .describe(\n 'Map of answers keyed by question title or referenceId. Values should be strings for text/single-select, or arrays of strings for multi-select.',\n ),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Internal user IDs to assign the form to (optional)'),\n assignee_emails: z\n .array(z.string())\n .optional()\n .describe('External email addresses to assign the form to (optional)'),\n reviewer_ids: z.array(z.string()).optional().describe('User IDs to set as reviewers (optional)'),\n submit_for_review: z\n .boolean()\n .optional()\n .describe(\n 'Whether to automatically submit the form for review after prefilling (default: false)',\n ),\n});\nexport type PrefillInput = z.infer<typeof PrefillSchema>;\n\nexport function createAssessmentsPrefillTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_prefill',\n description:\n 'Convenience tool: Create a new assessment form, AI-prefill all the answers, and assign it to a reviewer. ' +\n 'Combines: create form → get questions → answer each question → assign reviewers → optionally submit for review. ' +\n 'Provide answers as a map of {questionTitle: answer} or {referenceId: answer}. ' +\n 'For SINGLE_SELECT/MULTI_SELECT, the answer should match the exact text of the answer option(s). ' +\n 'For text questions, provide the free-text answer string. ' +\n 'For multi-select, provide an array of answer option values.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates assessment, prefills answers, assigns reviewers',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: PrefillSchema,\n handler: async ({\n answers,\n title,\n assessment_group_id,\n template_id,\n assignee_ids,\n assignee_emails,\n reviewer_ids,\n submit_for_review,\n }) => {\n let assessmentGroupId = assessment_group_id;\n if (!assessmentGroupId && template_id) {\n const resolved = await resolveTemplateToGroupId(graphql, template_id);\n if ('error' in resolved) return resolved.error;\n assessmentGroupId = resolved.groupId;\n }\n if (!assessmentGroupId) {\n return createToolResult(\n false,\n undefined,\n 'Either template_id or assessment_group_id is required.',\n );\n }\n\n const assessment = await graphql.createAssessment({\n title,\n assessmentGroupId,\n });\n const assessmentId = assessment.id;\n\n const fullForm = await graphql.getAssessment(assessmentId);\n if (!fullForm.sections || fullForm.sections.length === 0) {\n return createToolResult(true, {\n assessment: fullForm,\n message: 'Assessment created but has no sections/questions to prefill.',\n answersApplied: 0,\n });\n }\n\n const results: { question: string; status: string; answer?: string }[] = [];\n let answersApplied = 0;\n let answersSkipped = 0;\n\n for (const section of fullForm.sections as AssessmentSection[]) {\n if (!section.questions) continue;\n\n for (const question of section.questions) {\n const answerKey = Object.keys(answers).find(\n (key) =>\n key === question.referenceId ||\n key.toLowerCase() === (question.title || '').toLowerCase() ||\n key === question.id,\n );\n\n if (!answerKey) {\n results.push({\n question: question.title || question.id,\n status: 'skipped',\n });\n answersSkipped++;\n continue;\n }\n\n const answerValue = answers[answerKey];\n if (answerValue === undefined) {\n results.push({\n question: question.title || question.id,\n status: 'skipped',\n });\n answersSkipped++;\n continue;\n }\n\n try {\n const qType = (question.type || '').toUpperCase();\n\n if (qType === 'SINGLE_SELECT' || qType === 'MULTI_SELECT') {\n const answerValues = Array.isArray(answerValue) ? answerValue : [answerValue];\n const matchedIds: string[] = [];\n\n for (const val of answerValues) {\n const matchedOption = (question.answerOptions || []).find(\n (opt) => opt.value.toLowerCase() === val.toLowerCase(),\n );\n if (matchedOption) {\n matchedIds.push(matchedOption.id);\n }\n }\n\n if (matchedIds.length > 0) {\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerIds: matchedIds,\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered',\n answer: answerValues.join(', '),\n });\n } else {\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerValues: answerValues.map((v) => ({\n value: v,\n isUserCreated: true,\n })),\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered (custom value)',\n answer: answerValues.join(', '),\n });\n }\n } else {\n const textValue = Array.isArray(answerValue) ? answerValue.join('\\n') : answerValue;\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerValues: [{ value: textValue, isUserCreated: true }],\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered',\n answer: textValue.length > 100 ? textValue.substring(0, 100) + '...' : textValue,\n });\n }\n } catch (err) {\n results.push({\n question: question.title || question.id,\n status: `error: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n }\n }\n\n let assignmentResult: Record<string, unknown> | null = null;\n if (assignee_ids || assignee_emails) {\n assignmentResult = await graphql.updateAssessmentFormAssignees({\n id: assessmentId,\n assigneeIds: assignee_ids,\n externalAssigneeEmails: assignee_emails,\n });\n }\n\n if (reviewer_ids) {\n await graphql.updateAssessment({\n id: assessmentId,\n reviewerIds: reviewer_ids,\n });\n }\n\n let submitResult: Assessment | null = null;\n if (submit_for_review) {\n const sectionIds = (fullForm.sections as AssessmentSection[]).map((s) => s.id);\n if (sectionIds.length > 0) {\n submitResult = await graphql.submitAssessmentForReview({\n id: assessmentId,\n assessmentSectionIds: sectionIds,\n });\n }\n }\n\n return createToolResult(true, {\n assessmentId,\n title,\n answersApplied,\n answersSkipped,\n totalQuestions: results.length,\n results,\n assignment: assignmentResult\n ? {\n status: assignmentResult.status,\n message: 'Assignees updated',\n }\n : null,\n submittedForReview: !!submitResult,\n message:\n `Assessment \"${title}\" created and prefilled with ${answersApplied}/${results.length} answers. ` +\n (assignmentResult ? `Assigned to reviewers. ` : '') +\n (submitResult ? 'Submitted for review.' : 'Ready for manual submission.'),\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentLinks } from '../helpers/buildAssessmentLinks.js';\n\nexport const SubmitResponseSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to submit for review'),\n assessment_section_ids: z\n .array(z.string())\n .describe('Array of section IDs to submit for review. Required by the API.'),\n});\nexport type SubmitResponseInput = z.infer<typeof SubmitResponseSchema>;\n\nexport function createAssessmentsSubmitResponseTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_submit_response',\n description:\n 'Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status. The response includes a `url` field pointing at the assessment-group page where reviewers can find the submitted form — surface that to the user verbatim and do not construct assessment URLs from raw IDs.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Submits assessment for review — cannot be undone',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: SubmitResponseSchema,\n handler: async ({ assessment_id, assessment_section_ids }) => {\n const result = await graphql.submitAssessmentForReview({\n id: assessment_id,\n assessmentSectionIds: assessment_section_ids,\n });\n\n const links = buildAssessmentLinks({ dashboardUrl, assessmentFormId: result.id });\n\n return createToolResult(true, {\n assessment: { ...result, ...links },\n ...links,\n message: `Assessment submitted for review successfully. View it at ${links.url}`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { buildAssessmentLinks } from '../helpers/buildAssessmentLinks.js';\nimport { AssessmentStatusEnum } from './assessments_list.js';\n\nexport const UpdateAssessmentSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to update'),\n title: z.string().optional().describe('New title for the assessment'),\n description: z.string().optional().describe('New description'),\n reviewer_ids: z\n .array(z.string())\n .optional()\n .describe('IDs of users assigned to review this assessment'),\n due_date: z.string().optional().describe('New due date (ISO format)'),\n status: AssessmentStatusEnum.optional().describe('New status'),\n});\nexport type UpdateAssessmentInput = z.infer<typeof UpdateAssessmentSchema>;\n\nexport function createAssessmentsUpdateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n const { dashboardUrl } = clients;\n return defineTool({\n name: 'assessments_update',\n description:\n 'Update an existing assessment. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Updates the assessment',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: UpdateAssessmentSchema,\n handler: async ({ assessment_id, title, description, reviewer_ids, due_date, status }) => {\n const result = await graphql.updateAssessment({\n id: assessment_id,\n title,\n description,\n reviewerIds: reviewer_ids,\n dueDate: due_date,\n status,\n });\n\n const links = buildAssessmentLinks({ dashboardUrl, assessmentFormId: result.id });\n\n return createToolResult(true, {\n assessment: { ...result, ...links },\n ...links,\n message: `Assessment updated successfully. View it at ${links.url}`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const UpdateAssigneesSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment form to update assignees for'),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Array of internal user IDs to assign to the assessment'),\n external_assignee_emails: z\n .array(z.string())\n .optional()\n .describe('Array of external email addresses to assign to the assessment'),\n});\nexport type UpdateAssigneesInput = z.infer<typeof UpdateAssigneesSchema>;\n\nexport function createAssessmentsUpdateAssigneesTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_update_assignees',\n description:\n 'Assign internal users (by ID) or external users (by email) to an assessment form. This also transitions DRAFT assessments to SHARED status.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Assigns users to the assessment form',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: UpdateAssigneesSchema,\n handler: async ({ assessment_id, assignee_ids, external_assignee_emails }) => {\n const result = await graphql.updateAssessmentFormAssignees({\n id: assessment_id,\n assigneeIds: assignee_ids,\n externalAssigneeEmails: external_assignee_emails,\n });\n\n return createToolResult(true, {\n assessment: result,\n message: `Assessment assignees updated successfully. Status: ${result.status}`,\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-base';\n\nimport { createAssessmentsAddSectionTool } from './assessments_add_section.js';\nimport { createAssessmentsAnswerQuestionTool } from './assessments_answer_question.js';\nimport { createAssessmentsCreateTool } from './assessments_create.js';\nimport { createAssessmentsCreateGroupTool } from './assessments_create_group.js';\nimport { createAssessmentsCreateTemplateTool } from './assessments_create_template.js';\nimport { createAssessmentsExportTemplateTool } from './assessments_export_template.js';\nimport { createAssessmentsGetTool } from './assessments_get.js';\nimport { createAssessmentsListTool } from './assessments_list.js';\nimport { createAssessmentsListGroupsTool } from './assessments_list_groups.js';\nimport { createAssessmentsListTemplatesTool } from './assessments_list_templates.js';\nimport { createAssessmentsPrefillTool } from './assessments_prefill.js';\nimport { createAssessmentsSubmitResponseTool } from './assessments_submit_response.js';\nimport { createAssessmentsUpdateTool } from './assessments_update.js';\nimport { createAssessmentsUpdateAssigneesTool } from './assessments_update_assignees.js';\n\nexport function getAssessmentTools(clients: ToolClients): ToolDefinition[] {\n return [\n createAssessmentsListTool(clients),\n createAssessmentsGetTool(clients),\n createAssessmentsCreateTool(clients),\n createAssessmentsCreateGroupTool(clients),\n createAssessmentsListGroupsTool(clients),\n createAssessmentsUpdateTool(clients),\n createAssessmentsListTemplatesTool(clients),\n createAssessmentsUpdateAssigneesTool(clients),\n createAssessmentsAnswerQuestionTool(clients),\n createAssessmentsSubmitResponseTool(clients),\n createAssessmentsCreateTemplateTool(clients),\n createAssessmentsAddSectionTool(clients),\n createAssessmentsExportTemplateTool(clients),\n createAssessmentsPrefillTool(clients),\n ];\n}\n","import {\n TranscendGraphQLBase,\n type PaginatedResponse,\n type Assessment,\n type AssessmentTemplate,\n type AssessmentGroup,\n type AssessmentCreateInput,\n type AssessmentUpdateInput,\n type AssessmentSubmitForReviewInput,\n type AssessmentTemplateCreateInput,\n type AssessmentTemplateExport,\n type AssessmentQuestionInput,\n type ListOptions,\n} from '@transcend-io/mcp-server-base';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nfunction generateUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n\nfunction normalizeQuestion(q: AssessmentQuestionInput): Record<string, unknown> {\n let { referenceId, subType, allowSelectOther, requireRiskEvaluation } = q;\n\n if (!referenceId || !UUID_RE.test(referenceId)) {\n referenceId = generateUUID();\n }\n\n if (allowSelectOther && (!subType || subType === 'NONE')) {\n subType = 'CUSTOM';\n }\n\n if (requireRiskEvaluation && !q.riskFrameworkId) {\n requireRiskEvaluation = false;\n }\n\n return {\n title: q.title,\n type: q.type,\n subType: subType || 'NONE',\n placeholder: q.placeholder || '',\n description: q.description || '',\n isRequired: q.isRequired ?? false,\n referenceId,\n answerOptions: q.answerOptions || [],\n allowSelectOther: allowSelectOther ?? false,\n requireRiskEvaluation: requireRiskEvaluation ?? false,\n ...(q.riskLogic && { riskLogic: q.riskLogic }),\n ...(q.riskCategoryIds && { riskCategoryIds: q.riskCategoryIds }),\n ...(q.riskFrameworkId && { riskFrameworkId: q.riskFrameworkId }),\n ...(q.displayLogic && { displayLogic: q.displayLogic }),\n };\n}\n\nexport class AssessmentsMixin extends TranscendGraphQLBase {\n async listAssessments(\n options?: ListOptions & { filterBy?: { statuses?: string[] } },\n ): Promise<PaginatedResponse<Assessment>> {\n const query = `\n query ListAssessments($first: Int, $filterBy: AssessmentFormFiltersInput) {\n assessmentForms(first: $first, filterBy: $filterBy) {\n nodes {\n id\n title\n status\n createdAt\n assessmentGroup {\n id\n }\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentForms: {\n nodes: Array<Omit<Assessment, 'assessmentGroupId'> & { assessmentGroup?: { id: string } }>;\n totalCount: number;\n };\n }>(query, {\n first: Math.min(options?.first || 50, 100),\n filterBy: options?.filterBy?.statuses ? { statuses: options.filterBy.statuses } : undefined,\n });\n return {\n nodes: data.assessmentForms.nodes.map(({ assessmentGroup, ...rest }) => ({\n ...rest,\n assessmentGroupId: assessmentGroup?.id,\n })),\n pageInfo: {\n hasNextPage: data.assessmentForms.nodes.length < data.assessmentForms.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentForms.totalCount,\n };\n }\n\n async getAssessment(id: string): Promise<Assessment> {\n const query = `\n query GetAssessment($ids: [ID!]!) {\n assessmentForms(first: 1, filterBy: { ids: $ids }) {\n nodes {\n id\n title\n status\n dueDate\n submittedAt\n createdAt\n updatedAt\n assessmentGroup {\n id\n }\n sections {\n id\n title\n index\n status\n questions {\n id\n title\n index\n type\n subType\n description\n isRequired\n placeholder\n answerOptions {\n id\n index\n value\n }\n selectedAnswers {\n id\n index\n value\n }\n }\n }\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentForms: {\n nodes: Array<Omit<Assessment, 'assessmentGroupId'> & { assessmentGroup?: { id: string } }>;\n };\n }>(query, { ids: [id] });\n const node = data.assessmentForms.nodes[0];\n if (!node) {\n throw new Error(`Assessment with id ${id} not found`);\n }\n const { assessmentGroup, ...rest } = node;\n return { ...rest, assessmentGroupId: assessmentGroup?.id };\n }\n\n async selectAssessmentQuestionAnswers(input: {\n assessmentQuestionId: string;\n assessmentAnswerIds?: string[];\n assessmentAnswerValues?: { value: string; isUserCreated: boolean }[];\n }): Promise<Array<{ id: string; index: number; value: string }>> {\n const mutation = `\n mutation SelectAssessmentQuestionAnswers($input: SelectAssessmentQuestionAnswerInput!) {\n selectAssessmentQuestionAnswers(input: $input) {\n selectedAnswers {\n id\n index\n value\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n selectAssessmentQuestionAnswers: {\n selectedAnswers: Array<{ id: string; index: number; value: string }>;\n };\n }>(mutation, { input });\n return data.selectAssessmentQuestionAnswers.selectedAnswers;\n }\n\n async updateAssessmentFormAssignees(input: {\n id: string;\n assigneeIds?: string[];\n externalAssigneeEmails?: string[];\n }): Promise<{ id: string; title: string; status: string }> {\n const mutation = `\n mutation UpdateAssessmentFormAssignees($input: UpdateAssessmentFormAssigneesInput!) {\n updateAssessmentFormAssignees(input: $input) {\n assessmentForm {\n id\n title\n status\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n updateAssessmentFormAssignees: {\n assessmentForm: { id: string; title: string; status: string };\n };\n }>(mutation, { input });\n return data.updateAssessmentFormAssignees.assessmentForm;\n }\n\n async listAssessmentGroups(options?: ListOptions): Promise<PaginatedResponse<AssessmentGroup>> {\n const query = `\n query ListAssessmentGroups($first: Int) {\n assessmentGroups(first: $first) {\n nodes {\n id\n title\n assessmentFormTemplate {\n id\n title\n }\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentGroups: { nodes: AssessmentGroup[]; totalCount: number };\n }>(query, { first: Math.min(options?.first || 50, 100) });\n return {\n nodes: data.assessmentGroups.nodes,\n pageInfo: {\n hasNextPage: data.assessmentGroups.nodes.length < data.assessmentGroups.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentGroups.totalCount,\n };\n }\n\n async createAssessmentGroup(input: {\n title: string;\n assessmentFormTemplateId: string;\n description?: string;\n isTriggerEnabled?: boolean;\n reviewerIds?: string[];\n }): Promise<{ id: string; title: string }> {\n const mutation = `\n mutation CreateAssessmentGroup($input: CreateAssessmentGroupInput!) {\n createAssessmentGroup(input: $input) {\n assessmentGroup {\n id\n title\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n createAssessmentGroup: { assessmentGroup: { id: string; title: string } };\n }>(mutation, { input });\n return data.createAssessmentGroup.assessmentGroup;\n }\n\n async createAssessment(input: AssessmentCreateInput): Promise<Assessment> {\n const mutation = `\n mutation CreateAssessmentForms($input: CreateAssessmentFormsInput!) {\n createAssessmentForms(input: $input) {\n assessmentForms {\n id\n title\n status\n createdAt\n }\n }\n }\n `;\n const batchInput = {\n assessmentForms: [\n {\n title: input.title,\n assessmentGroupId: input.assessmentGroupId,\n ...(input.assigneeIds && { assigneeIds: input.assigneeIds }),\n },\n ],\n };\n const data = await this.makeRequest<{\n createAssessmentForms: { assessmentForms: Assessment[] };\n }>(mutation, { input: batchInput });\n const created = data.createAssessmentForms.assessmentForms[0];\n if (!created) throw new Error('createAssessmentForms returned an empty array');\n // The mutation response doesn't echo `assessmentGroup`, but we know the\n // ID from the input — surface it so callers can build a deep link without\n // an extra round trip.\n return { ...created, assessmentGroupId: input.assessmentGroupId };\n }\n\n async updateAssessment(input: AssessmentUpdateInput): Promise<Assessment> {\n const mutation = `\n mutation UpdateAssessmentForm($input: UpdateAssessmentFormInput!) {\n updateAssessmentForm(input: $input) {\n assessmentForm {\n id\n title\n description\n status\n dueDate\n updatedAt\n assessmentGroup {\n id\n }\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n updateAssessmentForm: {\n assessmentForm: Omit<Assessment, 'assessmentGroupId'> & {\n assessmentGroup?: { id: string };\n };\n };\n }>(mutation, { input });\n const { assessmentGroup, ...rest } = data.updateAssessmentForm.assessmentForm;\n return { ...rest, assessmentGroupId: assessmentGroup?.id };\n }\n\n async listAssessmentTemplates(\n options?: ListOptions,\n ): Promise<PaginatedResponse<AssessmentTemplate>> {\n const query = `\n query ListAssessmentTemplates($first: Int) {\n assessmentFormTemplates(first: $first) {\n nodes {\n id\n title\n description\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentFormTemplates: {\n nodes: Array<{ id: string; title: string; description: string | null }>;\n totalCount: number;\n };\n }>(query, { first: Math.min(options?.first || 50, 100) });\n const templates: AssessmentTemplate[] = data.assessmentFormTemplates.nodes.map((t) => ({\n id: t.id,\n title: t.title,\n description: t.description || undefined,\n version: '1.0.0',\n isActive: true,\n createdAt: new Date().toISOString(),\n }));\n return {\n nodes: templates,\n pageInfo: {\n hasNextPage:\n data.assessmentFormTemplates.nodes.length < data.assessmentFormTemplates.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentFormTemplates.totalCount,\n };\n }\n\n async submitAssessmentForReview(input: AssessmentSubmitForReviewInput): Promise<Assessment> {\n const mutation = `\n mutation SubmitAssessmentFormForReview($input: SubmitAssessmentFormForReviewInput!) {\n submitAssessmentFormForReview(input: $input) {\n clientMutationId\n }\n }\n `;\n await this.makeRequest<{ submitAssessmentFormForReview: { clientMutationId?: string } }>(\n mutation,\n { input },\n );\n return this.getAssessment(input.id);\n }\n\n async createAssessmentFormTemplate(\n input: AssessmentTemplateCreateInput,\n ): Promise<{ id: string; title: string; status: string }> {\n const mutation = `\n mutation CreateAssessmentFormTemplate($input: CreateAssessmentFormTemplateInput!) {\n createAssessmentFormTemplate(input: $input) {\n assessmentFormTemplate {\n id\n title\n status\n sections {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n }\n }\n `;\n const gqlInput: Record<string, unknown> = {\n title: input.title,\n description: input.description || '',\n status: input.status || 'DRAFT',\n source: input.source || 'MANUAL',\n };\n if (input.sections) {\n gqlInput.sections = input.sections.map((s) => ({\n title: s.title,\n questions: s.questions?.map(normalizeQuestion) || [],\n }));\n }\n const data = await this.makeRequest<{\n createAssessmentFormTemplate: {\n assessmentFormTemplate: {\n id: string;\n title: string;\n status: string;\n sections: Array<{\n id: string;\n title: string;\n index: number;\n questions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n }>;\n };\n };\n }>(mutation, { input: gqlInput });\n return data.createAssessmentFormTemplate.assessmentFormTemplate;\n }\n\n async createAssessmentSection(input: {\n assessmentFormTemplateId: string;\n title: string;\n questions?: AssessmentQuestionInput[];\n }): Promise<{ id: string; title: string; index: number }> {\n const mutation = `\n mutation CreateAssessmentSection($input: CreateAssessmentSectionInput!) {\n createAssessmentSection(input: $input) {\n assessmentSection {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n }\n `;\n const gqlInput: Record<string, unknown> = {\n assessmentFormTemplateId: input.assessmentFormTemplateId,\n title: input.title,\n };\n if (input.questions) {\n gqlInput.questions = input.questions.map(normalizeQuestion);\n }\n const data = await this.makeRequest<{\n createAssessmentSection: {\n assessmentSection: {\n id: string;\n title: string;\n index: number;\n questions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n };\n };\n }>(mutation, { input: gqlInput });\n return data.createAssessmentSection.assessmentSection;\n }\n\n async createAssessmentQuestions(\n assessmentSectionId: string,\n questions: AssessmentQuestionInput[],\n ): Promise<\n Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>\n > {\n const mutation = `\n mutation CreateAssessmentQuestions($input: [CreateAssessmentQuestionInput!]!) {\n createAssessmentQuestions(input: $input) {\n assessmentQuestions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n `;\n const input = questions.map((q) => ({\n title: q.title,\n type: q.type,\n subType: q.subType || 'NONE',\n placeholder: q.placeholder || '',\n description: q.description || '',\n isRequired: q.isRequired ?? false,\n referenceId: q.referenceId,\n assessmentSectionId,\n answerOptions: q.answerOptions || [],\n allowSelectOther: q.allowSelectOther ?? false,\n requireRiskEvaluation: q.requireRiskEvaluation ?? false,\n }));\n const data = await this.makeRequest<{\n createAssessmentQuestions: {\n assessmentQuestions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n };\n }>(mutation, { input });\n return data.createAssessmentQuestions.assessmentQuestions;\n }\n\n async getAssessmentFormTemplate(templateId: string): Promise<AssessmentTemplateExport> {\n const query = `\n query GetAssessmentFormTemplate($ids: [ID!]) {\n assessmentFormTemplates(first: 1, filterBy: { ids: $ids }) {\n nodes {\n id\n title\n description\n status\n source\n createdAt\n updatedAt\n sections {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n description\n placeholder\n isRequired\n referenceId\n allowSelectOther\n requireRiskEvaluation\n answerOptions {\n id\n index\n value\n }\n }\n }\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentFormTemplates: { nodes: AssessmentTemplateExport[] };\n }>(query, { ids: [templateId] });\n const node = data.assessmentFormTemplates.nodes[0];\n if (!node) {\n throw new Error(`Assessment template with id ${templateId} not found`);\n }\n return node;\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -74,6 +74,34 @@ declare class AssessmentsMixin extends TranscendGraphQLBase {
|
|
|
74
74
|
getAssessmentFormTemplate(templateId: string): Promise<AssessmentTemplateExport>;
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
|
+
//#region src/helpers/buildAssessmentLinks.d.ts
|
|
78
|
+
/** Inputs to {@link buildAssessmentLinks}. */
|
|
79
|
+
interface BuildAssessmentLinksInput {
|
|
80
|
+
/** Base admin-dashboard URL (e.g. `https://app.transcend.io`) */
|
|
81
|
+
dashboardUrl: string;
|
|
82
|
+
/** The assessment form ID */
|
|
83
|
+
assessmentFormId: string;
|
|
84
|
+
}
|
|
85
|
+
/** Deep link into the Transcend admin dashboard for a given assessment. */
|
|
86
|
+
interface AssessmentLinks {
|
|
87
|
+
/** Read-only response page for the assessment. */
|
|
88
|
+
url: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build the canonical admin-dashboard deep link for an assessment.
|
|
92
|
+
*
|
|
93
|
+
* Always points at `/assessments/forms/:id/response`, mirroring the
|
|
94
|
+
* dashboard's own "View Responses" row action. The fillable
|
|
95
|
+
* `/assessments/forms/:id/view` route is intentionally not emitted —
|
|
96
|
+
* it only resolves for the form's assignee, which the MCP can't verify.
|
|
97
|
+
*/
|
|
98
|
+
declare function buildAssessmentLinks({
|
|
99
|
+
dashboardUrl,
|
|
100
|
+
assessmentFormId
|
|
101
|
+
}: BuildAssessmentLinksInput): AssessmentLinks;
|
|
102
|
+
/** Build a link to the assessment-group page (for group-level tools). */
|
|
103
|
+
declare function buildAssessmentGroupUrl(dashboardUrl: string, assessmentGroupId: string): string;
|
|
104
|
+
//#endregion
|
|
77
105
|
//#region src/tools/assessments_add_section.d.ts
|
|
78
106
|
declare const AddSectionSchema: z.ZodObject<{
|
|
79
107
|
template_id: z.ZodString;
|
|
@@ -201,5 +229,5 @@ declare const UpdateAssigneesSchema: z.ZodObject<{
|
|
|
201
229
|
}, z.core.$strip>;
|
|
202
230
|
type UpdateAssigneesInput = z.infer<typeof UpdateAssigneesSchema>;
|
|
203
231
|
//#endregion
|
|
204
|
-
export { type AddSectionInput, AddSectionSchema, type AnswerQuestionInput, AnswerQuestionSchema, type AnswerQuestionValueInput, AnswerQuestionValueSchema, AssessmentStatusEnum, type AssessmentStatusEnumInput, AssessmentsMixin, type CreateAssessmentInput, CreateAssessmentSchema, type CreateGroupInput, CreateGroupSchema, type CreateTemplateInput, CreateTemplateSchema, type ExportTemplateInput, ExportTemplateSchema, type GetAssessmentInput, GetAssessmentSchema, type ListAssessmentsInput, ListAssessmentsSchema, type ListGroupsInput, ListGroupsSchema, type ListTemplatesInput, ListTemplatesSchema, type PrefillInput, PrefillSchema, type SubmitResponseInput, SubmitResponseSchema, type UpdateAssessmentInput, UpdateAssessmentSchema, type UpdateAssigneesInput, UpdateAssigneesSchema, getAssessmentTools };
|
|
232
|
+
export { type AddSectionInput, AddSectionSchema, type AnswerQuestionInput, AnswerQuestionSchema, type AnswerQuestionValueInput, AnswerQuestionValueSchema, type AssessmentLinks, AssessmentStatusEnum, type AssessmentStatusEnumInput, AssessmentsMixin, type BuildAssessmentLinksInput, type CreateAssessmentInput, CreateAssessmentSchema, type CreateGroupInput, CreateGroupSchema, type CreateTemplateInput, CreateTemplateSchema, type ExportTemplateInput, ExportTemplateSchema, type GetAssessmentInput, GetAssessmentSchema, type ListAssessmentsInput, ListAssessmentsSchema, type ListGroupsInput, ListGroupsSchema, type ListTemplatesInput, ListTemplatesSchema, type PrefillInput, PrefillSchema, type SubmitResponseInput, SubmitResponseSchema, type UpdateAssessmentInput, UpdateAssessmentSchema, type UpdateAssigneesInput, UpdateAssigneesSchema, buildAssessmentGroupUrl, buildAssessmentLinks, getAssessmentTools };
|
|
205
233
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/graphql.ts","../src/tools/assessments_add_section.ts","../src/tools/assessments_answer_question.ts","../src/tools/assessments_create.ts","../src/tools/assessments_create_group.ts","../src/tools/assessments_create_template.ts","../src/tools/assessments_export_template.ts","../src/tools/assessments_get.ts","../src/tools/assessments_list.ts","../src/tools/assessments_list_groups.ts","../src/tools/assessments_list_templates.ts","../src/tools/assessments_prefill.ts","../src/tools/assessments_submit_response.ts","../src/tools/assessments_update.ts","../src/tools/assessments_update_assignees.ts"],"mappings":";;;;;iBAiBgB,kBAAA,CAAmB,OAAA,EAAS,WAAA,GAAc,cAAA;;;cCwC7C,gBAAA,SAAyB,oBAAA;EAC9B,eAAA,CACJ,OAAA,GAAU,WAAA;IAAgB,QAAA;MAAa,QAAA;IAAA;EAAA,IACtC,OAAA,CAAQ,iBAAA,CAAkB,UAAA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/graphql.ts","../src/helpers/buildAssessmentLinks.ts","../src/tools/assessments_add_section.ts","../src/tools/assessments_answer_question.ts","../src/tools/assessments_create.ts","../src/tools/assessments_create_group.ts","../src/tools/assessments_create_template.ts","../src/tools/assessments_export_template.ts","../src/tools/assessments_get.ts","../src/tools/assessments_list.ts","../src/tools/assessments_list_groups.ts","../src/tools/assessments_list_templates.ts","../src/tools/assessments_prefill.ts","../src/tools/assessments_submit_response.ts","../src/tools/assessments_update.ts","../src/tools/assessments_update_assignees.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { AddSectionSchema, AnswerQuestionSchema, AnswerQuestionValueSchema, AssessmentStatusEnum, AssessmentsMixin, CreateAssessmentSchema, CreateGroupSchema, CreateTemplateSchema, ExportTemplateSchema, GetAssessmentSchema, ListAssessmentsSchema, ListGroupsSchema, ListTemplatesSchema, PrefillSchema, SubmitResponseSchema, UpdateAssessmentSchema, UpdateAssigneesSchema, getAssessmentTools };
|
|
1
|
+
import { _ as buildAssessmentLinks, a as SubmitResponseSchema, b as AddSectionSchema, c as ListGroupsSchema, d as GetAssessmentSchema, f as ExportTemplateSchema, g as buildAssessmentGroupUrl, h as CreateAssessmentSchema, i as UpdateAssessmentSchema, l as AssessmentStatusEnum, m as CreateGroupSchema, n as getAssessmentTools, o as PrefillSchema, p as CreateTemplateSchema, r as UpdateAssigneesSchema, s as ListTemplatesSchema, t as AssessmentsMixin, u as ListAssessmentsSchema, v as AnswerQuestionSchema, y as AnswerQuestionValueSchema } from "./graphql-DMh8AG9n.mjs";
|
|
2
|
+
export { AddSectionSchema, AnswerQuestionSchema, AnswerQuestionValueSchema, AssessmentStatusEnum, AssessmentsMixin, CreateAssessmentSchema, CreateGroupSchema, CreateTemplateSchema, ExportTemplateSchema, GetAssessmentSchema, ListAssessmentsSchema, ListGroupsSchema, ListTemplatesSchema, PrefillSchema, SubmitResponseSchema, UpdateAssessmentSchema, UpdateAssigneesSchema, buildAssessmentGroupUrl, buildAssessmentLinks, getAssessmentTools };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transcend-io/mcp-server-assessment",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"description": "Transcend MCP Server — Assessments tools.",
|
|
5
5
|
"homepage": "https://github.com/transcend-io/tools/tree/main/packages/mcp/mcp-server-assessment",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
34
|
"zod": "^4.3.6",
|
|
35
|
-
"@transcend-io/mcp-server-base": "0.4.
|
|
36
|
-
"@transcend-io/privacy-types": "5.
|
|
35
|
+
"@transcend-io/mcp-server-base": "0.4.5",
|
|
36
|
+
"@transcend-io/privacy-types": "5.2.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
40
40
|
"@types/node": "^22.19.15",
|
|
41
41
|
"publint": "^0.3.18",
|
|
42
42
|
"tsdown": "^0.21.2",
|
|
43
|
-
"typescript": "^
|
|
43
|
+
"typescript": "^6.0.0",
|
|
44
44
|
"vitest": "^4.0.18"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-7PovZAly.mjs","names":[],"sources":["../src/tools/assessments_add_section.ts","../src/tools/assessments_answer_question.ts","../src/tools/_helpers.ts","../src/tools/assessments_create.ts","../src/tools/assessments_create_group.ts","../src/tools/assessments_create_template.ts","../src/tools/assessments_export_template.ts","../src/tools/assessments_get.ts","../src/tools/assessments_list.ts","../src/tools/assessments_list_groups.ts","../src/tools/assessments_list_templates.ts","../src/tools/assessments_prefill.ts","../src/tools/assessments_submit_response.ts","../src/tools/assessments_update.ts","../src/tools/assessments_update_assignees.ts","../src/tools/index.ts","../src/graphql.ts"],"sourcesContent":["import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type AssessmentSectionInput,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const AddSectionSchema = z.object({\n template_id: z.string().describe('ID of the assessment form template to add the section to'),\n title: z.string().describe('Title of the new section'),\n questions: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe(\n 'Array of question objects: [{title, type, subType?, description?, placeholder?, isRequired?, referenceId?, answerOptions?: [{value}], allowSelectOther?, requireRiskEvaluation?}]',\n ),\n});\nexport type AddSectionInput = z.infer<typeof AddSectionSchema>;\n\nexport function createAssessmentsAddSectionTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_add_section',\n description:\n 'Add a new section (with optional inline questions) to an existing assessment form template. ' +\n 'Useful for building templates incrementally or adding sections to imported templates. ' +\n 'Same auto-corrections as assessments_create_template apply to questions.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Adds a section to the assessment template',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: AddSectionSchema,\n handler: async ({ template_id, title, questions }) => {\n const result = await graphql.createAssessmentSection({\n assessmentFormTemplateId: template_id,\n title,\n questions: questions as AssessmentSectionInput['questions'],\n });\n\n return createToolResult(true, {\n section: result,\n message: `Section \"${title}\" added to template successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const AnswerQuestionValueSchema = z.object({\n value: z.string(),\n isUserCreated: z.boolean(),\n});\nexport type AnswerQuestionValueInput = z.infer<typeof AnswerQuestionValueSchema>;\n\nexport const AnswerQuestionSchema = z.object({\n assessment_question_id: z.string().describe('ID of the assessment question to answer'),\n assessment_answer_ids: z\n .array(z.string())\n .optional()\n .describe(\n 'IDs of existing answer options to select (for SINGLE_SELECT/MULTI_SELECT questions)',\n ),\n assessment_answer_values: z\n .array(AnswerQuestionValueSchema)\n .optional()\n .describe(\n 'Free-text answer values to create and select (for text questions). Each item: {value: string, isUserCreated: boolean}',\n ),\n});\nexport type AnswerQuestionInput = z.infer<typeof AnswerQuestionSchema>;\n\nexport function createAssessmentsAnswerQuestionTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_answer_question',\n description:\n 'Answer an assessment question by selecting existing answer options or providing free-text values. For SINGLE_SELECT/MULTI_SELECT questions, provide assessmentAnswerIds from the answerOptions. For SHORT_ANSWER_TEXT/LONG_ANSWER_TEXT, provide assessmentAnswerValues with {value, isUserCreated: true}.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Records answer to the assessment question',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: AnswerQuestionSchema,\n handler: async ({\n assessment_question_id,\n assessment_answer_ids,\n assessment_answer_values,\n }) => {\n const input: {\n assessmentQuestionId: string;\n assessmentAnswerIds?: string[];\n assessmentAnswerValues?: { value: string; isUserCreated: boolean }[];\n } = {\n assessmentQuestionId: assessment_question_id,\n };\n\n if (assessment_answer_ids) {\n input.assessmentAnswerIds = assessment_answer_ids;\n }\n if (assessment_answer_values) {\n input.assessmentAnswerValues = assessment_answer_values;\n }\n\n const result = await graphql.selectAssessmentQuestionAnswers(input);\n\n return createToolResult(true, {\n selectedAnswers: result,\n message: 'Assessment question answered successfully',\n });\n },\n });\n}\n","import { createToolResult } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\n/**\n * Resolves a template_id to an assessment group ID by searching through all groups.\n * Returns either the group ID or an error result.\n */\nexport async function resolveTemplateToGroupId(\n graphql: AssessmentsMixin,\n templateId: string,\n): Promise<{ groupId: string } | { error: ReturnType<typeof createToolResult> }> {\n const groups = await graphql.listAssessmentGroups({ first: 100 });\n const matchingGroups = groups.nodes.filter((g) => g.assessmentFormTemplate?.id === templateId);\n\n if (matchingGroups.length === 0) {\n return {\n error: createToolResult(\n false,\n undefined,\n `No assessment group found for template_id \"${templateId}\". Use assessments_list_groups to see available groups.`,\n ),\n };\n }\n\n if (matchingGroups.length > 1) {\n const ids = matchingGroups.map((g) => g.id).join(', ');\n return {\n error: createToolResult(\n false,\n undefined,\n `Multiple assessment groups found for template_id \"${templateId}\" (group IDs: ${ids}). ` +\n `Please specify assessment_group_id explicitly. Use assessments_list_groups to find available groups.`,\n ),\n };\n }\n\n return { groupId: matchingGroups[0]!.id };\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { resolveTemplateToGroupId } from './_helpers.js';\n\nexport const CreateAssessmentSchema = z.object({\n title: z.string().describe('Title of the assessment'),\n assessment_group_id: z\n .string()\n .optional()\n .describe(\n 'ID of the assessment group to create the assessment in (preferred). Use assessments_list_groups to find available groups.',\n ),\n template_id: z\n .string()\n .optional()\n .describe(\n 'ID of the assessment template. If assessment_group_id is not provided, the first group using this template will be used.',\n ),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Array of user IDs to assign the assessment to'),\n});\nexport type CreateAssessmentInput = z.infer<typeof CreateAssessmentSchema>;\n\nexport function createAssessmentsCreateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_create',\n description:\n 'Create a new privacy assessment within an assessment group. Assessment groups are linked to templates. You can provide either an assessment_group_id directly, or a template_id to auto-resolve the first matching group. Use assessments_list_groups to find available groups.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new privacy assessment',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateAssessmentSchema,\n handler: async ({ title, assessment_group_id, template_id, assignee_ids }) => {\n let assessmentGroupId = assessment_group_id;\n\n if (!assessmentGroupId && template_id) {\n const resolved = await resolveTemplateToGroupId(graphql, template_id);\n if ('error' in resolved) return resolved.error;\n assessmentGroupId = resolved.groupId;\n }\n\n if (!assessmentGroupId) {\n return createToolResult(\n false,\n undefined,\n 'Either assessment_group_id or template_id must be provided. Use assessments_list_groups to find available groups.',\n );\n }\n\n const result = await graphql.createAssessment({\n title,\n assessmentGroupId,\n assigneeIds: assignee_ids,\n });\n\n return createToolResult(true, {\n assessment: result,\n message: `Assessment \"${title}\" created successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const CreateGroupSchema = z.object({\n title: z.string().describe('Title of the assessment group'),\n template_id: z.string().describe('ID of the assessment template to link this group to'),\n description: z.string().optional().describe('Description of the assessment group (optional)'),\n reviewer_ids: z\n .array(z.string())\n .optional()\n .describe('IDs of users assigned to review new assessments in this group (optional)'),\n});\nexport type CreateGroupInput = z.infer<typeof CreateGroupSchema>;\n\nexport function createAssessmentsCreateGroupTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_create_group',\n description:\n 'Create a new assessment group linked to a template. Assessment groups are containers for assessments.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new assessment group',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateGroupSchema,\n handler: async ({ title, template_id, description, reviewer_ids }) => {\n const result = await graphql.createAssessmentGroup({\n title,\n assessmentFormTemplateId: template_id,\n description,\n reviewerIds: reviewer_ids,\n });\n\n return createToolResult(true, {\n assessmentGroup: result,\n message: `Assessment group \"${title}\" created successfully`,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type AssessmentTemplateCreateInput,\n type AssessmentSectionInput,\n} from '@transcend-io/mcp-server-base';\nimport { AssessmentFormTemplateStatus } from '@transcend-io/privacy-types';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const CreateTemplateSchema = z.object({\n title: z.string().describe('Title of the assessment form template'),\n description: z.string().optional().describe('Description of the template'),\n status: z\n .nativeEnum(AssessmentFormTemplateStatus)\n .optional()\n .describe('Template status: DRAFT or PUBLISHED (default: DRAFT)'),\n sections: z\n .array(z.record(z.string(), z.unknown()))\n .optional()\n .describe('Array of section objects with title and optional questions array'),\n});\nexport type CreateTemplateInput = z.infer<typeof CreateTemplateSchema>;\n\nexport function createAssessmentsCreateTemplateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_create_template',\n description:\n 'Create a new assessment form template with sections and questions inline. ' +\n 'This is the \"import\" side of the JSON import/export workflow. ' +\n 'You can provide the full template structure (sections with questions and answer options) in a single call. ' +\n 'Question types: LONG_ANSWER_TEXT, SHORT_ANSWER_TEXT, SINGLE_SELECT, MULTI_SELECT, FILE. ' +\n 'SubTypes: NONE, CUSTOM, USER, TEAM, DATA_SUB_CATEGORY, HAS_PERSONAL_DATA, ATTRIBUTE_KEY, SENSITIVE_CATEGORY. ' +\n 'Auto-corrections: referenceId is auto-generated as UUID if missing or not UUID format; ' +\n 'subType is auto-set to CUSTOM when allowSelectOther is true; ' +\n 'requireRiskEvaluation is ignored when no riskFrameworkId is provided.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates a new assessment form template',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: CreateTemplateSchema,\n handler: async ({ title, description, status, sections }) => {\n const input: AssessmentTemplateCreateInput = {\n title,\n description,\n status: status ?? 'DRAFT',\n sections: sections as AssessmentSectionInput[] | undefined,\n };\n\n const result = await graphql.createAssessmentFormTemplate(input);\n\n return createToolResult(true, {\n template: result,\n message: `Assessment template \"${title}\" created successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const ExportTemplateSchema = z.object({\n template_id: z.string().describe('ID of the assessment form template to export'),\n});\nexport type ExportTemplateInput = z.infer<typeof ExportTemplateSchema>;\n\nexport function createAssessmentsExportTemplateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_export_template',\n description:\n 'Export a full assessment form template as JSON, including all sections, questions, answer options, ' +\n 'and configuration. This is the \"export\" side of the JSON import/export workflow. ' +\n 'The output can be used as input for assessments_create_template to recreate the template elsewhere.',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ExportTemplateSchema,\n handler: async ({ template_id }) => {\n const template = await graphql.getAssessmentFormTemplate(template_id);\n\n const exportData = {\n _exportedAt: new Date().toISOString(),\n _format: 'transcend-assessment-template-v1',\n template: {\n title: template.title,\n description: template.description,\n status: template.status,\n sections: template.sections.map((section) => ({\n title: section.title,\n questions: section.questions.map((q) => ({\n title: q.title,\n type: q.type,\n subType: q.subType,\n description: q.description,\n placeholder: q.placeholder,\n isRequired: q.isRequired,\n referenceId: q.referenceId,\n allowSelectOther: q.allowSelectOther,\n requireRiskEvaluation: q.requireRiskEvaluation,\n answerOptions: q.answerOptions.map((opt) => ({\n value: opt.value,\n })),\n })),\n })),\n },\n _raw: template,\n };\n\n return createToolResult(true, exportData);\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const GetAssessmentSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to retrieve'),\n assessment_name: z\n .string()\n .optional()\n .describe(\n 'Optional human-readable name (e.g. title) for the tool call in chat; not sent to the API.',\n ),\n});\nexport type GetAssessmentInput = z.infer<typeof GetAssessmentSchema>;\n\nexport function createAssessmentsGetTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_get',\n description:\n 'Get detailed information about a specific assessment including questions and responses',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetAssessmentSchema,\n handler: async ({ assessment_id }) => {\n const result = await graphql.getAssessment(assessment_id);\n return createToolResult(true, result);\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n z,\n PaginationSchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\nimport { AssessmentFormStatus } from '@transcend-io/privacy-types';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const AssessmentStatusEnum = z.nativeEnum(AssessmentFormStatus);\nexport type AssessmentStatusEnumInput = z.infer<typeof AssessmentStatusEnum>;\n\nexport const ListAssessmentsSchema = z\n .object({\n status: AssessmentStatusEnum.optional().describe('Filter by assessment status'),\n })\n .merge(PaginationSchema);\nexport type ListAssessmentsInput = z.infer<typeof ListAssessmentsSchema>;\n\nexport function createAssessmentsListTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_list',\n description:\n 'List all privacy assessments in your organization. Supports filtering by status. Note: Cursor pagination is not supported (max 100 results).',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListAssessmentsSchema,\n handler: async ({ status, limit, cursor }) => {\n const result = await graphql.listAssessments({\n first: limit,\n after: cursor,\n filterBy: status ? { statuses: [status] } : undefined,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n PaginationSchema,\n z,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const ListGroupsSchema = PaginationSchema;\nexport type ListGroupsInput = z.infer<typeof ListGroupsSchema>;\n\nexport function createAssessmentsListGroupsTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_list_groups',\n description:\n 'List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments.',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListGroupsSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listAssessmentGroups({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createListResult,\n defineTool,\n PaginationSchema,\n z,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const ListTemplatesSchema = PaginationSchema;\nexport type ListTemplatesInput = z.infer<typeof ListTemplatesSchema>;\n\nexport function createAssessmentsListTemplatesTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_list_templates',\n description:\n 'List all available assessment templates. Note: Cursor pagination is not supported by the Transcend API for templates - use limit to control results (max 100).',\n category: 'Assessments',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListTemplatesSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listAssessmentTemplates({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n z,\n type ToolClients,\n type Assessment,\n type AssessmentSection,\n} from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { resolveTemplateToGroupId } from './_helpers.js';\n\nexport const PrefillSchema = z.object({\n title: z.string().describe('Title for the new assessment form'),\n template_id: z\n .string()\n .optional()\n .describe(\n 'Template ID to create the form from. Will auto-resolve to the first matching assessment group.',\n ),\n assessment_group_id: z\n .string()\n .optional()\n .describe('Assessment group ID (alternative to template_id)'),\n answers: z\n .record(z.string(), z.union([z.string(), z.array(z.string())]))\n .describe(\n 'Map of answers keyed by question title or referenceId. Values should be strings for text/single-select, or arrays of strings for multi-select.',\n ),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Internal user IDs to assign the form to (optional)'),\n assignee_emails: z\n .array(z.string())\n .optional()\n .describe('External email addresses to assign the form to (optional)'),\n reviewer_ids: z.array(z.string()).optional().describe('User IDs to set as reviewers (optional)'),\n submit_for_review: z\n .boolean()\n .optional()\n .describe(\n 'Whether to automatically submit the form for review after prefilling (default: false)',\n ),\n});\nexport type PrefillInput = z.infer<typeof PrefillSchema>;\n\nexport function createAssessmentsPrefillTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_prefill',\n description:\n 'Convenience tool: Create a new assessment form, AI-prefill all the answers, and assign it to a reviewer. ' +\n 'Combines: create form → get questions → answer each question → assign reviewers → optionally submit for review. ' +\n 'Provide answers as a map of {questionTitle: answer} or {referenceId: answer}. ' +\n 'For SINGLE_SELECT/MULTI_SELECT, the answer should match the exact text of the answer option(s). ' +\n 'For text questions, provide the free-text answer string. ' +\n 'For multi-select, provide an array of answer option values.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Creates assessment, prefills answers, assigns reviewers',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n zodSchema: PrefillSchema,\n handler: async ({\n answers,\n title,\n assessment_group_id,\n template_id,\n assignee_ids,\n assignee_emails,\n reviewer_ids,\n submit_for_review,\n }) => {\n let assessmentGroupId = assessment_group_id;\n if (!assessmentGroupId && template_id) {\n const resolved = await resolveTemplateToGroupId(graphql, template_id);\n if ('error' in resolved) return resolved.error;\n assessmentGroupId = resolved.groupId;\n }\n if (!assessmentGroupId) {\n return createToolResult(\n false,\n undefined,\n 'Either template_id or assessment_group_id is required.',\n );\n }\n\n const assessment = await graphql.createAssessment({\n title,\n assessmentGroupId,\n });\n const assessmentId = assessment.id;\n\n const fullForm = await graphql.getAssessment(assessmentId);\n if (!fullForm.sections || fullForm.sections.length === 0) {\n return createToolResult(true, {\n assessment: fullForm,\n message: 'Assessment created but has no sections/questions to prefill.',\n answersApplied: 0,\n });\n }\n\n const results: { question: string; status: string; answer?: string }[] = [];\n let answersApplied = 0;\n let answersSkipped = 0;\n\n for (const section of fullForm.sections as AssessmentSection[]) {\n if (!section.questions) continue;\n\n for (const question of section.questions) {\n const answerKey = Object.keys(answers).find(\n (key) =>\n key === question.referenceId ||\n key.toLowerCase() === (question.title || '').toLowerCase() ||\n key === question.id,\n );\n\n if (!answerKey) {\n results.push({\n question: question.title || question.id,\n status: 'skipped',\n });\n answersSkipped++;\n continue;\n }\n\n const answerValue = answers[answerKey];\n if (answerValue === undefined) {\n results.push({\n question: question.title || question.id,\n status: 'skipped',\n });\n answersSkipped++;\n continue;\n }\n\n try {\n const qType = (question.type || '').toUpperCase();\n\n if (qType === 'SINGLE_SELECT' || qType === 'MULTI_SELECT') {\n const answerValues = Array.isArray(answerValue) ? answerValue : [answerValue];\n const matchedIds: string[] = [];\n\n for (const val of answerValues) {\n const matchedOption = (question.answerOptions || []).find(\n (opt) => opt.value.toLowerCase() === val.toLowerCase(),\n );\n if (matchedOption) {\n matchedIds.push(matchedOption.id);\n }\n }\n\n if (matchedIds.length > 0) {\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerIds: matchedIds,\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered',\n answer: answerValues.join(', '),\n });\n } else {\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerValues: answerValues.map((v) => ({\n value: v,\n isUserCreated: true,\n })),\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered (custom value)',\n answer: answerValues.join(', '),\n });\n }\n } else {\n const textValue = Array.isArray(answerValue) ? answerValue.join('\\n') : answerValue;\n await graphql.selectAssessmentQuestionAnswers({\n assessmentQuestionId: question.id,\n assessmentAnswerValues: [{ value: textValue, isUserCreated: true }],\n });\n answersApplied++;\n results.push({\n question: question.title || question.id,\n status: 'answered',\n answer: textValue.length > 100 ? textValue.substring(0, 100) + '...' : textValue,\n });\n }\n } catch (err) {\n results.push({\n question: question.title || question.id,\n status: `error: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n }\n }\n\n let assignmentResult: Record<string, unknown> | null = null;\n if (assignee_ids || assignee_emails) {\n assignmentResult = await graphql.updateAssessmentFormAssignees({\n id: assessmentId,\n assigneeIds: assignee_ids,\n externalAssigneeEmails: assignee_emails,\n });\n }\n\n if (reviewer_ids) {\n await graphql.updateAssessment({\n id: assessmentId,\n reviewerIds: reviewer_ids,\n });\n }\n\n let submitResult: Assessment | null = null;\n if (submit_for_review) {\n const sectionIds = (fullForm.sections as AssessmentSection[]).map((s) => s.id);\n if (sectionIds.length > 0) {\n submitResult = await graphql.submitAssessmentForReview({\n id: assessmentId,\n assessmentSectionIds: sectionIds,\n });\n }\n }\n\n return createToolResult(true, {\n assessmentId,\n title,\n answersApplied,\n answersSkipped,\n totalQuestions: results.length,\n results,\n assignment: assignmentResult\n ? {\n status: assignmentResult.status,\n message: 'Assignees updated',\n }\n : null,\n submittedForReview: !!submitResult,\n message:\n `Assessment \"${title}\" created and prefilled with ${answersApplied}/${results.length} answers. ` +\n (assignmentResult ? `Assigned to reviewers. ` : '') +\n (submitResult ? 'Submitted for review.' : 'Ready for manual submission.'),\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const SubmitResponseSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to submit for review'),\n assessment_section_ids: z\n .array(z.string())\n .describe('Array of section IDs to submit for review. Required by the API.'),\n});\nexport type SubmitResponseInput = z.infer<typeof SubmitResponseSchema>;\n\nexport function createAssessmentsSubmitResponseTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_submit_response',\n description:\n 'Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Submits assessment for review — cannot be undone',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: SubmitResponseSchema,\n handler: async ({ assessment_id, assessment_section_ids }) => {\n const result = await graphql.submitAssessmentForReview({\n id: assessment_id,\n assessmentSectionIds: assessment_section_ids,\n });\n\n return createToolResult(true, {\n assessment: result,\n message: 'Assessment submitted for review successfully',\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\nimport { AssessmentStatusEnum } from './assessments_list.js';\n\nexport const UpdateAssessmentSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment to update'),\n title: z.string().optional().describe('New title for the assessment'),\n description: z.string().optional().describe('New description'),\n reviewer_ids: z\n .array(z.string())\n .optional()\n .describe('IDs of users assigned to review this assessment'),\n due_date: z.string().optional().describe('New due date (ISO format)'),\n status: AssessmentStatusEnum.optional().describe('New status'),\n});\nexport type UpdateAssessmentInput = z.infer<typeof UpdateAssessmentSchema>;\n\nexport function createAssessmentsUpdateTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_update',\n description: 'Update an existing assessment',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Updates the assessment',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: UpdateAssessmentSchema,\n handler: async ({ assessment_id, title, description, reviewer_ids, due_date, status }) => {\n const result = await graphql.updateAssessment({\n id: assessment_id,\n title,\n description,\n reviewerIds: reviewer_ids,\n dueDate: due_date,\n status,\n });\n\n return createToolResult(true, {\n assessment: result,\n message: 'Assessment updated successfully',\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nimport type { AssessmentsMixin } from '../graphql.js';\n\nexport const UpdateAssigneesSchema = z.object({\n assessment_id: z.string().describe('ID of the assessment form to update assignees for'),\n assignee_ids: z\n .array(z.string())\n .optional()\n .describe('Array of internal user IDs to assign to the assessment'),\n external_assignee_emails: z\n .array(z.string())\n .optional()\n .describe('Array of external email addresses to assign to the assessment'),\n});\nexport type UpdateAssigneesInput = z.infer<typeof UpdateAssigneesSchema>;\n\nexport function createAssessmentsUpdateAssigneesTool(clients: ToolClients) {\n const graphql = clients.graphql as AssessmentsMixin;\n return defineTool({\n name: 'assessments_update_assignees',\n description:\n 'Assign internal users (by ID) or external users (by email) to an assessment form. This also transitions DRAFT assessments to SHARED status.',\n category: 'Assessments',\n readOnly: false,\n confirmationHint: 'Assigns users to the assessment form',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: UpdateAssigneesSchema,\n handler: async ({ assessment_id, assignee_ids, external_assignee_emails }) => {\n const result = await graphql.updateAssessmentFormAssignees({\n id: assessment_id,\n assigneeIds: assignee_ids,\n externalAssigneeEmails: external_assignee_emails,\n });\n\n return createToolResult(true, {\n assessment: result,\n message: `Assessment assignees updated successfully. Status: ${result.status}`,\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-base';\n\nimport { createAssessmentsAddSectionTool } from './assessments_add_section.js';\nimport { createAssessmentsAnswerQuestionTool } from './assessments_answer_question.js';\nimport { createAssessmentsCreateTool } from './assessments_create.js';\nimport { createAssessmentsCreateGroupTool } from './assessments_create_group.js';\nimport { createAssessmentsCreateTemplateTool } from './assessments_create_template.js';\nimport { createAssessmentsExportTemplateTool } from './assessments_export_template.js';\nimport { createAssessmentsGetTool } from './assessments_get.js';\nimport { createAssessmentsListTool } from './assessments_list.js';\nimport { createAssessmentsListGroupsTool } from './assessments_list_groups.js';\nimport { createAssessmentsListTemplatesTool } from './assessments_list_templates.js';\nimport { createAssessmentsPrefillTool } from './assessments_prefill.js';\nimport { createAssessmentsSubmitResponseTool } from './assessments_submit_response.js';\nimport { createAssessmentsUpdateTool } from './assessments_update.js';\nimport { createAssessmentsUpdateAssigneesTool } from './assessments_update_assignees.js';\n\nexport function getAssessmentTools(clients: ToolClients): ToolDefinition[] {\n return [\n createAssessmentsListTool(clients),\n createAssessmentsGetTool(clients),\n createAssessmentsCreateTool(clients),\n createAssessmentsCreateGroupTool(clients),\n createAssessmentsListGroupsTool(clients),\n createAssessmentsUpdateTool(clients),\n createAssessmentsListTemplatesTool(clients),\n createAssessmentsUpdateAssigneesTool(clients),\n createAssessmentsAnswerQuestionTool(clients),\n createAssessmentsSubmitResponseTool(clients),\n createAssessmentsCreateTemplateTool(clients),\n createAssessmentsAddSectionTool(clients),\n createAssessmentsExportTemplateTool(clients),\n createAssessmentsPrefillTool(clients),\n ];\n}\n","import {\n TranscendGraphQLBase,\n type PaginatedResponse,\n type Assessment,\n type AssessmentTemplate,\n type AssessmentGroup,\n type AssessmentCreateInput,\n type AssessmentUpdateInput,\n type AssessmentSubmitForReviewInput,\n type AssessmentTemplateCreateInput,\n type AssessmentTemplateExport,\n type AssessmentQuestionInput,\n type ListOptions,\n} from '@transcend-io/mcp-server-base';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nfunction generateUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n\nfunction normalizeQuestion(q: AssessmentQuestionInput): Record<string, unknown> {\n let { referenceId, subType, allowSelectOther, requireRiskEvaluation } = q;\n\n if (!referenceId || !UUID_RE.test(referenceId)) {\n referenceId = generateUUID();\n }\n\n if (allowSelectOther && (!subType || subType === 'NONE')) {\n subType = 'CUSTOM';\n }\n\n if (requireRiskEvaluation && !q.riskFrameworkId) {\n requireRiskEvaluation = false;\n }\n\n return {\n title: q.title,\n type: q.type,\n subType: subType || 'NONE',\n placeholder: q.placeholder || '',\n description: q.description || '',\n isRequired: q.isRequired ?? false,\n referenceId,\n answerOptions: q.answerOptions || [],\n allowSelectOther: allowSelectOther ?? false,\n requireRiskEvaluation: requireRiskEvaluation ?? false,\n ...(q.riskLogic && { riskLogic: q.riskLogic }),\n ...(q.riskCategoryIds && { riskCategoryIds: q.riskCategoryIds }),\n ...(q.riskFrameworkId && { riskFrameworkId: q.riskFrameworkId }),\n ...(q.displayLogic && { displayLogic: q.displayLogic }),\n };\n}\n\nexport class AssessmentsMixin extends TranscendGraphQLBase {\n async listAssessments(\n options?: ListOptions & { filterBy?: { statuses?: string[] } },\n ): Promise<PaginatedResponse<Assessment>> {\n const query = `\n query ListAssessments($first: Int, $filterBy: AssessmentFormFiltersInput) {\n assessmentForms(first: $first, filterBy: $filterBy) {\n nodes {\n id\n title\n status\n createdAt\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentForms: { nodes: Assessment[]; totalCount: number };\n }>(query, {\n first: Math.min(options?.first || 50, 100),\n filterBy: options?.filterBy?.statuses ? { statuses: options.filterBy.statuses } : undefined,\n });\n return {\n nodes: data.assessmentForms.nodes,\n pageInfo: {\n hasNextPage: data.assessmentForms.nodes.length < data.assessmentForms.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentForms.totalCount,\n };\n }\n\n async getAssessment(id: string): Promise<Assessment> {\n const query = `\n query GetAssessment($ids: [ID!]!) {\n assessmentForms(first: 1, filterBy: { ids: $ids }) {\n nodes {\n id\n title\n status\n dueDate\n submittedAt\n createdAt\n updatedAt\n sections {\n id\n title\n index\n status\n questions {\n id\n title\n index\n type\n subType\n description\n isRequired\n placeholder\n answerOptions {\n id\n index\n value\n }\n selectedAnswers {\n id\n index\n value\n }\n }\n }\n }\n }\n }\n `;\n const data = await this.makeRequest<{ assessmentForms: { nodes: Assessment[] } }>(query, {\n ids: [id],\n });\n const node = data.assessmentForms.nodes[0];\n if (!node) {\n throw new Error(`Assessment with id ${id} not found`);\n }\n return node;\n }\n\n async selectAssessmentQuestionAnswers(input: {\n assessmentQuestionId: string;\n assessmentAnswerIds?: string[];\n assessmentAnswerValues?: { value: string; isUserCreated: boolean }[];\n }): Promise<Array<{ id: string; index: number; value: string }>> {\n const mutation = `\n mutation SelectAssessmentQuestionAnswers($input: SelectAssessmentQuestionAnswerInput!) {\n selectAssessmentQuestionAnswers(input: $input) {\n selectedAnswers {\n id\n index\n value\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n selectAssessmentQuestionAnswers: {\n selectedAnswers: Array<{ id: string; index: number; value: string }>;\n };\n }>(mutation, { input });\n return data.selectAssessmentQuestionAnswers.selectedAnswers;\n }\n\n async updateAssessmentFormAssignees(input: {\n id: string;\n assigneeIds?: string[];\n externalAssigneeEmails?: string[];\n }): Promise<{ id: string; title: string; status: string }> {\n const mutation = `\n mutation UpdateAssessmentFormAssignees($input: UpdateAssessmentFormAssigneesInput!) {\n updateAssessmentFormAssignees(input: $input) {\n assessmentForm {\n id\n title\n status\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n updateAssessmentFormAssignees: {\n assessmentForm: { id: string; title: string; status: string };\n };\n }>(mutation, { input });\n return data.updateAssessmentFormAssignees.assessmentForm;\n }\n\n async listAssessmentGroups(options?: ListOptions): Promise<PaginatedResponse<AssessmentGroup>> {\n const query = `\n query ListAssessmentGroups($first: Int) {\n assessmentGroups(first: $first) {\n nodes {\n id\n title\n assessmentFormTemplate {\n id\n title\n }\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentGroups: { nodes: AssessmentGroup[]; totalCount: number };\n }>(query, { first: Math.min(options?.first || 50, 100) });\n return {\n nodes: data.assessmentGroups.nodes,\n pageInfo: {\n hasNextPage: data.assessmentGroups.nodes.length < data.assessmentGroups.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentGroups.totalCount,\n };\n }\n\n async createAssessmentGroup(input: {\n title: string;\n assessmentFormTemplateId: string;\n description?: string;\n isTriggerEnabled?: boolean;\n reviewerIds?: string[];\n }): Promise<{ id: string; title: string }> {\n const mutation = `\n mutation CreateAssessmentGroup($input: CreateAssessmentGroupInput!) {\n createAssessmentGroup(input: $input) {\n assessmentGroup {\n id\n title\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n createAssessmentGroup: { assessmentGroup: { id: string; title: string } };\n }>(mutation, { input });\n return data.createAssessmentGroup.assessmentGroup;\n }\n\n async createAssessment(input: AssessmentCreateInput): Promise<Assessment> {\n const mutation = `\n mutation CreateAssessmentForms($input: CreateAssessmentFormsInput!) {\n createAssessmentForms(input: $input) {\n assessmentForms {\n id\n title\n status\n createdAt\n }\n }\n }\n `;\n const batchInput = {\n assessmentForms: [\n {\n title: input.title,\n assessmentGroupId: input.assessmentGroupId,\n ...(input.assigneeIds && { assigneeIds: input.assigneeIds }),\n },\n ],\n };\n const data = await this.makeRequest<{\n createAssessmentForms: { assessmentForms: Assessment[] };\n }>(mutation, { input: batchInput });\n const created = data.createAssessmentForms.assessmentForms[0];\n if (!created) throw new Error('createAssessmentForms returned an empty array');\n return created;\n }\n\n async updateAssessment(input: AssessmentUpdateInput): Promise<Assessment> {\n const mutation = `\n mutation UpdateAssessmentForm($input: UpdateAssessmentFormInput!) {\n updateAssessmentForm(input: $input) {\n assessmentForm {\n id\n title\n description\n status\n dueDate\n updatedAt\n }\n }\n }\n `;\n const data = await this.makeRequest<{ updateAssessmentForm: { assessmentForm: Assessment } }>(\n mutation,\n { input },\n );\n return data.updateAssessmentForm.assessmentForm;\n }\n\n async listAssessmentTemplates(\n options?: ListOptions,\n ): Promise<PaginatedResponse<AssessmentTemplate>> {\n const query = `\n query ListAssessmentTemplates($first: Int) {\n assessmentFormTemplates(first: $first) {\n nodes {\n id\n title\n description\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentFormTemplates: {\n nodes: Array<{ id: string; title: string; description: string | null }>;\n totalCount: number;\n };\n }>(query, { first: Math.min(options?.first || 50, 100) });\n const templates: AssessmentTemplate[] = data.assessmentFormTemplates.nodes.map((t) => ({\n id: t.id,\n title: t.title,\n description: t.description || undefined,\n version: '1.0.0',\n isActive: true,\n createdAt: new Date().toISOString(),\n }));\n return {\n nodes: templates,\n pageInfo: {\n hasNextPage:\n data.assessmentFormTemplates.nodes.length < data.assessmentFormTemplates.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.assessmentFormTemplates.totalCount,\n };\n }\n\n async submitAssessmentForReview(input: AssessmentSubmitForReviewInput): Promise<Assessment> {\n const mutation = `\n mutation SubmitAssessmentFormForReview($input: SubmitAssessmentFormForReviewInput!) {\n submitAssessmentFormForReview(input: $input) {\n clientMutationId\n }\n }\n `;\n await this.makeRequest<{ submitAssessmentFormForReview: { clientMutationId?: string } }>(\n mutation,\n { input },\n );\n return this.getAssessment(input.id);\n }\n\n async createAssessmentFormTemplate(\n input: AssessmentTemplateCreateInput,\n ): Promise<{ id: string; title: string; status: string }> {\n const mutation = `\n mutation CreateAssessmentFormTemplate($input: CreateAssessmentFormTemplateInput!) {\n createAssessmentFormTemplate(input: $input) {\n assessmentFormTemplate {\n id\n title\n status\n sections {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n }\n }\n `;\n const gqlInput: Record<string, unknown> = {\n title: input.title,\n description: input.description || '',\n status: input.status || 'DRAFT',\n source: input.source || 'MANUAL',\n };\n if (input.sections) {\n gqlInput.sections = input.sections.map((s) => ({\n title: s.title,\n questions: s.questions?.map(normalizeQuestion) || [],\n }));\n }\n const data = await this.makeRequest<{\n createAssessmentFormTemplate: {\n assessmentFormTemplate: {\n id: string;\n title: string;\n status: string;\n sections: Array<{\n id: string;\n title: string;\n index: number;\n questions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n }>;\n };\n };\n }>(mutation, { input: gqlInput });\n return data.createAssessmentFormTemplate.assessmentFormTemplate;\n }\n\n async createAssessmentSection(input: {\n assessmentFormTemplateId: string;\n title: string;\n questions?: AssessmentQuestionInput[];\n }): Promise<{ id: string; title: string; index: number }> {\n const mutation = `\n mutation CreateAssessmentSection($input: CreateAssessmentSectionInput!) {\n createAssessmentSection(input: $input) {\n assessmentSection {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n }\n `;\n const gqlInput: Record<string, unknown> = {\n assessmentFormTemplateId: input.assessmentFormTemplateId,\n title: input.title,\n };\n if (input.questions) {\n gqlInput.questions = input.questions.map(normalizeQuestion);\n }\n const data = await this.makeRequest<{\n createAssessmentSection: {\n assessmentSection: {\n id: string;\n title: string;\n index: number;\n questions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n };\n };\n }>(mutation, { input: gqlInput });\n return data.createAssessmentSection.assessmentSection;\n }\n\n async createAssessmentQuestions(\n assessmentSectionId: string,\n questions: AssessmentQuestionInput[],\n ): Promise<\n Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>\n > {\n const mutation = `\n mutation CreateAssessmentQuestions($input: [CreateAssessmentQuestionInput!]!) {\n createAssessmentQuestions(input: $input) {\n assessmentQuestions {\n id\n title\n index\n type\n subType\n referenceId\n }\n }\n }\n `;\n const input = questions.map((q) => ({\n title: q.title,\n type: q.type,\n subType: q.subType || 'NONE',\n placeholder: q.placeholder || '',\n description: q.description || '',\n isRequired: q.isRequired ?? false,\n referenceId: q.referenceId,\n assessmentSectionId,\n answerOptions: q.answerOptions || [],\n allowSelectOther: q.allowSelectOther ?? false,\n requireRiskEvaluation: q.requireRiskEvaluation ?? false,\n }));\n const data = await this.makeRequest<{\n createAssessmentQuestions: {\n assessmentQuestions: Array<{\n id: string;\n title: string;\n index: number;\n type: string;\n subType: string;\n referenceId: string;\n }>;\n };\n }>(mutation, { input });\n return data.createAssessmentQuestions.assessmentQuestions;\n }\n\n async getAssessmentFormTemplate(templateId: string): Promise<AssessmentTemplateExport> {\n const query = `\n query GetAssessmentFormTemplate($ids: [ID!]) {\n assessmentFormTemplates(first: 1, filterBy: { ids: $ids }) {\n nodes {\n id\n title\n description\n status\n source\n createdAt\n updatedAt\n sections {\n id\n title\n index\n questions {\n id\n title\n index\n type\n subType\n description\n placeholder\n isRequired\n referenceId\n allowSelectOther\n requireRiskEvaluation\n answerOptions {\n id\n index\n value\n }\n }\n }\n }\n }\n }\n `;\n const data = await this.makeRequest<{\n assessmentFormTemplates: { nodes: AssessmentTemplateExport[] };\n }>(query, { ids: [templateId] });\n const node = data.assessmentFormTemplates.nodes[0];\n if (!node) {\n throw new Error(`Assessment template with id ${templateId} not found`);\n }\n return node;\n }\n}\n"],"mappings":"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"}
|