UNPKG

twenty-mcp-server

Version:

Easy-to-install Model Context Protocol server for Twenty CRM. Try instantly with 'npx twenty-mcp-server setup' or install globally for permanent use.

196 lines (190 loc) 9.02 kB
import { z } from 'zod'; export function registerActivityTools(server, client) { server.tool('get_activities', 'Get unified activities timeline from Twenty CRM (tasks, notes, etc.)', { type: z.array(z.enum(['task', 'note'])).optional().describe('Filter by activity types'), dateFrom: z.string().optional().describe('Start date filter (ISO 8601 format)'), dateTo: z.string().optional().describe('End date filter (ISO 8601 format)'), authorId: z.string().optional().describe('Filter by author/assignee ID'), limit: z.number().optional().default(20).describe('Maximum number of activities to return'), offset: z.number().optional().default(0).describe('Number of activities to skip'), }, async (args) => { try { const timeline = await client.getActivities({ type: args.type, dateFrom: args.dateFrom, dateTo: args.dateTo, authorId: args.authorId, limit: args.limit, offset: args.offset, }); const activitiesText = timeline.activities.map(activity => { const authorName = activity.author ? `${activity.author.name.firstName} ${activity.author.name.lastName}` : 'Unknown'; const createdDate = new Date(activity.createdAt).toLocaleDateString(); return `[${activity.type.toUpperCase()}] ${activity.title || 'Untitled'} (${createdDate}) Author: ${authorName} ${activity.body ? `Content: ${activity.body.substring(0, 200)}${activity.body.length > 200 ? '...' : ''}` : ''} ID: ${activity.id} ---`; }).join('\n\n'); return { content: [{ type: 'text', text: `Activities Timeline (${timeline.totalCount} total, showing ${timeline.activities.length}): ${activitiesText} ${timeline.hasMore ? 'Use offset parameter to load more activities.' : 'No more activities to load.'}` }] }; } catch (error) { return { content: [{ type: 'text', text: `Error retrieving activities: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } }); server.tool('filter_activities', 'Filter activities by specific criteria', { type: z.array(z.enum(['task', 'note'])).optional().describe('Activity types to include'), dateFrom: z.string().optional().describe('Start date (ISO 8601 format)'), dateTo: z.string().optional().describe('End date (ISO 8601 format)'), authorId: z.string().optional().describe('Filter by author/assignee ID'), status: z.array(z.string()).optional().describe('Task status filter (for tasks only)'), limit: z.number().optional().default(20).describe('Maximum number of results'), offset: z.number().optional().default(0).describe('Number of results to skip'), }, async (args) => { try { const activities = await client.filterActivities({ type: args.type, dateFrom: args.dateFrom, dateTo: args.dateTo, authorId: args.authorId, status: args.status, limit: args.limit, offset: args.offset, }); if (activities.length === 0) { return { content: [{ type: 'text', text: 'No activities found matching the specified criteria.' }] }; } const resultsText = activities.map((activity, index) => { const authorName = activity.author ? `${activity.author.name.firstName} ${activity.author.name.lastName}` : 'Unknown'; return `${index + 1}. [${activity.type.toUpperCase()}] ${activity.title || 'Untitled'} Created: ${new Date(activity.createdAt).toLocaleString()} Author: ${authorName} ID: ${activity.id}`; }).join('\n\n'); return { content: [{ type: 'text', text: `Found ${activities.length} activities matching criteria: ${resultsText}` }] }; } catch (error) { return { content: [{ type: 'text', text: `Error filtering activities: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } }); server.tool('create_comment', 'Create a comment on any CRM record', { body: z.string().describe('Comment content'), authorId: z.string().optional().describe('ID of the comment author'), activityTargetId: z.string().optional().describe('ID of the activity target (if linking to specific record)'), targetObjectId: z.string().optional().describe('ID of the target object (person, company, opportunity)'), targetObjectType: z.enum(['person', 'company', 'opportunity']).optional().describe('Type of target object'), }, async (args) => { try { const comment = await client.createComment({ body: args.body, authorId: args.authorId, activityTargetId: args.activityTargetId, targetObjectId: args.targetObjectId, targetObjectNameSingular: args.targetObjectType, }); const authorName = comment.author ? `${comment.author.name.firstName} ${comment.author.name.lastName}` : 'Unknown'; return { content: [{ type: 'text', text: `Comment created successfully by ${authorName} (ID: ${comment.id}) Content: ${comment.body} Created: ${new Date(comment.createdAt).toLocaleString()}` }] }; } catch (error) { return { content: [{ type: 'text', text: `Error creating comment: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } }); server.tool('get_entity_activities', 'Get all activities related to a specific entity (person, company, or opportunity)', { entityId: z.string().describe('ID of the entity'), entityType: z.enum(['person', 'company', 'opportunity']).describe('Type of entity'), includeComments: z.boolean().optional().default(true).describe('Include comments in results'), limit: z.number().optional().default(20).describe('Maximum number of activities'), offset: z.number().optional().default(0).describe('Number of activities to skip'), }, async (args) => { try { const timeline = await client.getEntityActivities({ entityId: args.entityId, entityType: args.entityType, includeComments: args.includeComments, limit: args.limit, offset: args.offset, }); if (timeline.activities.length === 0) { return { content: [{ type: 'text', text: `No activities found for ${args.entityType} ${args.entityId}.` }] }; } const activitiesText = timeline.activities.map((activity, index) => { const authorName = activity.author ? `${activity.author.name.firstName} ${activity.author.name.lastName}` : 'Unknown'; const date = new Date(activity.createdAt); return `${index + 1}. [${activity.type.toUpperCase()}] ${activity.title || 'Untitled'} Created: ${date.toLocaleDateString()} at ${date.toLocaleTimeString()} Author: ${authorName} ${activity.body ? `Preview: ${activity.body.substring(0, 150)}${activity.body.length > 150 ? '...' : ''}` : ''}`; }).join('\n\n'); return { content: [{ type: 'text', text: `Activities for ${args.entityType} ${args.entityId} (${timeline.totalCount} total): ${activitiesText} ${timeline.hasMore ? `Use offset=${args.offset + args.limit} to load more activities.` : 'No more activities available.'}` }] }; } catch (error) { return { content: [{ type: 'text', text: `Error retrieving entity activities: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } }); } //# sourceMappingURL=activities.js.map