teamflect-mcp-server 1.0.3

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.
Files changed (47) hide show
  1. package/.env.example +9 -0
  2. package/README.md +177 -0
  3. package/dist/constants.d.ts +9 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +9 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/index.d.ts +9 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +85 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/services/apiClient.d.ts +29 -0
  12. package/dist/services/apiClient.d.ts.map +1 -0
  13. package/dist/services/apiClient.js +92 -0
  14. package/dist/services/apiClient.js.map +1 -0
  15. package/dist/services/errorHandler.d.ts +5 -0
  16. package/dist/services/errorHandler.d.ts.map +1 -0
  17. package/dist/services/errorHandler.js +93 -0
  18. package/dist/services/errorHandler.js.map +1 -0
  19. package/dist/tools/feedbacks.d.ts +7 -0
  20. package/dist/tools/feedbacks.d.ts.map +1 -0
  21. package/dist/tools/feedbacks.js +372 -0
  22. package/dist/tools/feedbacks.js.map +1 -0
  23. package/dist/tools/goals.d.ts +7 -0
  24. package/dist/tools/goals.d.ts.map +1 -0
  25. package/dist/tools/goals.js +466 -0
  26. package/dist/tools/goals.js.map +1 -0
  27. package/dist/tools/recognitions.d.ts +7 -0
  28. package/dist/tools/recognitions.d.ts.map +1 -0
  29. package/dist/tools/recognitions.js +314 -0
  30. package/dist/tools/recognitions.js.map +1 -0
  31. package/dist/tools/reviews.d.ts +7 -0
  32. package/dist/tools/reviews.d.ts.map +1 -0
  33. package/dist/tools/reviews.js +224 -0
  34. package/dist/tools/reviews.js.map +1 -0
  35. package/dist/tools/tasks.d.ts +7 -0
  36. package/dist/tools/tasks.d.ts.map +1 -0
  37. package/dist/tools/tasks.js +262 -0
  38. package/dist/tools/tasks.js.map +1 -0
  39. package/dist/tools/users.d.ts +7 -0
  40. package/dist/tools/users.d.ts.map +1 -0
  41. package/dist/tools/users.js +417 -0
  42. package/dist/tools/users.js.map +1 -0
  43. package/dist/types.d.ts +284 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +9 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +63 -0
