mcpengine/servers/wrike/src/tools/comments-tools.ts
Jake Shore fdfbc4017e Wrike MCP: Complete rebuild with 60+ tools and 22 React apps
- API Client: Full Wrike API v4 with OAuth2/token auth, pagination, error handling
- 60+ Tools across 14 categories: tasks, folders, projects, spaces, contacts, comments, timelogs, attachments, workflows, custom-fields, approvals, groups, invitations, webhooks
- 22 React Apps: task-dashboard, task-detail, task-grid, task-board, project-dashboard, project-detail, project-grid, folder-tree, space-overview, gantt-view, time-dashboard, time-entries, member-workload, comment-thread, approval-manager, workflow-editor, custom-fields-manager, attachment-gallery, search-results, activity-feed, sprint-board, reports-dashboard
- All apps: dark theme, client-side state, standalone directories
- Full TypeScript types for all Wrike API entities
- Comprehensive README with setup instructions

Replaces single-file stub with production-ready MCP server
2026-02-12 17:18:32 -05:00

183 lines
5.8 KiB
TypeScript

import type { WrikeClient } from '../clients/wrike.js';
import type { WrikeComment } from '../types/index.js';
export function createCommentTools(client: WrikeClient) {
return {
// List comments
wrike_list_comments: {
name: 'wrike_list_comments',
description: 'List comments on a task or folder',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID to get comments from' },
folderId: { type: 'string', description: 'Folder ID to get comments from' },
updatedDateStart: { type: 'string', description: 'Updated date range begin' },
updatedDateEnd: { type: 'string', description: 'Updated date range end' },
plainText: { type: 'boolean', description: 'Return plain text instead of HTML' },
limit: { type: 'number', description: 'Maximum comments to return' },
},
},
handler: async (params: Record<string, unknown>) => {
let endpoint = '/comments';
if (params.taskId) {
endpoint = `/tasks/${params.taskId}/comments`;
} else if (params.folderId) {
endpoint = `/folders/${params.folderId}/comments`;
}
const queryParams: Record<string, unknown> = {};
if (params.plainText !== undefined) queryParams.plainText = params.plainText;
if (params.limit) queryParams.limit = params.limit;
if (params.updatedDateStart || params.updatedDateEnd) {
queryParams.updatedDate = {
start: params.updatedDateStart,
end: params.updatedDateEnd,
};
}
const response = await client.get<WrikeComment>(endpoint, queryParams);
return {
content: [
{
type: 'text',
text: JSON.stringify(response.data, null, 2),
},
],
};
},
},
// Get comment by ID
wrike_get_comment: {
name: 'wrike_get_comment',
description: 'Get a specific comment by ID',
inputSchema: {
type: 'object',
properties: {
commentId: { type: 'string', description: 'Comment ID (required)' },
plainText: { type: 'boolean', description: 'Return plain text instead of HTML' },
},
required: ['commentId'],
},
handler: async (params: { commentId: string; plainText?: boolean }) => {
const response = await client.get<WrikeComment>(`/comments/${params.commentId}`, {
plainText: params.plainText,
});
return {
content: [
{
type: 'text',
text: JSON.stringify(response.data[0], null, 2),
},
],
};
},
},
// Create comment
wrike_create_comment: {
name: 'wrike_create_comment',
description: 'Create a new comment on a task or folder',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID to comment on' },
folderId: { type: 'string', description: 'Folder ID to comment on' },
text: { type: 'string', description: 'Comment text (HTML supported, required)' },
plainText: { type: 'boolean', description: 'Text is plain text, not HTML' },
},
required: ['text'],
},
handler: async (params: { taskId?: string; folderId?: string; text: string; plainText?: boolean }) => {
let endpoint = '/comments';
if (params.taskId) {
endpoint = `/tasks/${params.taskId}/comments`;
} else if (params.folderId) {
endpoint = `/folders/${params.folderId}/comments`;
} else {
throw new Error('Either taskId or folderId is required');
}
const body = {
text: params.text,
plainText: params.plainText,
};
const response = await client.post<WrikeComment>(endpoint, body);
return {
content: [
{
type: 'text',
text: JSON.stringify(response.data[0], null, 2),
},
],
};
},
},
// Update comment
wrike_update_comment: {
name: 'wrike_update_comment',
description: 'Update an existing comment',
inputSchema: {
type: 'object',
properties: {
commentId: { type: 'string', description: 'Comment ID (required)' },
text: { type: 'string', description: 'New comment text (required)' },
plainText: { type: 'boolean', description: 'Text is plain text, not HTML' },
},
required: ['commentId', 'text'],
},
handler: async (params: { commentId: string; text: string; plainText?: boolean }) => {
const body = {
text: params.text,
plainText: params.plainText,
};
const response = await client.put<WrikeComment>(`/comments/${params.commentId}`, body);
return {
content: [
{
type: 'text',
text: JSON.stringify(response.data[0], null, 2),
},
],
};
},
},
// Delete comment
wrike_delete_comment: {
name: 'wrike_delete_comment',
description: 'Delete a comment',
inputSchema: {
type: 'object',
properties: {
commentId: { type: 'string', description: 'Comment ID (required)' },
},
required: ['commentId'],
},
handler: async (params: { commentId: string }) => {
const response = await client.delete<WrikeComment>(`/comments/${params.commentId}`);
return {
content: [
{
type: 'text',
text: JSON.stringify(response.data[0], null, 2),
},
],
};
},
},
};
}