extract_action_items
Extracts actionable items from conversations and optionally creates tasks to help teams implement decisions and track follow-ups from discussions.
Instructions
Extract actionable items from a conversation and optionally create tasks
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| conversation_id | Yes | The conversation ID to extract action items from | |
| auto_create_tasks | No | Whether to automatically create tasks for action items |
Implementation Reference
- src/tools/ai-conversations.ts:363-412 (handler)The primary handler function for the 'extract_action_items' MCP tool. It validates input, retrieves the conversation from the database, extracts action items using a helper function, and optionally creates Supabase tasks if auto_create_tasks is true.export const extractActionItems = requireAuth(async (args: any) => { const { conversation_id, auto_create_tasks } = ExtractActionItemsSchema.parse(args) logger.info('Extracting action items', { conversation_id, auto_create_tasks }) const conversation = await getConversationFromDatabase(conversation_id) if (!conversation) { throw new Error('Conversation not found') } const actionItems = extractActionItemsFromConversation( conversation.messages, conversation.metadata?.context ) let createdTasks = [] if (auto_create_tasks && actionItems.length > 0) { // Create tasks for each action item for (const item of actionItems) { try { const task = await supabaseService.createTask({ project_id: conversation.project_id, initiative_id: null, title: item.title, description: `${item.description}\n\nExtracted from conversation: ${conversation.title}\n\n[Source: AI Conversation ${conversation.id}, Confidence: ${item.confidence}]`, priority: item.priority || 'medium', status: 'todo', due_date: null, assignee_id: null }) createdTasks.push(task) } catch (error) { logger.error('Failed to create task from action item', { error, item }) } } } return { conversation_id, action_items: actionItems, created_tasks: createdTasks, summary: { total_items: actionItems.length, high_priority: actionItems.filter(item => item.priority === 'high').length, tasks_created: createdTasks.length } } })
- src/tools/ai-conversations.ts:52-55 (schema)Zod validation schema used in the handler to parse and validate input arguments for the tool.const ExtractActionItemsSchema = z.object({ conversation_id: z.string().uuid(), auto_create_tasks: z.boolean().default(false) })
- src/tools/ai-conversations.ts:342-361 (registration)MCPTool registration object defining the tool's name, description, and JSON input schema for the MCP protocol.export const extractActionItemsTool: MCPTool = { name: 'extract_action_items', description: 'Extract actionable items from a conversation and optionally create tasks', inputSchema: { type: 'object', properties: { conversation_id: { type: 'string', format: 'uuid', description: 'The conversation ID to extract action items from' }, auto_create_tasks: { type: 'boolean', default: false, description: 'Whether to automatically create tasks for action items' } }, required: ['conversation_id'] } }
- src/tools/ai-conversations.ts:851-856 (registration)Handler map registration that associates the 'extract_action_items' name with the extractActionItems handler function.export const conversationHandlers = { save_conversation: saveConversation, get_conversations: getConversations, analyze_conversation: analyzeConversation, extract_action_items: extractActionItems, generate_conversation_summary: generateConversationSummary
- Core helper function that implements the action item extraction logic using regex patterns on conversation messages, assigning priority and confidence scores.function extractActionItemsFromConversation(messages: Message[], context?: any): any[] { const actionItems: any[] = [] // Simple regex patterns for action items const patterns = [ /(?:need to|should|must|will|todo|action item):?\s*(.+)/gi, /(?:let's|we'll|i'll|you'll)\s+(.+)/gi, /(?:next step|follow up|follow-up):?\s*(.+)/gi ] messages.forEach((message, index) => { patterns.forEach(pattern => { const matches = [...message.content.matchAll(pattern)] matches.forEach(match => { if (match[1] && match[1].length > 10 && match[1].length < 200) { actionItems.push({ title: match[1].trim(), description: `From conversation: "${message.content.substring(0, 100)}..."`, source_message_index: index, source_role: message.role, priority: determinePriority(match[1]), confidence: calculateConfidence(match[1], message.content), context }) } }) }) }) return actionItems }