@@ -0,0 +1,314 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../services/errorHandler.js";
3
+ import { ResponseFormat } from "../types.js";
4
+ import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, CHARACTER_LIMIT } from "../constants.js";
5
+ /**
6
+ * Register recognition-related tools
7
+ */
8
+ export function registerRecognitionTools(server, apiClient) {
9
+ // Get Recognition Schema
10
+ const GetRecognitionInputSchema = z.object({
11
+ recognitionId: z.string().min(1).describe("The ID of the recognition to retrieve"),
12
+ response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
13
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable"),
14
+ }).strict();
15
+ server.registerTool("teamflect_get_recognition", {
16
+ title: "Get Recognition by ID",
17
+ description: `Retrieve a single recognition by its ID from Teamflect.
18
+
19
+ This tool fetches detailed information about a specific recognition including its badge, recipients, and description.
20
+
21
+ Args:
22
+ - recognitionId (string, required): The unique identifier of the recognition
23
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
24
+
25
+ Returns:
26
+ Complete recognition details including badge information and recipients.
27
+
28
+ Error Handling:
29
+ - Returns "Error: Resource not found" if recognitionId doesn't exist
30
+ - Returns "Error: Authentication failed" if API key is invalid`,
31
+ inputSchema: GetRecognitionInputSchema,
32
+ annotations: {
33
+ readOnlyHint: true,
34
+ destructiveHint: false,
35
+ idempotentHint: true,
36
+ openWorldHint: true,
37
+ },
38
+ }, async (params) => {
39
+ try {
40
+ const recognition = await apiClient.get(`/recognition/${params.recognitionId}`);
41
+ let textContent;
42
+ if (params.response_format === ResponseFormat.MARKDOWN) {
43
+ const lines = [`# Recognition`, ""];
44
+ if (recognition.badge) {
45
+ lines.push(`**Badge**: ${recognition.badge.title}`);
46
+ if (recognition.badge.description) {
47
+ lines.push(`*${recognition.badge.description}*`);
48
+ }
49
+ }
50
+ lines.push(`\n**Description**: ${recognition.description}`);
51
+ lines.push(`- **ID**: ${recognition.id}`);
52
+ lines.push(`- **Private**: ${recognition.isPrivate ? "Yes" : "No"}`);
53
+ if (recognition.createdAt) {
54
+ lines.push(`- **Created At**: ${recognition.createdAt}`);
55
+ }
56
+ if (recognition.recipients && recognition.recipients.length > 0) {
57
+ lines.push(`\n**Recipients:**`);
58
+ recognition.recipients.forEach((r) => {
59
+ lines.push(`- ${r.displayName}${r.jobTitle ? ` (${r.jobTitle})` : ""} - ${r.mail}`);
60
+ });
61
+ }
62
+ textContent = lines.join("\n");
63
+ }
64
+ else {
65
+ textContent = JSON.stringify(recognition, null, 2);
66
+ }
67
+ return {
68
+ content: [{ type: "text", text: textContent }],
69
+ structuredContent: recognition,
70
+ };
71
+ }
72
+ catch (error) {
73
+ return {
74
+ content: [{
75
+ type: "text",
76
+ text: handleApiError(error),
77
+ }],
78
+ };
79
+ }
80
+ });
81
+ // Search Recognitions Schema
82
+ const SearchRecognitionsInputSchema = z.object({
83
+ recipientEmail: z.string().email().optional().describe("Filter by recipient email address"),
84
+ badgeId: z.string().optional().describe("Filter by badge ID"),
85
+ startDate: z.string().optional().describe("Filter by start date (ISO format)"),
86
+ endDate: z.string().optional().describe("Filter by end date (ISO format)"),
87
+ isPrivate: z.boolean().optional().describe("Filter by privacy status"),
88
+ limit: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE)
89
+ .describe("Maximum number of recognitions to return"),
90
+ offset: z.number().int().min(0).default(0)
91
+ .describe("Number of recognitions to skip for pagination"),
92
+ response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
93
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable"),
94
+ }).strict();
95
+ server.registerTool("teamflect_search_recognitions", {
96
+ title: "Search Recognitions",
97
+ description: `Search for recognitions in Teamflect based on filters.
98
+
99
+ This tool searches for recognitions matching the specified criteria. You can filter by recipient, badge, date range, and privacy status. Results are paginated.
100
+
101
+ Args:
102
+ - recipientEmail (string, optional): Filter by recipient email address
103
+ - badgeId (string, optional): Filter by badge ID
104
+ - startDate (string, optional): Filter by start date in ISO format (YYYY-MM-DD)
105
+ - endDate (string, optional): Filter by end date in ISO format (YYYY-MM-DD)
106
+ - isPrivate (boolean, optional): Filter by privacy status
107
+ - limit (number, optional): Maximum results to return, between 1-300 (default: 20)
108
+ - offset (number, optional): Number of results to skip for pagination (default: 0)
109
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
110
+
111
+ Returns:
112
+ For JSON format: Structured data with schema:
113
+ {
114
+ "total": number,
115
+ "count": number,
116
+ "offset": number,
117
+ "recognitions": [
118
+ {
119
+ "id": string,
120
+ "description": string,
121
+ "createdAt": string,
122
+ "isPrivate": boolean,
123
+ "badge": {"id": string, "title": string, "description": string},
124
+ "recipients": [{"displayName": string, "jobTitle": string, "mail": string}]
125
+ }
126
+ ],
127
+ "has_more": boolean,
128
+ "next_offset": number
129
+ }
130
+
131
+ Examples:
132
+ - Use when: "Get all recognitions for john@example.com" -> params with recipientEmail="john@example.com"
133
+ - Use when: "List public recognitions this month" -> params with isPrivate=false and date filters
134
+
135
+ Error Handling:
136
+ - Returns "Error: Authentication failed" if API key is invalid
137
+ - Returns "Error: Rate limit exceeded" if too many requests`,
138
+ inputSchema: SearchRecognitionsInputSchema,
139
+ annotations: {
140
+ readOnlyHint: true,
141
+ destructiveHint: false,
142
+ idempotentHint: true,
143
+ openWorldHint: true,
144
+ },
145
+ }, async (params) => {
146
+ try {
147
+ const requestBody = {
148
+ limit: params.limit,
149
+ offset: params.offset,
150
+ };
151
+ if (params.recipientEmail)
152
+ requestBody.recipientEmail = params.recipientEmail;
153
+ if (params.badgeId)
154
+ requestBody.badgeId = params.badgeId;
155
+ if (params.startDate)
156
+ requestBody.startDate = params.startDate;
157
+ if (params.endDate)
158
+ requestBody.endDate = params.endDate;
159
+ if (params.isPrivate !== undefined)
160
+ requestBody.isPrivate = params.isPrivate;
161
+ const response = await apiClient.post("/recognition", requestBody);
162
+ const recognitions = response.recognitions || [];
163
+ const total = response.total ?? recognitions.length;
164
+ const hasMore = total > params.offset + recognitions.length;
165
+ const nextOffset = hasMore ? params.offset + recognitions.length : undefined;
166
+ const output = {
167
+ total,
168
+ count: recognitions.length,
169
+ offset: params.offset,
170
+ recognitions: recognitions.map((recognition) => ({
171
+ id: recognition.id,
172
+ description: recognition.description,
173
+ createdAt: recognition.createdAt || "",
174
+ isPrivate: recognition.isPrivate,
175
+ badge: recognition.badge || null,
176
+ recipients: recognition.recipients || [],
177
+ })),
178
+ has_more: hasMore,
179
+ ...(nextOffset !== undefined ? { next_offset: nextOffset } : {}),
180
+ };
181
+ let textContent;
182
+ if (params.response_format === ResponseFormat.MARKDOWN) {
183
+ const lines = [`# Recognitions (${total} total)`, ""];
184
+ if (recognitions.length === 0) {
185
+ lines.push("No recognitions found matching the criteria.");
186
+ }
187
+ else {
188
+ lines.push(`Showing ${recognitions.length} of ${total} recognitions\n`);
189
+ recognitions.forEach((recognition) => {
190
+ lines.push(`## ${recognition.badge?.title || "Recognition"} (${recognition.id})`);
191
+ lines.push(`- **Description**: ${recognition.description}`);
192
+ lines.push(`- **Private**: ${recognition.isPrivate ? "Yes" : "No"}`);
193
+ if (recognition.createdAt) {
194
+ lines.push(`- **Created At**: ${recognition.createdAt}`);
195
+ }
196
+ if (recognition.recipients && recognition.recipients.length > 0) {
197
+ lines.push(`\n**Recipients:**`);
198
+ recognition.recipients.forEach((r) => {
199
+ lines.push(`- ${r.displayName}${r.jobTitle ? ` (${r.jobTitle})` : ""} - ${r.mail}`);
200
+ });
201
+ }
202
+ lines.push("");
203
+ });
204
+ if (hasMore) {
205
+ lines.push(`\n*Use offset=${nextOffset} to get more results*`);
206
+ }
207
+ }
208
+ textContent = lines.join("\n");
209
+ }
210
+ else {
211
+ textContent = JSON.stringify(output, null, 2);
212
+ }
213
+ // Check character limit
214
+ if (textContent.length > CHARACTER_LIMIT) {
215
+ const truncated = output.recognitions.slice(0, Math.floor(output.recognitions.length / 2));
216
+ const truncatedOutput = { ...output, recognitions: truncated, truncated: true };
217
+ textContent = params.response_format === ResponseFormat.MARKDOWN
218
+ ? `# Recognitions (Truncated)\n\nResponse truncated from ${output.recognitions.length} to ${truncated.length} recognitions. Use filters or pagination to see more results.\n\n${JSON.stringify(truncatedOutput, null, 2)}`
219
+ : JSON.stringify(truncatedOutput, null, 2);
220
+ }
221
+ return {
222
+ content: [{ type: "text", text: textContent }],
223
+ structuredContent: output,
224
+ };
225
+ }
226
+ catch (error) {
227
+ return {
228
+ content: [{
229
+ type: "text",
230
+ text: handleApiError(error),
231
+ }],
232
+ };
233
+ }
234
+ });
235
+ // Create Recognition Schema
236
+ const CreateRecognitionInputSchema = z.object({
237
+ description: z.string().min(1).max(5000).describe("Recognition description (1-5000 characters)"),
238
+ badgeId: z.string().min(1).describe("Badge ID to assign"),
239
+ badgeTitle: z.string().min(1).optional().describe("Badge title (required by API, defaults to badgeId if not provided)"),
240
+ recipientEmails: z.array(z.string().email()).min(1).describe("Array of recipient email addresses"),
241
+ senderIdOrUPN: z.string().email().optional().describe("Sender email (optional, defaults to API key user)"),
242
+ isPrivate: z.boolean().default(false).describe("Whether the recognition is private (default: false)"),
243
+ response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
244
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable"),
245
+ }).strict();
246
+ server.registerTool("teamflect_create_recognition", {
247
+ title: "Create Recognition",
248
+ description: `Create a new recognition in Teamflect.
249
+
250
+ This tool creates a recognition (award/badge) for one or more recipients. Recognitions can be public or private.
251
+
252
+ Args:
253
+ - description (string, required): Recognition description (1-5000 characters)
254
+ - badgeId (string, required): Badge ID to assign to the recognition
255
+ - recipientEmails (array, required): Array of recipient email addresses (at least one)
256
+ - senderIdOrUPN (string, optional): Sender email address (defaults to first recipient if not provided)
257
+ - isPrivate (boolean, optional): Whether the recognition is private (default: false)
258
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
259
+
260
+ Returns:
261
+ The created recognition(s) with all details.
262
+
263
+ Error Handling:
264
+ - Returns "Error: Bad request" if required fields are missing or invalid
265
+ - Returns "Error: Permission denied" if you don't have permission to create recognitions`,
266
+ inputSchema: CreateRecognitionInputSchema,
267
+ annotations: {
268
+ readOnlyHint: false,
269
+ destructiveHint: false,
270
+ idempotentHint: false,
271
+ openWorldHint: true,
272
+ },
273
+ }, async (params) => {
274
+ try {
275
+ // API expects an array format where each element has recipientsIdsOrUPNS array and badgeTitle
276
+ const requestBody = [{
277
+ description: params.description,
278
+ badgeId: params.badgeId,
279
+ badgeTitle: params.badgeTitle || params.badgeId, // Use badgeId as fallback if badgeTitle not provided
280
+ recipientsIdsOrUPNS: params.recipientEmails,
281
+ senderIdOrUPN: params.senderIdOrUPN || params.recipientEmails[0], // Use first recipient as fallback if not provided
282
+ isPrivate: params.isPrivate,
283
+ }];
284
+ const response = await apiClient.post("/recognition/createNewRecognitions", requestBody);
285
+ const recognitions = response.recognitions || [];
286
+ let textContent;
287
+ if (params.response_format === ResponseFormat.MARKDOWN) {
288
+ if (recognitions.length === 1) {
289
+ const rec = recognitions[0];
290
+ textContent = `# Recognition Created\n\nRecognition created successfully.\n\n- **ID**: ${rec.id}\n- **Description**: ${rec.description}\n- **Badge**: ${rec.badge?.title || params.badgeId}\n- **Recipients**: ${rec.recipients?.map((r) => r.displayName).join(", ") || params.recipientEmails.join(", ")}\n- **Private**: ${rec.isPrivate ? "Yes" : "No"}`;
291
+ }
292
+ else {
293
+ textContent = `# Recognitions Created\n\n${recognitions.length} recognition(s) created successfully.\n\n${recognitions.map((rec) => `- **${rec.badge?.title || "Recognition"}** (${rec.id}): ${rec.description}`).join("\n")}`;
294
+ }
295
+ }
296
+ else {
297
+ textContent = JSON.stringify(response, null, 2);
298
+ }
299
+ return {
300
+ content: [{ type: "text", text: textContent }],
301
+ structuredContent: response,
302
+ };
303
+ }
304
+ catch (error) {
305
+ return {
306
+ content: [{
307
+ type: "text",
308
+ text: handleApiError(error),
309
+ }],
310
+ };
311
+ }
312
+ });
313
+ }
314
+ //# sourceMappingURL=recognitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recognitions.js","sourceRoot":"","sources":["../../src/tools/recognitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { TeamflectApiClient } from "../services/apiClient.js";
3
+ /**
4
+ * Register review-related tools
5
+ */
6
+ export declare function registerReviewTools(server: McpServer, apiClient: TeamflectApiClient): void;
7
+ //# sourceMappingURL=reviews.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../src/tools/reviews.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK9D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,GAAG,IAAI,CA2O1F"}
@@ -0,0 +1,224 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../services/errorHandler.js";
3
+ import { ResponseFormat } from "../types.js";
4
+ import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, CHARACTER_LIMIT } from "../constants.js";
5
+ /**
6
+ * Register review-related tools
7
+ */
8
+ export function registerReviewTools(server, apiClient) {
9
+ // Get Reviews Schema
10
+ const GetReviewsInputSchema = z.object({
11
+ revieweeEmail: z.string().email().optional().describe("Filter by reviewee email address"),
12
+ reviewerEmail: z.string().email().optional().describe("Filter by reviewer email address"),
13
+ status: z.string().optional().describe("Filter by review status"),
14
+ startDate: z.string().optional().describe("Filter by period start date (ISO format)"),
15
+ endDate: z.string().optional().describe("Filter by period end date (ISO format)"),
16
+ limit: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE)
17
+ .describe("Maximum number of reviews to return"),
18
+ offset: z.number().int().min(0).default(0)
19
+ .describe("Number of reviews to skip for pagination"),
20
+ response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
21
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable"),
22
+ }).strict();
23
+ server.registerTool("teamflect_get_reviews", {
24
+ title: "Get Reviews",
25
+ description: `Retrieve a list of reviews from Teamflect based on filters.
26
+
27
+ This tool searches for reviews matching the specified criteria. You can filter by reviewee, reviewer, status, and date ranges. Results are paginated.
28
+
29
+ Args:
30
+ - revieweeEmail (string, optional): Filter by reviewee email address
31
+ - reviewerEmail (string, optional): Filter by reviewer email address
32
+ - status (string, optional): Filter by review status (e.g., "Finalized", "In Progress")
33
+ - startDate (string, optional): Filter by period start date in ISO format (YYYY-MM-DD)
34
+ - endDate (string, optional): Filter by period end date in ISO format (YYYY-MM-DD)
35
+ - limit (number, optional): Maximum results to return, between 1-300 (default: 20)
36
+ - offset (number, optional): Number of results to skip for pagination (default: 0)
37
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
38
+
39
+ Returns:
40
+ For JSON format: Structured data with schema:
41
+ {
42
+ "total": number,
43
+ "count": number,
44
+ "offset": number,
45
+ "reviews": [
46
+ {
47
+ "reviewId": string,
48
+ "reviewee": {"displayName": string, "mail": string},
49
+ "reviewer": {"displayName": string, "mail": string},
50
+ "status": string,
51
+ "reviewTemplate": string,
52
+ "periodStartDate": string,
53
+ "periodEndDate": string,
54
+ "ratingResults": [{"title": string, "score": number}],
55
+ "note": string,
56
+ "createdAt": string
57
+ }
58
+ ],
59
+ "has_more": boolean,
60
+ "next_offset": number
61
+ }
62
+
63
+ Examples:
64
+ - Use when: "Get all reviews for john@example.com" -> params with revieweeEmail="john@example.com"
65
+ - Use when: "List finalized reviews this year" -> params with status="Finalized" and date filters
66
+
67
+ Error Handling:
68
+ - Returns "Error: Authentication failed" if API key is invalid
69
+ - Returns "Error: Rate limit exceeded" if too many requests`,
70
+ inputSchema: GetReviewsInputSchema,
71
+ annotations: {
72
+ readOnlyHint: true,
73
+ destructiveHint: false,
74
+ idempotentHint: true,
75
+ openWorldHint: true,
76
+ },
77
+ }, async (params) => {
78
+ try {
79
+ // API doesn't accept query parameters - fetch all and filter client-side
80
+ const response = await apiClient.get("/review/getReviews");
81
+ // Handle array response format
82
+ let allReviews = Array.isArray(response) ? response : [];
83
+ // Apply client-side filtering
84
+ let reviews = allReviews;
85
+ if (params.revieweeEmail) {
86
+ reviews = reviews.filter((r) => {
87
+ const revieweeEmail = r.reviewee?.mail || r.reviewee?.userPrincipalName || "";
88
+ return revieweeEmail.toLowerCase() === params.revieweeEmail.toLowerCase();
89
+ });
90
+ }
91
+ if (params.reviewerEmail) {
92
+ reviews = reviews.filter((r) => {
93
+ const reviewerEmail = r.reviewer?.userPrincipalName || r.reviewer?.mail || "";
94
+ return reviewerEmail.toLowerCase() === params.reviewerEmail.toLowerCase();
95
+ });
96
+ }
97
+ if (params.status) {
98
+ reviews = reviews.filter((r) => r.status?.toLowerCase() === params.status.toLowerCase());
99
+ }
100
+ if (params.startDate) {
101
+ const start = new Date(params.startDate);
102
+ reviews = reviews.filter((r) => {
103
+ const periodStart = r.periodStartDate ? new Date(r.periodStartDate) : null;
104
+ return periodStart && periodStart >= start;
105
+ });
106
+ }
107
+ if (params.endDate) {
108
+ const end = new Date(params.endDate);
109
+ reviews = reviews.filter((r) => {
110
+ const periodEnd = r.periodEndDate ? new Date(r.periodEndDate) : null;
111
+ return periodEnd && periodEnd <= end;
112
+ });
113
+ }
114
+ // Calculate total before pagination
115
+ const total = reviews.length;
116
+ // Apply pagination after filtering
117
+ const startIndex = params.offset;
118
+ const endIndex = startIndex + params.limit;
119
+ reviews = reviews.slice(startIndex, endIndex);
120
+ const hasMore = total > params.offset + reviews.length;
121
+ const nextOffset = hasMore ? params.offset + reviews.length : undefined;
122
+ const output = {
123
+ total,
124
+ count: reviews.length,
125
+ offset: params.offset,
126
+ reviews: reviews.map((review) => ({
127
+ reviewId: review.id || review.reviewId || "",
128
+ reviewee: review.reviewee ? {
129
+ displayName: review.reviewee.displayName || "",
130
+ mail: review.reviewee.mail || review.reviewee.userPrincipalName || ""
131
+ } : null,
132
+ reviewer: review.reviewer ? {
133
+ displayName: review.reviewer.displayName || "",
134
+ mail: review.reviewer.mail || review.reviewer.userPrincipalName || ""
135
+ } : null,
136
+ status: review.status || "",
137
+ reviewTemplate: review.reviewTemplate || "",
138
+ periodStartDate: review.periodStartDate || "",
139
+ periodEndDate: review.periodEndDate || "",
140
+ ratingResults: review.reviewRatingResults || review.ratingResults || [],
141
+ note: review.note || "",
142
+ createdAt: review.createdAt || "",
143
+ selfReviewSubmittedAt: review.selfReviewSubmittedAt || "",
144
+ isDeleted: review.isDeleted || false,
145
+ assignedNineBox: review.assignedNineBox || "",
146
+ createdBy: review.createdBy || null,
147
+ })),
148
+ has_more: hasMore,
149
+ ...(nextOffset !== undefined ? { next_offset: nextOffset } : {}),
150
+ };
151
+ let textContent;
152
+ if (params.response_format === ResponseFormat.MARKDOWN) {
153
+ const lines = [`# Reviews (${total} total)`, ""];
154
+ if (reviews.length === 0) {
155
+ lines.push("No reviews found matching the criteria.");
156
+ }
157
+ else {
158
+ lines.push(`Showing ${reviews.length} of ${total} reviews\n`);
159
+ reviews.forEach((review) => {
160
+ const reviewId = review.id || review.reviewId || "N/A";
161
+ lines.push(`## Review ${reviewId}`);
162
+ if (review.reviewee) {
163
+ const revieweeEmail = review.reviewee.mail || review.reviewee.userPrincipalName || "";
164
+ lines.push(`- **Reviewee**: ${review.reviewee.displayName || ""} (${revieweeEmail})`);
165
+ }
166
+ if (review.reviewer) {
167
+ const reviewerEmail = review.reviewer.mail || review.reviewer.userPrincipalName || "";
168
+ lines.push(`- **Reviewer**: ${review.reviewer.displayName || ""} (${reviewerEmail})`);
169
+ }
170
+ lines.push(`- **Status**: ${review.status || ""}`);
171
+ if (review.reviewTemplate) {
172
+ lines.push(`- **Template**: ${review.reviewTemplate}`);
173
+ }
174
+ if (review.periodStartDate && review.periodEndDate) {
175
+ lines.push(`- **Period**: ${review.periodStartDate} to ${review.periodEndDate}`);
176
+ }
177
+ const ratingResults = review.reviewRatingResults || review.ratingResults || [];
178
+ if (ratingResults.length > 0) {
179
+ lines.push(`\n**Ratings:**`);
180
+ ratingResults.forEach((r) => {
181
+ lines.push(`- ${r.title}: ${r.score || 0}${r.outOf ? `/${r.outOf}` : ""}`);
182
+ });
183
+ }
184
+ if (review.note) {
185
+ lines.push(`\n**Note**: ${review.note}`);
186
+ }
187
+ if (review.createdAt) {
188
+ lines.push(`- **Created At**: ${review.createdAt}`);
189
+ }
190
+ lines.push("");
191
+ });
192
+ if (hasMore) {
193
+ lines.push(`\n*Use offset=${nextOffset} to get more results*`);
194
+ }
195
+ }
196
+ textContent = lines.join("\n");
197
+ }
198
+ else {
199
+ textContent = JSON.stringify(output, null, 2);
200
+ }
201
+ // Check character limit
202
+ if (textContent.length > CHARACTER_LIMIT) {
203
+ const truncated = output.reviews.slice(0, Math.floor(output.reviews.length / 2));
204
+ const truncatedOutput = { ...output, reviews: truncated, truncated: true };
205
+ textContent = params.response_format === ResponseFormat.MARKDOWN
206
+ ? `# Reviews (Truncated)\n\nResponse truncated from ${output.reviews.length} to ${truncated.length} reviews. Use filters or pagination to see more results.\n\n${JSON.stringify(truncatedOutput, null, 2)}`
207
+ : JSON.stringify(truncatedOutput, null, 2);
208
+ }
209
+ return {
210
+ content: [{ type: "text", text: textContent }],
211
+ structuredContent: output,
212
+ };
213
+ }
214
+ catch (error) {
215
+ return {
216
+ content: [{
217
+ type: "text",
218
+ text: handleApiError(error),
219
+ }],
220
+ };
221
+ }
222
+ });
223
+ }
224
+ //# sourceMappingURL=reviews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviews.js","sourceRoot":"","sources":["../../src/tools/reviews.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { TeamflectApiClient } from "../services/apiClient.js";
3
+ /**
4
+ * Register task-related tools
5
+ */
6
+ export declare function registerTaskTools(server: McpServer, apiClient: TeamflectApiClient): void;
7
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK9D;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,GAAG,IAAI,CA2QxF"}