@mgsoftwarebv/mcp-server-bridge 2.12.1 → 2.13.0

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 CHANGED
@@ -98,7 +98,7 @@ De bridge geeft toegang tot alle tools van je MCP server:
98
98
  - **save-customer-response** - Sla customer response op
99
99
 
100
100
  ### Time Tracking
101
- - **log-hours** šŸ†• - Analyseer chat conversatie en log uren automatisch (zie Cursor Command `/hours`)
101
+ - **log-hours** šŸ†• - Analyseer chat conversatie en log uren automatisch naar agenda (zie Cursor Command `/hours`)
102
102
 
103
103
  ## ā±ļø Quick Hour Logging met `/hours` Command
104
104
 
package/dist/index.js CHANGED
@@ -689,8 +689,7 @@ ${email ? `Email: ${email}
689
689
  name,
690
690
  description,
691
691
  customer_id,
692
- created_at,
693
- customers(id, name)
692
+ created_at
694
693
  `).in("team_id", teamIds).limit(Math.min(pageSize, 100));
695
694
  if (customerId) query = query.eq("customer_id", customerId);
696
695
  if (q) query = query.ilike("name", `%${q}%`);
@@ -704,7 +703,6 @@ ${email ? `Email: ${email}
704
703
  ${data?.map(
705
704
  (project) => `**${project.name}** (ID: ${project.id})
706
705
  ${project.description ? `Description: ${project.description}
707
- ` : ""}${project.customers?.name ? `Customer: ${project.customers.name}
708
706
  ` : ""}Created: ${new Date(project.created_at).toLocaleDateString()}
709
707
  `
710
708
  ).join("\n") || "No projects found."}`
@@ -1327,19 +1325,22 @@ ${efficiencyNotes}
1327
1325
  const durationSeconds = Math.round(estimatedHours * 3600);
1328
1326
  const now = /* @__PURE__ */ new Date();
1329
1327
  const startTime = new Date(now.getTime() - durationSeconds * 1e3);
1330
- const { data: trackerEntry, error: trackerError } = await supabase.from("tracker_entries").insert({
1328
+ const { data: agendaEntry, error: agendaError } = await supabase.from("agenda_events").insert({
1331
1329
  team_id: authContext.teamId,
1332
- assigned_id: authContext.userId,
1330
+ user_id: authContext.userId,
1333
1331
  project_id: project?.id || null,
1334
- description: workDescription,
1335
- duration: durationSeconds,
1336
- start: startTime.toISOString(),
1337
- stop: now.toISOString(),
1338
- date: now.toISOString().split("T")[0],
1339
- billed: false
1340
- }).select("id, duration, project_id").single();
1341
- if (trackerError || !trackerEntry) {
1342
- throw new Error(`Failed to create tracker entry: ${trackerError?.message || "Unknown error"}`);
1332
+ title: workDescription,
1333
+ description: chatContextSummary || workDescription,
1334
+ start_time: startTime.toISOString(),
1335
+ end_time: now.toISOString(),
1336
+ type: "work",
1337
+ status: "draft",
1338
+ all_day: false,
1339
+ is_tracked: true,
1340
+ tracked_duration: durationSeconds
1341
+ }).select("id, tracked_duration, project_id").single();
1342
+ if (agendaError || !agendaEntry) {
1343
+ throw new Error(`Failed to create time entry: ${agendaError?.message || "Unknown error"}`);
1343
1344
  }
1344
1345
  let responseText = `\u23F1\uFE0F **Hours Logged Successfully!**
1345
1346
 
@@ -1359,7 +1360,7 @@ ${efficiencyNotes}
1359
1360
  `;
1360
1361
  responseText += ` \u2022 Status: DRAFT (not billed yet)
1361
1362
  `;
1362
- responseText += ` \u2022 Entry ID: ${trackerEntry.id}
1363
+ responseText += ` \u2022 Entry ID: ${agendaEntry.id}
1363
1364
 
1364
1365
  `;
1365
1366
  if (chatContextSummary) {
@@ -1369,7 +1370,7 @@ ${efficiencyNotes}
1369
1370
 
1370
1371
  `;
1371
1372
  }
1372
- responseText += `\u2705 Time entry created and ready for review in the tracker!`;
1373
+ responseText += `\u2705 Time entry created and ready for review in the agenda!`;
1373
1374
  return {
1374
1375
  content: [{
1375
1376
  type: "text",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["args","name"],"mappings":"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","file":"index.js","sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';\r\nimport { createClient } from '@supabase/supabase-js';\r\nimport { createHash } from 'crypto';\r\n\r\n// Parse command line arguments and environment\r\nconst args = process.argv.slice(2);\r\nconst apiKey = args.find(arg => arg.startsWith('--api-key='))?.split('=')[1] || process.env.MG_TICKETS_API_KEY;\r\n// Default to MG Software's Supabase for SaaS customers\r\nconst supabaseUrl = args.find(arg => arg.startsWith('--supabase-url='))?.split('=')[1] || \r\n process.env.SUPABASE_URL || \r\n 'https://cvjdbczxyczjnatuolsk.supabase.co';\r\n\r\nconst supabaseKey = args.find(arg => arg.startsWith('--supabase-key='))?.split('=')[1] || \r\n process.env.SUPABASE_SERVICE_ROLE_KEY || \r\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN2amRiY3p4eWN6am5hdHVvbHNrIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc1NjE0NzcyNCwiZXhwIjoyMDcxNzIzNzI0fQ.LljuNdCZXDcSIVTeIVOSNsvGNBfWsIM1QIswBJmGXKE';\r\n\r\nif (!apiKey) {\r\n console.error('āŒ API key is required. Use --api-key=your_key or set MG_TICKETS_API_KEY environment variable');\r\n process.exit(1);\r\n}\r\n\r\n// Supabase credentials validation (optional with defaults)\r\nif (!supabaseUrl || !supabaseKey) {\r\n console.error('āŒ Supabase credentials missing. Using defaults for MG Software SaaS.');\r\n}\r\n\r\n// Initialize Supabase client with service role\r\nconst supabase = createClient(supabaseUrl, supabaseKey);\r\n\r\ninterface AuthContext {\r\n userId: string;\r\n teamId: string;\r\n scopes: string[];\r\n}\r\n\r\n// Smart time estimation and codebase analysis is now handled by Cursor AI\r\n// MCP bridge focuses on data storage and session management only\r\n\r\n// Helper function to get accessible team IDs (own team + child teams)\r\nasync function getAccessibleTeamIds(teamId: string): Promise<string[]> {\r\n const { data: accessibleTeams } = await supabase\r\n .from('teams')\r\n .select('id')\r\n .or(`id.eq.${teamId},parent_team_id.eq.${teamId}`);\r\n \r\n return accessibleTeams?.map(t => t.id) || [teamId];\r\n}\r\n\r\n// API Key validation - direct database access\r\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\r\n if (!key.startsWith('mid_') || key.length !== 68) {\r\n console.error('šŸ”‘ Invalid API key format');\r\n return null;\r\n }\r\n\r\n try {\r\n // Hash the API key\r\n const keyHash = createHash('sha256').update(key).digest('hex');\r\n console.error(`šŸ” Validating API key hash: ${keyHash.substring(0, 16)}...`);\r\n \r\n // Query database for API key\r\n const { data: apiKeyData, error } = await supabase\r\n .from('api_keys')\r\n .select('id, user_id, team_id, scopes, last_used_at')\r\n .eq('key_hash', keyHash)\r\n .single();\r\n\r\n if (error || !apiKeyData) {\r\n console.error('āŒ API key not found or invalid:', error?.message);\r\n return null;\r\n }\r\n\r\n // Update last used timestamp\r\n await supabase\r\n .from('api_keys')\r\n .update({ last_used_at: new Date().toISOString() })\r\n .eq('id', apiKeyData.id);\r\n\r\n console.error(`āœ… API key validated for user ${apiKeyData.user_id} in team ${apiKeyData.team_id}`);\r\n \r\n return {\r\n userId: apiKeyData.user_id,\r\n teamId: apiKeyData.team_id,\r\n scopes: apiKeyData.scopes || []\r\n };\r\n } catch (error) {\r\n console.error('šŸ’„ API key validation error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n// Validate auth context once at startup\r\nlet authContext: AuthContext | null = null;\r\n\r\n// Helper function to check if a file is an image\r\nfunction isImageFile(mimeType: string): boolean {\r\n return mimeType.startsWith('image/') && \r\n ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'].includes(mimeType);\r\n}\r\n\r\n// Helper function to download and convert image to base64\r\nasync function downloadImageAsBase64(storageKey: string): Promise<string | null> {\r\n try {\r\n // Get signed URL for the file (1 hour expiry)\r\n const { data: urlData, error: urlError } = await supabase.storage\r\n .from('vault')\r\n .createSignedUrl(storageKey, 3600);\r\n \r\n if (urlError || !urlData?.signedUrl) {\r\n console.error(`Failed to create signed URL for ${storageKey}:`, urlError);\r\n return null;\r\n }\r\n \r\n // Download the file\r\n const response = await fetch(urlData.signedUrl);\r\n if (!response.ok) {\r\n console.error(`Failed to download file ${storageKey}: ${response.status}`);\r\n return null;\r\n }\r\n \r\n // Convert to base64\r\n const arrayBuffer = await response.arrayBuffer();\r\n const buffer = Buffer.from(arrayBuffer);\r\n return buffer.toString('base64');\r\n } catch (error) {\r\n console.error(`Error downloading image ${storageKey}:`, error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Convert TipTap JSON format to plain text for timetrack/agenda display\r\n * @param description - The description in TipTap JSON format or plain text\r\n * @returns Plain text version of the description\r\n */\r\nfunction convertTipTapToPlainText(description?: string | null): string {\r\n if (!description) {\r\n return \"\";\r\n }\r\n\r\n // If it's already plain text, return as is\r\n if (!description.startsWith('{\"type\":\"doc\"')) {\r\n return description;\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(description);\r\n \r\n // Recursively extract text from TipTap JSON structure\r\n const extractText = (node: any): string => {\r\n if (!node) return \"\";\r\n\r\n // Text nodes contain the actual text\r\n if (node.type === \"text\") {\r\n return node.text || \"\";\r\n }\r\n\r\n // Handle hard breaks\r\n if (node.type === \"hardBreak\") {\r\n return \"\\n\";\r\n }\r\n\r\n // Handle mentions\r\n if (node.type === \"mention\") {\r\n return `@${node.attrs?.label || node.attrs?.id || \"\"}`;\r\n }\r\n\r\n // Handle ticket mentions\r\n if (node.type === \"ticketMention\") {\r\n return `#${node.attrs?.label || node.attrs?.id || \"\"}`;\r\n }\r\n\r\n // Handle images\r\n if (node.type === \"image\") {\r\n return \"[afbeelding]\";\r\n }\r\n\r\n // Process children recursively\r\n if (node.content && Array.isArray(node.content)) {\r\n const childrenText = node.content.map(extractText).join(\"\");\r\n \r\n // Add appropriate spacing based on node type\r\n switch (node.type) {\r\n case \"paragraph\":\r\n return childrenText + \"\\n\";\r\n case \"heading\":\r\n return childrenText + \"\\n\\n\";\r\n case \"listItem\":\r\n return \"• \" + childrenText + \"\\n\";\r\n case \"blockquote\":\r\n return \"> \" + childrenText + \"\\n\";\r\n default:\r\n return childrenText;\r\n }\r\n }\r\n \r\n // For nodes without content (like empty paragraphs without content array)\r\n if (node.type === \"paragraph\") {\r\n return \"\\n\";\r\n }\r\n\r\n return \"\";\r\n };\r\n\r\n const plainText = extractText(parsed);\r\n return plainText.trim();\r\n } catch (error) {\r\n // If parsing fails, return original string\r\n return description;\r\n }\r\n}\r\n\r\n// MCP Server setup\r\nconst server = new Server(\r\n {\r\n name: 'mg-tickets-mcp-bridge',\r\n version: '2.0.0',\r\n },\r\n {\r\n capabilities: {\r\n tools: {},\r\n resources: {},\r\n },\r\n }\r\n);\r\n\r\n// Available tools definition\r\nconst TOOLS = [\r\n {\r\n name: 'get-tickets',\r\n description: 'Get tickets with optional filtering by status, priority, project, customer, or search query',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'] },\r\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\r\n projectId: { type: 'string' },\r\n customerId: { type: 'string' },\r\n q: { type: 'string', description: 'Search query for title or description' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'get-ticket-by-id',\r\n description: 'Get a specific ticket by its ID, including all attachments, comments, and images. Images from ticket attachments and comment attachments are automatically downloaded and returned as base64-encoded content that can be analyzed by AI.',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n id: { type: 'string', description: 'Ticket ID' }\r\n },\r\n required: ['id']\r\n }\r\n },\r\n {\r\n name: 'create-ticket',\r\n description: 'Create a new ticket',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n title: { type: 'string', description: 'Ticket title' },\r\n description: { type: 'string' },\r\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'], default: 'open' },\r\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },\r\n type: { type: 'string', enum: ['task', 'bug', 'feature', 'support', 'question', 'improvement'], default: 'task' },\r\n projectId: { type: 'string' },\r\n customerId: { type: 'string' }\r\n },\r\n required: ['title']\r\n }\r\n },\r\n {\r\n name: 'get-customers',\r\n description: 'Get customers with optional search',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n q: { type: 'string', description: 'Search query for customer name or email' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'create-customer',\r\n description: 'Create a new customer',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n name: { type: 'string', description: 'Customer name' },\r\n email: { type: 'string' },\r\n website: { type: 'string' }\r\n },\r\n required: ['name']\r\n }\r\n },\r\n {\r\n name: 'get-projects',\r\n description: 'Get projects with optional filtering',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n customerId: { type: 'string', description: 'Filter by customer ID' },\r\n q: { type: 'string', description: 'Search query for project name' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'create-project',\r\n description: 'Create a new project',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n name: { type: 'string', description: 'Project name' },\r\n description: { type: 'string' },\r\n customerId: { type: 'string' },\r\n status: { type: 'string', enum: ['active', 'on_hold', 'completed', 'cancelled'], default: 'active' }\r\n },\r\n required: ['name']\r\n }\r\n },\r\n // === NEW AI SESSION TOOLS ===\r\n {\r\n name: 'start-ai-session-smart',\r\n description: 'Start a new AI development session with automatic tracking (time breakdown provided by Cursor AI)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n ticketId: { type: 'string' },\r\n ticketUrl: { type: 'string', description: 'URL to the ticket' },\r\n cursorSessionId: { type: 'string', description: 'Cursor session identifier' },\r\n codebaseContext: { \r\n type: 'array', \r\n items: { type: 'string' },\r\n description: 'Relevant files for complexity analysis'\r\n },\r\n timeBreakdown: {\r\n type: 'object',\r\n description: 'Time estimate breakdown by development phase (REQUIRED)',\r\n properties: {\r\n analysisMinutes: { type: 'number', description: 'Ticket/context analysis time' },\r\n investigationMinutes: { type: 'number', description: 'Bug investigation/reproduction (0 if not a bug)' },\r\n developmentMinutes: { type: 'number', description: 'Actual coding/fixing time' },\r\n communicationMinutes: { type: 'number', description: 'Customer response writing time' }\r\n },\r\n required: ['analysisMinutes', 'investigationMinutes', 'developmentMinutes', 'communicationMinutes']\r\n },\r\n complexityScore: {\r\n type: 'number',\r\n minimum: 1,\r\n maximum: 10,\r\n description: 'Estimated complexity from 1-10'\r\n }\r\n },\r\n required: ['ticketId', 'timeBreakdown']\r\n }\r\n },\r\n {\r\n name: 'track-manual-follow-up',\r\n description: 'Track manual follow-up prompt by developer',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n originalPrompt: { type: 'string' },\r\n aiResponse: { type: 'string' },\r\n developerFollowUp: { type: 'string' },\r\n followUpReason: { \r\n type: 'string', \r\n enum: ['incomplete_result', 'wrong_approach', 'needs_clarification', 'error_in_code']\r\n },\r\n outcome: {\r\n type: 'string',\r\n enum: ['success', 'partial_success', 'still_failed'],\r\n default: 'success'\r\n },\r\n timeSpentMinutes: { type: 'number' }\r\n },\r\n required: ['aiSessionId', 'originalPrompt', 'aiResponse', 'developerFollowUp', 'followUpReason']\r\n }\r\n },\r\n {\r\n name: 'get-session-context',\r\n description: 'Get current session context for follow-up continuity',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n includeTicketData: { type: 'boolean', default: true },\r\n includeTodoProgress: { type: 'boolean', default: true },\r\n includeFollowUpHistory: { type: 'boolean', default: false }\r\n },\r\n required: ['aiSessionId']\r\n }\r\n },\r\n {\r\n name: 'sync-session-todos',\r\n description: 'Synchronize todo list with AI session (replace existing) or add new todos',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n todos: {\r\n type: 'array',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n todoId: { type: 'string', description: 'Optional external todo ID for tracking' },\r\n content: { type: 'string' },\r\n status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'] },\r\n estimatedMinutes: { type: 'number' }\r\n },\r\n required: ['content', 'status']\r\n }\r\n },\r\n replaceAll: { \r\n type: 'boolean', \r\n default: true, \r\n description: 'If true, replace all existing todos. If false, add new todos to existing ones' \r\n }\r\n },\r\n required: ['aiSessionId', 'todos']\r\n }\r\n },\r\n {\r\n name: 'add-follow-up-todos',\r\n description: 'Add new todos from follow-up (without replacing existing ones)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n newTodos: {\r\n type: 'array',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n content: { type: 'string' },\r\n status: { type: 'string', enum: ['pending', 'in_progress'], default: 'pending' },\r\n estimatedMinutes: { type: 'number' },\r\n addedInFollowUp: { type: 'boolean', default: true }\r\n },\r\n required: ['content']\r\n }\r\n },\r\n followUpReason: { \r\n type: 'string', \r\n description: 'Why were these todos added in follow-up' \r\n }\r\n },\r\n required: ['aiSessionId', 'newTodos']\r\n }\r\n },\r\n {\r\n name: 'update-session-status',\r\n description: 'Update AI session status and completion info',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n status: {\r\n type: 'string',\r\n enum: ['started', 'in_progress', 'paused', 'completed', 'failed']\r\n },\r\n actualTimeMinutes: { type: 'number' },\r\n completionNotes: { type: 'string' }\r\n },\r\n required: ['aiSessionId', 'status']\r\n }\r\n },\r\n {\r\n name: 'get-completion-context',\r\n description: 'Get all context needed for Cursor AI to generate customer response',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n includeFollowUps: { type: 'boolean', default: true },\r\n includeTimeMetrics: { type: 'boolean', default: true },\r\n includeTodos: { type: 'boolean', default: true }\r\n },\r\n required: ['aiSessionId']\r\n }\r\n },\r\n {\r\n name: 'save-customer-response',\r\n description: 'Save customer response generated by Cursor AI',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n customerResponse: { type: 'string', description: 'Customer response generated by Cursor AI' },\r\n responseType: { \r\n type: 'string', \r\n enum: ['completion', 'progress_update', 'needs_clarification'],\r\n default: 'completion'\r\n }\r\n },\r\n required: ['aiSessionId', 'customerResponse']\r\n }\r\n },\r\n {\r\n name: 'complete-ai-session',\r\n description: 'Complete AI session with work summary - time calculated automatically',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n workCompleted: {\r\n type: 'array',\r\n items: { type: 'string' },\r\n description: 'List of completed tasks/todos in English'\r\n },\r\n technicalSummary: {\r\n type: 'string',\r\n description: 'Technical summary of work done in English'\r\n },\r\n invoiceDescription: {\r\n type: 'string',\r\n description: 'Short invoice-friendly description in the language of the ticket (2-3 sentences max, suitable for billing)'\r\n },\r\n efficiencyNotes: { type: 'string' }\r\n },\r\n required: ['aiSessionId', 'workCompleted']\r\n }\r\n },\r\n {\r\n name: 'log-hours',\r\n description: 'Analyze current chat conversation and log hours as draft tracker entry. AI analyzes chat context to estimate hours as a senior developer would (without AI assistance). Cursor AI matches workspace name to correct project from list (optional).',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n projectId: {\r\n type: 'string',\r\n description: 'Project ID (UUID) - Optional. Cursor AI should call get-projects first to try matching workspace name. If no clear match, omit this field.'\r\n },\r\n workDescription: {\r\n type: 'string',\r\n description: 'Short description of the work done (for the tracker entry)'\r\n },\r\n estimatedHours: {\r\n type: 'number',\r\n description: 'AI-estimated hours as senior developer would spend WITHOUT AI (e.g., 2.5 for 2.5 hours)'\r\n },\r\n chatContextSummary: {\r\n type: 'string',\r\n description: 'Brief summary of chat context for internal logging (optional)'\r\n }\r\n },\r\n required: ['workDescription', 'estimatedHours']\r\n }\r\n }\r\n];\r\n\r\n// Available resources\r\nconst RESOURCES = [\r\n {\r\n uri: 'tickets://recent',\r\n name: 'Recent Tickets',\r\n description: 'Most recently created tickets',\r\n mimeType: 'application/json'\r\n },\r\n {\r\n uri: 'customers://all',\r\n name: 'All Customers', \r\n description: 'Complete customer directory',\r\n mimeType: 'application/json'\r\n },\r\n {\r\n uri: 'projects://active',\r\n name: 'Active Projects',\r\n description: 'Currently active projects',\r\n mimeType: 'application/json'\r\n }\r\n];\r\n\r\n// List tools handler\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return { tools: TOOLS };\r\n});\r\n\r\n// List resources handler\r\nserver.setRequestHandler(ListResourcesRequestSchema, async () => {\r\n return { resources: RESOURCES };\r\n});\r\n\r\n// Tool execution handler\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n if (!authContext) {\r\n return {\r\n content: [{ type: 'text', text: 'Error: Not authenticated. API key validation failed.' }],\r\n };\r\n }\r\n\r\n const { name, arguments: args } = request.params;\r\n console.error(`šŸ› ļø Executing tool: ${name} for team ${authContext.teamId}`);\r\n \r\n try {\r\n switch (name) {\r\n case 'get-tickets': {\r\n const { status, priority, projectId, customerId, q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('tickets')\r\n .select(`\r\n id,\r\n ticket_number,\r\n title,\r\n description,\r\n status,\r\n priority,\r\n type,\r\n created_at,\r\n project_id,\r\n customer_id,\r\n projects:project_id(id, name),\r\n customers:customer_id(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (status) query = query.eq('status', status);\r\n if (priority) query = query.eq('priority', priority);\r\n if (projectId) query = query.eq('project_id', projectId);\r\n if (customerId) query = query.eq('customer_id', customerId);\r\n if (q) query = query.or(`title.ilike.%${q}%,description.ilike.%${q}%`);\r\n \r\n const { data, error } = await query.order('created_at', { ascending: false });\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} tickets:\\n\\n${data?.map(ticket => \r\n `**${ticket.ticket_number}**: ${ticket.title}\\n` +\r\n `Status: ${ticket.status} | Priority: ${ticket.priority}\\n` +\r\n `${(ticket.projects as any)?.name ? `Project: ${(ticket.projects as any).name}\\n` : ''}` +\r\n `${(ticket.customers as any)?.name ? `Customer: ${(ticket.customers as any).name}\\n` : ''}` +\r\n `Created: ${new Date(ticket.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No tickets found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-ticket-by-id': {\r\n const { id } = args as any;\r\n \r\n // Get ticket data - include tickets from provider's team AND child customer teams\r\n const { data: ticketData, error } = await supabase\r\n .from('tickets')\r\n .select(`\r\n *,\r\n projects:project_id(id, name),\r\n customers:customer_id(id, name),\r\n assignee:assignee_id(id, full_name, email),\r\n requester:requester_id(id, full_name, email)\r\n `)\r\n .eq('id', id)\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // Check if user has access to this ticket (own team or child team)\r\n const { data: teamAccess } = await supabase\r\n .from('teams')\r\n .select('id')\r\n .or(`id.eq.${ticketData.team_id},parent_team_id.eq.${authContext.teamId}`)\r\n .eq('id', ticketData.team_id)\r\n .single();\r\n \r\n if (!teamAccess && ticketData.team_id !== authContext.teamId) {\r\n throw new Error('Access denied: You do not have permission to view this ticket');\r\n }\r\n \r\n const data = ticketData;\r\n \r\n // Get ticket attachments (no team filter needed - already validated ticket access)\r\n const { data: attachments, error: attachmentsError } = await supabase\r\n .from('ticket_attachments')\r\n .select(`\r\n id,\r\n file_name,\r\n file_size,\r\n mime_type,\r\n storage_key,\r\n created_at,\r\n users:user_id(id, full_name)\r\n `)\r\n .eq('ticket_id', id)\r\n .order('created_at', { ascending: true });\r\n \r\n if (attachmentsError) {\r\n console.error('Error fetching attachments:', attachmentsError);\r\n }\r\n \r\n // Get ticket comments\r\n const { data: comments, error: commentsError } = await supabase\r\n .from('ticket_comments')\r\n .select(`\r\n id,\r\n content,\r\n created_at,\r\n users:user_id(id, full_name)\r\n `)\r\n .eq('ticket_id', id)\r\n .order('created_at', { ascending: true });\r\n \r\n if (commentsError) {\r\n console.error('Error fetching comments:', commentsError);\r\n }\r\n \r\n // Get comment attachments (no team filter needed - already validated ticket access)\r\n const commentIds = comments?.map(c => c.id) || [];\r\n let commentAttachments: any[] = [];\r\n \r\n if (commentIds.length > 0) {\r\n const { data: commAttachments, error: commAttachmentsError } = await supabase\r\n .from('ticket_comment_attachments')\r\n .select(`\r\n id,\r\n comment_id,\r\n file_name,\r\n file_size,\r\n mime_type,\r\n storage_key,\r\n created_at\r\n `)\r\n .in('comment_id', commentIds);\r\n \r\n if (commAttachmentsError) {\r\n console.error('Error fetching comment attachments:', commAttachmentsError);\r\n } else {\r\n commentAttachments = commAttachments || [];\r\n }\r\n }\r\n \r\n // Build content array starting with text\r\n const content: any[] = [{\r\n type: 'text',\r\n text: `**Ticket Details:**\\n\\n` +\r\n `**${data.ticket_number}**: ${data.title}\\n` +\r\n `Status: ${data.status}\\n` +\r\n `Priority: ${data.priority}\\n` +\r\n `Type: ${data.type}\\n` +\r\n `${data.description ? `Description: ${data.description}\\n` : ''}` +\r\n `${(data.projects as any)?.name ? `Project: ${(data.projects as any).name}\\n` : ''}` +\r\n `${(data.customers as any)?.name ? `Customer: ${(data.customers as any).name}\\n` : ''}` +\r\n `${data.assignee?.full_name ? `Assignee: ${data.assignee.full_name}\\n` : ''}` +\r\n `Requester: ${data.requester?.full_name || 'Unknown'}\\n` +\r\n `Created: ${new Date(data.created_at).toLocaleDateString()}\\n` +\r\n `${attachments && attachments.length > 0 ? `\\nšŸ“Ž Attachments: ${attachments.length}\\n` : ''}` +\r\n `${comments && comments.length > 0 ? `šŸ’¬ Comments: ${comments.length}\\n` : ''}`\r\n }];\r\n \r\n // Process ticket attachments - download images\r\n if (attachments && attachments.length > 0) {\r\n console.error(`šŸ“Ž Processing ${attachments.length} ticket attachments...`);\r\n \r\n for (const attachment of attachments) {\r\n if (isImageFile(attachment.mime_type)) {\r\n console.error(`šŸ–¼ļø Downloading image: ${attachment.file_name}`);\r\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\r\n \r\n if (base64Data) {\r\n content.push({\r\n type: 'image',\r\n data: base64Data,\r\n mimeType: attachment.mime_type\r\n });\r\n \r\n // Add text context about the image\r\n content.push({\r\n type: 'text',\r\n text: `\\nšŸ“ø **Image from ticket**: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB, uploaded by ${(attachment.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()})\\n`\r\n });\r\n }\r\n }\r\n }\r\n }\r\n \r\n // Process comment attachments - download images\r\n if (commentAttachments.length > 0) {\r\n console.error(`šŸ“Ž Processing ${commentAttachments.length} comment attachments...`);\r\n \r\n for (const attachment of commentAttachments) {\r\n if (isImageFile(attachment.mime_type)) {\r\n console.error(`šŸ–¼ļø Downloading comment image: ${attachment.file_name}`);\r\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\r\n \r\n if (base64Data) {\r\n // Find the comment this attachment belongs to\r\n const comment = comments?.find(c => c.id === attachment.comment_id);\r\n \r\n content.push({\r\n type: 'image',\r\n data: base64Data,\r\n mimeType: attachment.mime_type\r\n });\r\n \r\n // Add text context about the image\r\n content.push({\r\n type: 'text',\r\n text: `\\nšŸ“ø **Image from comment** by ${(comment?.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()}: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB)\\n` +\r\n (comment?.content ? `Comment text: \"${comment.content.substring(0, 100)}${comment.content.length > 100 ? '...' : ''}\"\\n` : '')\r\n });\r\n }\r\n }\r\n }\r\n }\r\n \r\n console.error(`āœ… Returning ticket with ${content.filter(c => c.type === 'image').length} images`);\r\n \r\n return { content };\r\n }\r\n \r\n case 'create-ticket': {\r\n const { title, description, status = 'open', priority = 'medium', type = 'task', projectId, customerId } = args as any;\r\n \r\n // Generate ticket number\r\n const year = new Date().getFullYear();\r\n const { count } = await supabase\r\n .from('tickets')\r\n .select('*', { count: 'exact', head: true })\r\n .eq('team_id', authContext.teamId);\r\n \r\n const ticketNumber = `${year}-${String((count || 0) + 1).padStart(3, '0')}`;\r\n \r\n const { data, error } = await supabase\r\n .from('tickets')\r\n .insert({\r\n team_id: authContext.teamId,\r\n ticket_number: ticketNumber,\r\n title,\r\n description,\r\n status,\r\n priority,\r\n type,\r\n project_id: projectId || null,\r\n customer_id: customerId || null,\r\n requester_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `āœ… **Ticket Created Successfully!**\\n\\n` +\r\n `Ticket Number: **${ticketNumber}**\\n` +\r\n `Title: ${title}\\n` +\r\n `Status: ${status}\\n` +\r\n `Priority: ${priority}\\n` +\r\n `Type: ${type}\\n`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-customers': {\r\n const { q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('customers')\r\n .select('id, name, email, website, created_at')\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (q) query = query.or(`name.ilike.%${q}%,email.ilike.%${q}%`);\r\n \r\n const { data, error } = await query.order('name');\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} customers:\\n\\n${data?.map(customer => \r\n `**${customer.name}**\\n` +\r\n `${customer.email ? `Email: ${customer.email}\\n` : ''}` +\r\n `${customer.website ? `Website: ${customer.website}\\n` : ''}` +\r\n `Created: ${new Date(customer.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No customers found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'create-customer': {\r\n const { name, email, website } = args as any;\r\n \r\n const { data, error } = await supabase\r\n .from('customers')\r\n .insert({\r\n team_id: authContext.teamId,\r\n name,\r\n email: email || null,\r\n website: website || null,\r\n user_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `āœ… **Customer Created Successfully!**\\n\\n` +\r\n `Name: ${name}\\n` +\r\n `${email ? `Email: ${email}\\n` : ''}` +\r\n `${website ? `Website: ${website}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-projects': {\r\n const { customerId, q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('projects')\r\n .select(`\r\n id,\r\n name,\r\n description,\r\n customer_id,\r\n created_at,\r\n customers(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (customerId) query = query.eq('customer_id', customerId);\r\n if (q) query = query.ilike('name', `%${q}%`);\r\n \r\n const { data, error } = await query.order('name');\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} projects:\\n\\n${data?.map(project => \r\n `**${project.name}** (ID: ${project.id})\\n` +\r\n `${project.description ? `Description: ${project.description}\\n` : ''}` +\r\n `${(project.customers as any)?.name ? `Customer: ${(project.customers as any).name}\\n` : ''}` +\r\n `Created: ${new Date(project.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No projects found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'create-project': {\r\n const { name, description, customerId, status = 'active' } = args as any;\r\n \r\n const { data, error } = await supabase\r\n .from('projects')\r\n .insert({\r\n team_id: authContext.teamId,\r\n name,\r\n description: description || null,\r\n customer_id: customerId || null,\r\n status,\r\n user_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `āœ… **Project Created Successfully!**\\n\\n` +\r\n `Name: ${name}\\n` +\r\n `Status: ${status}\\n` +\r\n `${description ? `Description: ${description}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n // === AI SESSION TOOLS ===\r\n case 'start-ai-session-smart': {\r\n const { ticketId, ticketUrl, cursorSessionId, codebaseContext, timeBreakdown, complexityScore } = args as any;\r\n \r\n // Validate timeBreakdown is provided\r\n if (!timeBreakdown || !timeBreakdown.analysisMinutes || timeBreakdown.developmentMinutes === undefined) {\r\n throw new Error('timeBreakdown is required with all phases: analysisMinutes, investigationMinutes, developmentMinutes, communicationMinutes');\r\n }\r\n \r\n // Calculate total time from breakdown\r\n const totalEstimateMinutes = \r\n (timeBreakdown.analysisMinutes || 0) +\r\n (timeBreakdown.investigationMinutes || 0) +\r\n (timeBreakdown.developmentMinutes || 0) +\r\n (timeBreakdown.communicationMinutes || 0);\r\n \r\n const sessionStartTime = new Date();\r\n \r\n // Create AI session with calculated total\r\n const { data: sessionData, error } = await supabase\r\n .from('ai_sessions')\r\n .insert({\r\n ticket_id: ticketId,\r\n provider_user_id: authContext.userId,\r\n team_id: authContext.teamId,\r\n cursor_session_id: cursorSessionId || null,\r\n ai_time_estimate_minutes: totalEstimateMinutes,\r\n complexity_score: complexityScore || null,\r\n status: 'in_progress'\r\n })\r\n .select('id, ticket_id, cursor_session_id, created_at')\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // CREATE PHASE TIME LOGS: Store breakdown as separate phase activities\r\n const phaseActivities = [\r\n {\r\n ai_session_id: sessionData.id,\r\n activity_type: 'analysis',\r\n description: 'Ticket analysis and context understanding',\r\n duration_seconds: 0,\r\n estimated_duration_seconds: timeBreakdown.analysisMinutes * 60,\r\n status: 'in_progress', // Analysis starts immediately\r\n productivity_score: 8,\r\n started_at: sessionStartTime.toISOString()\r\n },\r\n {\r\n ai_session_id: sessionData.id,\r\n activity_type: 'bug_investigation',\r\n description: 'Bug investigation and root cause analysis',\r\n duration_seconds: 0,\r\n estimated_duration_seconds: timeBreakdown.investigationMinutes * 60,\r\n status: 'pending',\r\n productivity_score: null\r\n },\r\n {\r\n ai_session_id: sessionData.id,\r\n activity_type: 'development',\r\n description: 'Implementation and coding',\r\n duration_seconds: 0,\r\n estimated_duration_seconds: timeBreakdown.developmentMinutes * 60,\r\n status: 'pending',\r\n productivity_score: null\r\n },\r\n {\r\n ai_session_id: sessionData.id,\r\n activity_type: 'communication',\r\n description: 'Customer response and documentation',\r\n duration_seconds: 0,\r\n estimated_duration_seconds: timeBreakdown.communicationMinutes * 60,\r\n status: 'pending',\r\n productivity_score: null\r\n }\r\n ];\r\n \r\n // Insert all phase activities\r\n await supabase.from('ai_time_logs').insert(phaseActivities);\r\n \r\n // Generate a readable session ID for UI\r\n const sessionId = `ai-sess-${sessionData.id.substring(0, 8)}`;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸš€ **AI Session Started Successfully!**\\n\\n` +\r\n `šŸ†” Session ID: **${sessionId}**\\n` +\r\n `šŸŽ« Ticket: ${ticketId}\\n` +\r\n `\\nšŸ“Š **Time Breakdown:**\\n` +\r\n ` • Analysis: ${timeBreakdown.analysisMinutes} min\\n` +\r\n ` • Investigation: ${timeBreakdown.investigationMinutes} min\\n` +\r\n ` • Development: ${timeBreakdown.developmentMinutes} min\\n` +\r\n ` • Communication: ${timeBreakdown.communicationMinutes} min\\n` +\r\n ` • **Total: ${totalEstimateMinutes} min**\\n\\n` +\r\n `${complexityScore ? `šŸŽÆ Complexity: ${complexityScore}/10\\n` : ''}` +\r\n `ā±ļø **Phase Tracking Started** (Analysis in progress)\\n` +\r\n `${cursorSessionId ? `šŸ”— Cursor Session: ${cursorSessionId}\\n` : ''}` +\r\n `šŸ“… Started: ${sessionStartTime.toLocaleString()}\\n\\n` +\r\n `āœ… Session initialized with phase breakdown!\\n` +\r\n `šŸ“ Timetrack entry will be created when you complete the session.`\r\n }]\r\n };\r\n }\r\n \r\n case 'track-manual-follow-up': {\r\n const { aiSessionId, originalPrompt, aiResponse, developerFollowUp, followUpReason, outcome = 'success', timeSpentMinutes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the full session ID and current session data\r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id, status, created_at, ai_time_estimate_minutes')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n const followUpTime = new Date();\r\n \r\n // RESTART SESSION: Set status back to in_progress for continued tracking\r\n await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: 'in_progress', // Restart active tracking\r\n // Don't update completed_at - session continues\r\n })\r\n .eq('id', session.id);\r\n \r\n // LOG FOLLOW-UP: Track the manual follow-up interaction\r\n const { data, error } = await supabase\r\n .from('manual_follow_ups')\r\n .insert({\r\n ai_session_id: session.id,\r\n developer_id: authContext.userId,\r\n team_id: authContext.teamId,\r\n original_prompt: originalPrompt,\r\n ai_response: aiResponse,\r\n follow_up_prompt: developerFollowUp,\r\n follow_up_reason: followUpReason,\r\n outcome: outcome,\r\n time_spent_minutes: timeSpentMinutes || null,\r\n resolved_at: outcome === 'success' ? new Date().toISOString() : null\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // RESTART TIME TRACKING: Log follow-up activity start\r\n await supabase\r\n .from('ai_time_logs')\r\n .insert({\r\n ai_session_id: session.id,\r\n activity_type: 'debugging', // Follow-ups are typically debugging/fixing\r\n description: `Follow-up: ${followUpReason.replace('_', ' ')} - ${outcome}`,\r\n duration_seconds: (timeSpentMinutes || 0) * 60,\r\n productivity_score: outcome === 'success' ? 9 : outcome === 'partial_success' ? 6 : 4,\r\n started_at: followUpTime.toISOString()\r\n });\r\n \r\n // CALCULATE CURRENT EFFICIENCY: Compare time spent vs estimated\r\n const sessionStartTime = new Date(session.created_at);\r\n const totalMinutesElapsed = Math.round((followUpTime.getTime() - sessionStartTime.getTime()) / 60000);\r\n const estimatedMinutes = session.ai_time_estimate_minutes || 60;\r\n const currentEfficiency = totalMinutesElapsed > 0 ? (totalMinutesElapsed / estimatedMinutes) : 1;\r\n \r\n // UPDATE EFFICIENCY TRACKING: Update running efficiency score\r\n await supabase\r\n .from('ai_sessions')\r\n .update({\r\n efficiency_score: currentEfficiency.toFixed(2),\r\n actual_time_minutes: totalMinutesElapsed\r\n })\r\n .eq('id', session.id);\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸ”„ **Follow-up Tracked & Session Restarted!**\\n\\n` +\r\n `šŸ†” Session: ${aiSessionId} (back to active)\\n` +\r\n `šŸ” Reason: ${followUpReason.replace('_', ' ')}\\n` +\r\n `āœ… Outcome: ${outcome}\\n` +\r\n `${timeSpentMinutes ? `ā±ļø Time spent: ${timeSpentMinutes} minutes\\n` : ''}` +\r\n `šŸ“Š **Current Progress:**\\n` +\r\n ` • Total time: ${totalMinutesElapsed} minutes\\n` +\r\n ` • Estimated: ${estimatedMinutes} minutes\\n` +\r\n ` • Efficiency: ${currentEfficiency < 1 ? 'šŸš€ ' : currentEfficiency > 1.5 ? 'āš ļø ' : 'ā±ļø '}${(currentEfficiency * 100).toFixed(0)}%\\n` +\r\n `\\n⚔ **Time tracking resumed** - continue with confidence!`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-session-context': {\r\n const { aiSessionId, includeTicketData = true, includeTodoProgress = true, includeFollowUpHistory = false } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session data with related info - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select(`\r\n id,\r\n ticket_id,\r\n status,\r\n ai_time_estimate_minutes,\r\n actual_time_minutes,\r\n complexity_score,\r\n created_at,\r\n cursor_session_id\r\n `)\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n \r\n if (sessionError || !session) {\r\n throw new Error(`Session not found: ${aiSessionId}`);\r\n }\r\n \r\n let context: any = {\r\n sessionId: aiSessionId,\r\n status: session.status,\r\n timeEstimate: session.ai_time_estimate_minutes,\r\n actualTime: session.actual_time_minutes,\r\n complexity: session.complexity_score,\r\n createdAt: session.created_at\r\n };\r\n \r\n // Include ticket data if requested\r\n if (includeTicketData) {\r\n const { data: ticket } = await supabase\r\n .from('tickets')\r\n .select('id, ticket_number, title, description, status, priority, type')\r\n .eq('id', session.ticket_id)\r\n .single();\r\n \r\n context.ticketData = ticket;\r\n }\r\n \r\n // Include todo progress if requested\r\n if (includeTodoProgress) {\r\n const { data: todos } = await supabase\r\n .from('ai_todos')\r\n .select('id, content, status, estimated_minutes, actual_minutes')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order');\r\n \r\n context.todos = todos || [];\r\n context.todoProgress = {\r\n total: todos?.length || 0,\r\n completed: todos?.filter(t => t.status === 'completed').length || 0,\r\n inProgress: todos?.filter(t => t.status === 'in_progress').length || 0\r\n };\r\n }\r\n \r\n // Include follow-up history if requested\r\n if (includeFollowUpHistory) {\r\n const { data: followUps } = await supabase\r\n .from('manual_follow_ups')\r\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at');\r\n \r\n context.followUpHistory = followUps || [];\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸŽÆ **Session Context Retrieved**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Status: ${session.status}\\n` +\r\n `${context.ticketData ? `Ticket: ${context.ticketData.ticket_number} - ${context.ticketData.title}\\n` : ''}` +\r\n `${context.todoProgress ? `Todo Progress: ${context.todoProgress.completed}/${context.todoProgress.total} completed\\n` : ''}` +\r\n `${context.followUpHistory ? `Follow-ups: ${context.followUpHistory.length}\\n` : ''}` +\r\n `\\nšŸ“‹ Full context preserved for seamless continuation!`\r\n }]\r\n };\r\n }\r\n \r\n case 'sync-session-todos': {\r\n const { aiSessionId, todos, replaceAll = true } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // If replacing all, clear existing todos first\r\n if (replaceAll) {\r\n await supabase\r\n .from('ai_todos')\r\n .delete()\r\n .eq('ai_session_id', session.id);\r\n }\r\n \r\n if (todos && todos.length > 0) {\r\n // Get current max sequence order if adding to existing\r\n let startSequence = 0;\r\n if (!replaceAll) {\r\n const { data: maxTodo } = await supabase\r\n .from('ai_todos')\r\n .select('sequence_order')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order', { ascending: false })\r\n .limit(1)\r\n .single();\r\n startSequence = (maxTodo?.sequence_order || 0) + 1;\r\n }\r\n \r\n const todoInserts = todos.map((todo: any, index: number) => ({\r\n ai_session_id: session.id,\r\n content: todo.content,\r\n status: todo.status,\r\n cursor_todo_id: todo.todoId || null,\r\n estimated_minutes: todo.estimatedMinutes || null,\r\n sequence_order: startSequence + index\r\n }));\r\n \r\n const { error: insertError } = await supabase\r\n .from('ai_todos')\r\n .insert(todoInserts);\r\n \r\n if (insertError) throw insertError;\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `āœ… **Todos ${replaceAll ? 'Synced' : 'Added'} Successfully!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `${replaceAll ? 'Synced' : 'Added'} ${todos?.length || 0} todos\\n` +\r\n `${replaceAll ? '' : 'āž• Added to existing todo list\\n'}` +\r\n `\\nšŸ“ Todo list updated and tracked for progress monitoring!`\r\n }]\r\n };\r\n }\r\n \r\n case 'add-follow-up-todos': {\r\n const { aiSessionId, newTodos, followUpReason } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n if (newTodos && newTodos.length > 0) {\r\n // Get current max sequence order\r\n const { data: maxTodo } = await supabase\r\n .from('ai_todos')\r\n .select('sequence_order')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order', { ascending: false })\r\n .limit(1)\r\n .single();\r\n const startSequence = (maxTodo?.sequence_order || 0) + 1;\r\n \r\n const todoInserts = newTodos.map((todo: any, index: number) => ({\r\n ai_session_id: session.id,\r\n content: `[Follow-up] ${todo.content}`,\r\n status: todo.status || 'pending',\r\n estimated_minutes: todo.estimatedMinutes || null,\r\n sequence_order: startSequence + index\r\n }));\r\n \r\n const { error: insertError } = await supabase\r\n .from('ai_todos')\r\n .insert(todoInserts);\r\n \r\n if (insertError) throw insertError;\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `āœ… **Follow-up Todos Added Successfully!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Added ${newTodos?.length || 0} new todos from follow-up\\n` +\r\n `${followUpReason ? `Reason: ${followUpReason}\\n` : ''}` +\r\n `\\nšŸ“ New tasks identified and added to existing workflow!`\r\n }]\r\n };\r\n }\r\n \r\n case 'update-session-status': {\r\n const { aiSessionId, status, actualTimeMinutes, completionNotes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find and update the session\r\n // First find the session\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: findError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (findError) {\r\n throw new Error(`Database error: ${findError.message}`);\r\n }\r\n \r\n const foundSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!foundSession) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Now update the found session\r\n const { data, error } = await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: status,\r\n actual_time_minutes: actualTimeMinutes || null,\r\n completed_at: status === 'completed' ? new Date().toISOString() : null\r\n })\r\n .eq('id', foundSession.id)\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸŽÆ **Session Status Updated!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Status: ${status}\\n` +\r\n `${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes\\n` : ''}` +\r\n `${status === 'completed' ? `āœ… Session completed successfully!\\n` : ''}` +\r\n `${completionNotes ? `Notes: ${completionNotes}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-completion-context': {\r\n const { aiSessionId, includeFollowUps = true, includeTimeMetrics = true, includeTodos = true } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session data with ticket info\r\n // Get comprehensive session context - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select(`\r\n id,\r\n ticket_id,\r\n ai_time_estimate_minutes,\r\n actual_time_minutes,\r\n efficiency_score,\r\n created_at,\r\n completed_at,\r\n status,\r\n complexity_score\r\n `)\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Get ticket data\r\n const { data: ticket, error: ticketError } = await supabase\r\n .from('tickets')\r\n .select('ticket_number, title, description, type, priority')\r\n .eq('id', session.ticket_id)\r\n .single();\r\n \r\n if (ticketError || !ticket) {\r\n throw new Error('Ticket not found for session');\r\n }\r\n \r\n let contextData: any = {\r\n session: {\r\n id: aiSessionId,\r\n status: session.status,\r\n complexity: session.complexity_score,\r\n createdAt: session.created_at,\r\n completedAt: session.completed_at\r\n },\r\n ticket: {\r\n number: ticket.ticket_number,\r\n title: ticket.title,\r\n description: ticket.description,\r\n type: ticket.type,\r\n priority: ticket.priority\r\n }\r\n };\r\n \r\n // Add time metrics if requested\r\n if (includeTimeMetrics) {\r\n const timeSaved = session.ai_time_estimate_minutes && session.actual_time_minutes \r\n ? Math.max(0, session.ai_time_estimate_minutes - session.actual_time_minutes)\r\n : null;\r\n \r\n contextData.timeMetrics = {\r\n estimatedMinutes: session.ai_time_estimate_minutes,\r\n actualMinutes: session.actual_time_minutes,\r\n timeSaved: timeSaved,\r\n efficiency: session.efficiency_score,\r\n sessionDuration: session.completed_at && session.created_at \r\n ? Math.round((new Date(session.completed_at).getTime() - new Date(session.created_at).getTime()) / 60000)\r\n : null\r\n };\r\n }\r\n \r\n // Add todos if requested\r\n if (includeTodos) {\r\n const { data: todos } = await supabase\r\n .from('ai_todos')\r\n .select('content, status, estimated_minutes, actual_minutes, completed_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at', { ascending: true });\r\n \r\n contextData.todos = todos || [];\r\n }\r\n \r\n // Add follow-ups if requested\r\n if (includeFollowUps) {\r\n const { data: followUps } = await supabase\r\n .from('manual_follow_ups')\r\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at', { ascending: true });\r\n \r\n contextData.followUps = followUps || [];\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸ“‹ **Completion Context Retrieved!**\\n\\n` +\r\n `šŸŽ« **Ticket:** ${ticket.ticket_number} - ${ticket.title}\\n` +\r\n `šŸ†” **Session:** ${aiSessionId} (${session.status})\\n` +\r\n `ā±ļø **Time:** ${session.actual_time_minutes || 'N/A'}/${session.ai_time_estimate_minutes || 'N/A'} minutes\\n` +\r\n `šŸ“‹ **Todos:** ${contextData.todos?.filter((t: any) => t.status === 'completed').length || 0}/${contextData.todos?.length || 0} completed\\n` +\r\n `šŸ”„ **Follow-ups:** ${contextData.followUps?.length || 0}\\n\\n` +\r\n `āœ… **Full context ready for Cursor AI to generate customer response!**\\n\\n` +\r\n `**Context Data:**\\n\\`\\`\\`json\\n${JSON.stringify(contextData, null, 2)}\\`\\`\\``\r\n }]\r\n };\r\n }\r\n \r\n case 'save-customer-response': {\r\n const { aiSessionId, customerResponse, responseType = 'completion' } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session to validate it exists - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Save the response in database\r\n const { data: responseData, error: responseError } = await supabase\r\n .from('ai_responses')\r\n .insert({\r\n ai_session_id: session.id,\r\n response_type: responseType,\r\n content: customerResponse,\r\n is_ready_for_customer: true,\r\n provider_approved: false // Needs manual approval\r\n })\r\n .select()\r\n .single();\r\n \r\n if (responseError) throw responseError;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šŸ’¾ **Customer Response Saved!**\\n\\n` +\r\n `šŸ†” Session: ${aiSessionId}\\n` +\r\n `šŸ“ Response Type: ${responseType}\\n` +\r\n `šŸ“„ Length: ${customerResponse.length} characters\\n\\n` +\r\n `āœ… **Response ready for provider approval**\\n` +\r\n `šŸ” Provider can review in AI tab before sending to customer\\n\\n` +\r\n `**Preview:**\\n\\`\\`\\`\\n${customerResponse.substring(0, 200)}${customerResponse.length > 200 ? '...' : ''}\\`\\`\\``\r\n }]\r\n };\r\n }\r\n \r\n case 'complete-ai-session': {\r\n const { aiSessionId, workCompleted, technicalSummary, invoiceDescription, efficiencyNotes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session to calculate actual time spent - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: getSessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\r\n .in('team_id', teamIds);\r\n \r\n if (getSessionError) {\r\n throw new Error(`Database error: ${getSessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const existingSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!existingSession) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n\r\n // Calculate actual time spent automatically\r\n const completionTime = new Date();\r\n const sessionStartTime = new Date(existingSession.created_at);\r\n const timeSpentMinutes = Math.round((completionTime.getTime() - sessionStartTime.getTime()) / 60000);\r\n \r\n // Update session to completed with calculated time\r\n const { data: session, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: 'completed',\r\n actual_time_minutes: timeSpentMinutes,\r\n completed_at: completionTime.toISOString(),\r\n efficiency_score: null // Will be calculated\r\n })\r\n .eq('id', existingSession.id)\r\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\r\n .single();\r\n \r\n if (sessionError || !session) {\r\n throw new Error(`Failed to update session: ${aiSessionId}`);\r\n }\r\n \r\n // Calculate efficiency score\r\n const efficiencyScore = session.ai_time_estimate_minutes \r\n ? (timeSpentMinutes / session.ai_time_estimate_minutes)\r\n : 1.0;\r\n \r\n // Update efficiency score\r\n await supabase\r\n .from('ai_sessions')\r\n .update({ efficiency_score: efficiencyScore.toFixed(2) })\r\n .eq('id', session.id);\r\n \r\n // Get session duration\r\n const sessionDuration = Math.round(\r\n (completionTime.getTime() - new Date(session.created_at).getTime()) / 60000\r\n );\r\n \r\n // Create work summary\r\n const workSummary = `Completed ${workCompleted.length} tasks including: ${workCompleted.slice(0, 3).join(', ')}${workCompleted.length > 3 ? ' and more' : ''}.`;\r\n \r\n // Get ticket details for agenda event creation\r\n const { data: ticketInfo } = await supabase\r\n .from('tickets')\r\n .select('ticket_number, title, project_id')\r\n .eq('id', session.ticket_id)\r\n .single();\r\n \r\n // CREATE AGENDA EVENT: Now that work is complete, create the timetrack entry\r\n // Use invoice description if provided, otherwise create a technical one\r\n let completionDescription: string;\r\n \r\n if (invoiceDescription) {\r\n // Use the invoice-friendly description provided by Cursor (in ticket language)\r\n completionDescription = `${ticketInfo?.ticket_number || 'Ticket'}: ${invoiceDescription}`;\r\n } else {\r\n // Fallback: Create a technical work description\r\n const workDescription = workCompleted.map((task: string, index: number) => `${index + 1}. ${task}`).join('\\n');\r\n completionDescription = `${ticketInfo?.ticket_number || 'Ticket'}: ${technicalSummary || workSummary}\\n\\nCompleted work:\\n${workDescription}`;\r\n }\r\n \r\n // Create the agenda event with AI estimated time\r\n // Use the original AI estimate for billing, not the actual AI completion time\r\n const estimatedMinutes = session.ai_time_estimate_minutes || timeSpentMinutes;\r\n const sessionStart = new Date(session.created_at);\r\n const estimatedEnd = new Date(sessionStart.getTime() + estimatedMinutes * 60000);\r\n \r\n const { data: agendaEvent, error: agendaError } = await supabase\r\n .from('agenda_events')\r\n .insert({\r\n team_id: authContext.teamId,\r\n user_id: authContext.userId,\r\n title: ticketInfo?.title || 'Development Work',\r\n description: completionDescription,\r\n start_time: sessionStart.toISOString(),\r\n end_time: estimatedEnd.toISOString(),\r\n project_id: ticketInfo?.project_id || null,\r\n ticket_id: session.ticket_id,\r\n ai_session_id: session.id, // Use the actual UUID, not the readable ID\r\n type: 'work',\r\n status: 'draft', // Mark as draft for manual approval\r\n all_day: false,\r\n is_tracked: true,\r\n tracked_duration: estimatedMinutes * 60 // Use AI estimate in seconds for billing\r\n })\r\n .select('id')\r\n .single();\r\n \r\n if (agendaError) {\r\n console.error('āš ļø Failed to create agenda event:', agendaError);\r\n // Don't fail the completion if agenda event creation fails\r\n }\r\n \r\n let responseText = `šŸŽ‰ **AI Session Completed Successfully!**\\n\\n`;\r\n responseText += `šŸ†” Session: ${aiSessionId}\\n`;\r\n responseText += `šŸ“Š **Performance Summary:**\\n`;\r\n responseText += ` • Tasks Completed: ${workCompleted.length}\\n`;\r\n responseText += ` • Time Spent: ${timeSpentMinutes} minutes\\n`;\r\n responseText += ` • Estimated Time: ${session.ai_time_estimate_minutes || 'N/A'} minutes\\n`;\r\n responseText += ` • Efficiency: ${efficiencyScore < 1 ? 'šŸš€' : efficiencyScore > 1.5 ? 'āš ļø' : 'ā±ļø'} ${(efficiencyScore * 100).toFixed(0)}%\\n`;\r\n responseText += ` • Session Duration: ${sessionDuration} minutes\\n\\n`;\r\n \r\n responseText += `āœ… **Work Completed:**\\n`;\r\n workCompleted.forEach((task: string, index: number) => {\r\n responseText += `${index + 1}. ${task}\\n`;\r\n });\r\n responseText += `\\n`;\r\n \r\n if (technicalSummary) {\r\n responseText += `šŸ”§ **Technical Summary:**\\n${technicalSummary}\\n\\n`;\r\n }\r\n \r\n if (efficiencyNotes) {\r\n responseText += `šŸ“ˆ **Efficiency Notes:**\\n${efficiencyNotes}\\n\\n`;\r\n }\r\n \r\n if (agendaEvent) {\r\n responseText += `šŸ“… **Timetrack Entry Created:**\\n`;\r\n responseText += ` • Agenda event created with work summary\\n`;\r\n responseText += ` • Status: DRAFT (requires approval in agenda)\\n`;\r\n responseText += ` • Duration: ${timeSpentMinutes} minutes\\n`;\r\n responseText += ` • Period: ${sessionStart.toLocaleString()} - ${completionTime.toLocaleString()}\\n\\n`;\r\n }\r\n \r\n // Provide context for Cursor AI to generate customer response\r\n responseText += `šŸ“‹ **Context for Customer Response:**\\n`;\r\n responseText += ` • Use \"get-completion-context\" to retrieve full context\\n`;\r\n responseText += ` • Generate customer-friendly response based on completed work\\n`;\r\n responseText += ` • Focus on business value and customer benefits\\n\\n`;\r\n \r\n responseText += `šŸŽÆ **Session archived successfully!**`;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: responseText\r\n }]\r\n };\r\n }\r\n \r\n case 'log-hours': {\r\n const { projectId, workDescription, estimatedHours, chatContextSummary } = args as any;\r\n \r\n let project = null;\r\n \r\n // Verify project access if projectId is provided\r\n if (projectId) {\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: projectData, error: projectError } = await supabase\r\n .from('projects')\r\n .select('id, name, team_id')\r\n .eq('id', projectId)\r\n .in('team_id', teamIds)\r\n .single();\r\n \r\n if (projectError || !projectData) {\r\n throw new Error(`Project not found or no access: ${projectId}. Please call get-projects first to find the correct project.`);\r\n }\r\n \r\n project = projectData;\r\n }\r\n \r\n // Convert hours to seconds for tracker_entries.duration\r\n const durationSeconds = Math.round(estimatedHours * 3600);\r\n \r\n // Create tracker entry as draft\r\n const now = new Date();\r\n const startTime = new Date(now.getTime() - durationSeconds * 1000); // Back-calculate start time\r\n \r\n const { data: trackerEntry, error: trackerError } = await supabase\r\n .from('tracker_entries')\r\n .insert({\r\n team_id: authContext.teamId,\r\n assigned_id: authContext.userId,\r\n project_id: project?.id || null,\r\n description: workDescription,\r\n duration: durationSeconds,\r\n start: startTime.toISOString(),\r\n stop: now.toISOString(),\r\n date: now.toISOString().split('T')[0],\r\n billed: false\r\n })\r\n .select('id, duration, project_id')\r\n .single();\r\n \r\n if (trackerError || !trackerEntry) {\r\n throw new Error(`Failed to create tracker entry: ${trackerError?.message || 'Unknown error'}`);\r\n }\r\n \r\n let responseText = `ā±ļø **Hours Logged Successfully!**\\n\\n`;\r\n responseText += `šŸ“‹ **Entry Details:**\\n`;\r\n if (project) {\r\n responseText += ` • Project: ${project.name}\\n`;\r\n } else {\r\n responseText += ` • Project: (No project assigned)\\n`;\r\n }\r\n responseText += ` • Description: ${workDescription}\\n`;\r\n responseText += ` • Estimated Hours: ${estimatedHours}h (${Math.floor(estimatedHours)}h ${Math.round((estimatedHours % 1) * 60)}m)\\n`;\r\n responseText += ` • Status: DRAFT (not billed yet)\\n`;\r\n responseText += ` • Entry ID: ${trackerEntry.id}\\n\\n`;\r\n \r\n if (chatContextSummary) {\r\n responseText += `šŸ“Š **Work Context:**\\n`;\r\n responseText += `${chatContextSummary.substring(0, 200)}${chatContextSummary.length > 200 ? '...' : ''}\\n\\n`;\r\n }\r\n \r\n responseText += `āœ… Time entry created and ready for review in the tracker!`;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: responseText\r\n }]\r\n };\r\n }\r\n \r\n default:\r\n throw new Error(`Unknown tool: ${name}`);\r\n }\r\n \r\n } catch (error) {\r\n console.error(`āŒ Tool execution error:`, error);\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Error executing ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n }]\r\n };\r\n }\r\n});\r\n\r\n// Resource read handler\r\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n if (!authContext) {\r\n return {\r\n contents: [{\r\n uri: request.params.uri,\r\n mimeType: 'text/plain',\r\n text: 'Error: Not authenticated. API key validation failed.'\r\n }]\r\n };\r\n }\r\n\r\n const { uri } = request.params;\r\n console.error(`šŸ“š Reading resource: ${uri}`);\r\n \r\n try {\r\n switch (uri) {\r\n case 'tickets://recent': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('tickets')\r\n .select(`\r\n id,\r\n ticket_number,\r\n title,\r\n status,\r\n priority,\r\n created_at\r\n `)\r\n .in('team_id', teamIds)\r\n .order('created_at', { ascending: false })\r\n .limit(20);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n case 'customers://all': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('customers')\r\n .select('id, name, email, website, created_at')\r\n .in('team_id', teamIds)\r\n .order('name')\r\n .limit(50);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n case 'projects://active': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('projects')\r\n .select(`\r\n id,\r\n name,\r\n description,\r\n status,\r\n created_at,\r\n customers:customer_id(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .eq('status', 'active')\r\n .order('name')\r\n .limit(50);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n default:\r\n throw new Error(`Unknown resource: ${uri}`);\r\n }\r\n \r\n } catch (error) {\r\n console.error(`āŒ Resource read error:`, error);\r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'text/plain',\r\n text: `Error reading ${uri}: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n }]\r\n };\r\n }\r\n});\r\n\r\n// Main function\r\nasync function main() {\r\n console.error('šŸš€ Starting MG Tickets MCP Bridge Server...');\r\n console.error(`šŸ”‘ API Key: ${apiKey?.substring(0, 10)}...`);\r\n \r\n // Validate API key\r\n authContext = await validateApiKey(apiKey!);\r\n if (!authContext) {\r\n console.error('āŒ API key validation failed. Please check your key and try again.');\r\n process.exit(1);\r\n }\r\n \r\n console.error(`āœ… Authenticated as user ${authContext.userId} in team ${authContext.teamId}`);\r\n console.error(`šŸ“‹ Available scopes: ${authContext.scopes.join(', ')}`);\r\n console.error('šŸ“” MCP Bridge Server ready for connections');\r\n \r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n}\r\n\r\n// Handle graceful shutdown\r\nprocess.on('SIGINT', async () => {\r\n console.error('šŸ‘‹ Shutting down MCP Bridge Server...');\r\n process.exit(0);\r\n});\r\n\r\nprocess.on('SIGTERM', async () => {\r\n console.error('šŸ‘‹ Shutting down MCP Bridge Server...');\r\n process.exit(0);\r\n});\r\n\r\n// Start the server\r\nmain().catch((error) => {\r\n console.error('šŸ’„ Fatal error:', error);\r\n process.exit(1);\r\n});"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["args","name"],"mappings":"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","file":"index.js","sourcesContent":["#!/usr/bin/env node\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { createClient } from '@supabase/supabase-js';\nimport { createHash } from 'crypto';\n\n// Parse command line arguments and environment\nconst args = process.argv.slice(2);\nconst apiKey = args.find(arg => arg.startsWith('--api-key='))?.split('=')[1] || process.env.MG_TICKETS_API_KEY;\n// Default to MG Software's Supabase for SaaS customers\nconst supabaseUrl = args.find(arg => arg.startsWith('--supabase-url='))?.split('=')[1] || \n process.env.SUPABASE_URL || \n 'https://cvjdbczxyczjnatuolsk.supabase.co';\n\nconst supabaseKey = args.find(arg => arg.startsWith('--supabase-key='))?.split('=')[1] || \n process.env.SUPABASE_SERVICE_ROLE_KEY || \n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN2amRiY3p4eWN6am5hdHVvbHNrIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc1NjE0NzcyNCwiZXhwIjoyMDcxNzIzNzI0fQ.LljuNdCZXDcSIVTeIVOSNsvGNBfWsIM1QIswBJmGXKE';\n\nif (!apiKey) {\n console.error('āŒ API key is required. Use --api-key=your_key or set MG_TICKETS_API_KEY environment variable');\n process.exit(1);\n}\n\n// Supabase credentials validation (optional with defaults)\nif (!supabaseUrl || !supabaseKey) {\n console.error('āŒ Supabase credentials missing. Using defaults for MG Software SaaS.');\n}\n\n// Initialize Supabase client with service role\nconst supabase = createClient(supabaseUrl, supabaseKey);\n\ninterface AuthContext {\n userId: string;\n teamId: string;\n scopes: string[];\n}\n\n// Smart time estimation and codebase analysis is now handled by Cursor AI\n// MCP bridge focuses on data storage and session management only\n\n// Helper function to get accessible team IDs (own team + child teams)\nasync function getAccessibleTeamIds(teamId: string): Promise<string[]> {\n const { data: accessibleTeams } = await supabase\n .from('teams')\n .select('id')\n .or(`id.eq.${teamId},parent_team_id.eq.${teamId}`);\n \n return accessibleTeams?.map(t => t.id) || [teamId];\n}\n\n// API Key validation - direct database access\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\n if (!key.startsWith('mid_') || key.length !== 68) {\n console.error('šŸ”‘ Invalid API key format');\n return null;\n }\n\n try {\n // Hash the API key\n const keyHash = createHash('sha256').update(key).digest('hex');\n console.error(`šŸ” Validating API key hash: ${keyHash.substring(0, 16)}...`);\n \n // Query database for API key\n const { data: apiKeyData, error } = await supabase\n .from('api_keys')\n .select('id, user_id, team_id, scopes, last_used_at')\n .eq('key_hash', keyHash)\n .single();\n\n if (error || !apiKeyData) {\n console.error('āŒ API key not found or invalid:', error?.message);\n return null;\n }\n\n // Update last used timestamp\n await supabase\n .from('api_keys')\n .update({ last_used_at: new Date().toISOString() })\n .eq('id', apiKeyData.id);\n\n console.error(`āœ… API key validated for user ${apiKeyData.user_id} in team ${apiKeyData.team_id}`);\n \n return {\n userId: apiKeyData.user_id,\n teamId: apiKeyData.team_id,\n scopes: apiKeyData.scopes || []\n };\n } catch (error) {\n console.error('šŸ’„ API key validation error:', error);\n return null;\n }\n}\n\n// Validate auth context once at startup\nlet authContext: AuthContext | null = null;\n\n// Helper function to check if a file is an image\nfunction isImageFile(mimeType: string): boolean {\n return mimeType.startsWith('image/') && \n ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'].includes(mimeType);\n}\n\n// Helper function to download and convert image to base64\nasync function downloadImageAsBase64(storageKey: string): Promise<string | null> {\n try {\n // Get signed URL for the file (1 hour expiry)\n const { data: urlData, error: urlError } = await supabase.storage\n .from('vault')\n .createSignedUrl(storageKey, 3600);\n \n if (urlError || !urlData?.signedUrl) {\n console.error(`Failed to create signed URL for ${storageKey}:`, urlError);\n return null;\n }\n \n // Download the file\n const response = await fetch(urlData.signedUrl);\n if (!response.ok) {\n console.error(`Failed to download file ${storageKey}: ${response.status}`);\n return null;\n }\n \n // Convert to base64\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n return buffer.toString('base64');\n } catch (error) {\n console.error(`Error downloading image ${storageKey}:`, error);\n return null;\n }\n}\n\n/**\n * Convert TipTap JSON format to plain text for timetrack/agenda display\n * @param description - The description in TipTap JSON format or plain text\n * @returns Plain text version of the description\n */\nfunction convertTipTapToPlainText(description?: string | null): string {\n if (!description) {\n return \"\";\n }\n\n // If it's already plain text, return as is\n if (!description.startsWith('{\"type\":\"doc\"')) {\n return description;\n }\n\n try {\n const parsed = JSON.parse(description);\n \n // Recursively extract text from TipTap JSON structure\n const extractText = (node: any): string => {\n if (!node) return \"\";\n\n // Text nodes contain the actual text\n if (node.type === \"text\") {\n return node.text || \"\";\n }\n\n // Handle hard breaks\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n\n // Handle mentions\n if (node.type === \"mention\") {\n return `@${node.attrs?.label || node.attrs?.id || \"\"}`;\n }\n\n // Handle ticket mentions\n if (node.type === \"ticketMention\") {\n return `#${node.attrs?.label || node.attrs?.id || \"\"}`;\n }\n\n // Handle images\n if (node.type === \"image\") {\n return \"[afbeelding]\";\n }\n\n // Process children recursively\n if (node.content && Array.isArray(node.content)) {\n const childrenText = node.content.map(extractText).join(\"\");\n \n // Add appropriate spacing based on node type\n switch (node.type) {\n case \"paragraph\":\n return childrenText + \"\\n\";\n case \"heading\":\n return childrenText + \"\\n\\n\";\n case \"listItem\":\n return \"• \" + childrenText + \"\\n\";\n case \"blockquote\":\n return \"> \" + childrenText + \"\\n\";\n default:\n return childrenText;\n }\n }\n \n // For nodes without content (like empty paragraphs without content array)\n if (node.type === \"paragraph\") {\n return \"\\n\";\n }\n\n return \"\";\n };\n\n const plainText = extractText(parsed);\n return plainText.trim();\n } catch (error) {\n // If parsing fails, return original string\n return description;\n }\n}\n\n// MCP Server setup\nconst server = new Server(\n {\n name: 'mg-tickets-mcp-bridge',\n version: '2.0.0',\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n }\n);\n\n// Available tools definition\nconst TOOLS = [\n {\n name: 'get-tickets',\n description: 'Get tickets with optional filtering by status, priority, project, customer, or search query',\n inputSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'] },\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\n projectId: { type: 'string' },\n customerId: { type: 'string' },\n q: { type: 'string', description: 'Search query for title or description' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'get-ticket-by-id',\n description: 'Get a specific ticket by its ID, including all attachments, comments, and images. Images from ticket attachments and comment attachments are automatically downloaded and returned as base64-encoded content that can be analyzed by AI.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Ticket ID' }\n },\n required: ['id']\n }\n },\n {\n name: 'create-ticket',\n description: 'Create a new ticket',\n inputSchema: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Ticket title' },\n description: { type: 'string' },\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'], default: 'open' },\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },\n type: { type: 'string', enum: ['task', 'bug', 'feature', 'support', 'question', 'improvement'], default: 'task' },\n projectId: { type: 'string' },\n customerId: { type: 'string' }\n },\n required: ['title']\n }\n },\n {\n name: 'get-customers',\n description: 'Get customers with optional search',\n inputSchema: {\n type: 'object',\n properties: {\n q: { type: 'string', description: 'Search query for customer name or email' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'create-customer',\n description: 'Create a new customer',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Customer name' },\n email: { type: 'string' },\n website: { type: 'string' }\n },\n required: ['name']\n }\n },\n {\n name: 'get-projects',\n description: 'Get projects with optional filtering',\n inputSchema: {\n type: 'object',\n properties: {\n customerId: { type: 'string', description: 'Filter by customer ID' },\n q: { type: 'string', description: 'Search query for project name' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'create-project',\n description: 'Create a new project',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Project name' },\n description: { type: 'string' },\n customerId: { type: 'string' },\n status: { type: 'string', enum: ['active', 'on_hold', 'completed', 'cancelled'], default: 'active' }\n },\n required: ['name']\n }\n },\n // === NEW AI SESSION TOOLS ===\n {\n name: 'start-ai-session-smart',\n description: 'Start a new AI development session with automatic tracking (time breakdown provided by Cursor AI)',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: { type: 'string' },\n ticketUrl: { type: 'string', description: 'URL to the ticket' },\n cursorSessionId: { type: 'string', description: 'Cursor session identifier' },\n codebaseContext: { \n type: 'array', \n items: { type: 'string' },\n description: 'Relevant files for complexity analysis'\n },\n timeBreakdown: {\n type: 'object',\n description: 'Time estimate breakdown by development phase (REQUIRED)',\n properties: {\n analysisMinutes: { type: 'number', description: 'Ticket/context analysis time' },\n investigationMinutes: { type: 'number', description: 'Bug investigation/reproduction (0 if not a bug)' },\n developmentMinutes: { type: 'number', description: 'Actual coding/fixing time' },\n communicationMinutes: { type: 'number', description: 'Customer response writing time' }\n },\n required: ['analysisMinutes', 'investigationMinutes', 'developmentMinutes', 'communicationMinutes']\n },\n complexityScore: {\n type: 'number',\n minimum: 1,\n maximum: 10,\n description: 'Estimated complexity from 1-10'\n }\n },\n required: ['ticketId', 'timeBreakdown']\n }\n },\n {\n name: 'track-manual-follow-up',\n description: 'Track manual follow-up prompt by developer',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n originalPrompt: { type: 'string' },\n aiResponse: { type: 'string' },\n developerFollowUp: { type: 'string' },\n followUpReason: { \n type: 'string', \n enum: ['incomplete_result', 'wrong_approach', 'needs_clarification', 'error_in_code']\n },\n outcome: {\n type: 'string',\n enum: ['success', 'partial_success', 'still_failed'],\n default: 'success'\n },\n timeSpentMinutes: { type: 'number' }\n },\n required: ['aiSessionId', 'originalPrompt', 'aiResponse', 'developerFollowUp', 'followUpReason']\n }\n },\n {\n name: 'get-session-context',\n description: 'Get current session context for follow-up continuity',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n includeTicketData: { type: 'boolean', default: true },\n includeTodoProgress: { type: 'boolean', default: true },\n includeFollowUpHistory: { type: 'boolean', default: false }\n },\n required: ['aiSessionId']\n }\n },\n {\n name: 'sync-session-todos',\n description: 'Synchronize todo list with AI session (replace existing) or add new todos',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n todos: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n todoId: { type: 'string', description: 'Optional external todo ID for tracking' },\n content: { type: 'string' },\n status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'] },\n estimatedMinutes: { type: 'number' }\n },\n required: ['content', 'status']\n }\n },\n replaceAll: { \n type: 'boolean', \n default: true, \n description: 'If true, replace all existing todos. If false, add new todos to existing ones' \n }\n },\n required: ['aiSessionId', 'todos']\n }\n },\n {\n name: 'add-follow-up-todos',\n description: 'Add new todos from follow-up (without replacing existing ones)',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n newTodos: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n status: { type: 'string', enum: ['pending', 'in_progress'], default: 'pending' },\n estimatedMinutes: { type: 'number' },\n addedInFollowUp: { type: 'boolean', default: true }\n },\n required: ['content']\n }\n },\n followUpReason: { \n type: 'string', \n description: 'Why were these todos added in follow-up' \n }\n },\n required: ['aiSessionId', 'newTodos']\n }\n },\n {\n name: 'update-session-status',\n description: 'Update AI session status and completion info',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n status: {\n type: 'string',\n enum: ['started', 'in_progress', 'paused', 'completed', 'failed']\n },\n actualTimeMinutes: { type: 'number' },\n completionNotes: { type: 'string' }\n },\n required: ['aiSessionId', 'status']\n }\n },\n {\n name: 'get-completion-context',\n description: 'Get all context needed for Cursor AI to generate customer response',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n includeFollowUps: { type: 'boolean', default: true },\n includeTimeMetrics: { type: 'boolean', default: true },\n includeTodos: { type: 'boolean', default: true }\n },\n required: ['aiSessionId']\n }\n },\n {\n name: 'save-customer-response',\n description: 'Save customer response generated by Cursor AI',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n customerResponse: { type: 'string', description: 'Customer response generated by Cursor AI' },\n responseType: { \n type: 'string', \n enum: ['completion', 'progress_update', 'needs_clarification'],\n default: 'completion'\n }\n },\n required: ['aiSessionId', 'customerResponse']\n }\n },\n {\n name: 'complete-ai-session',\n description: 'Complete AI session with work summary - time calculated automatically',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n workCompleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of completed tasks/todos in English'\n },\n technicalSummary: {\n type: 'string',\n description: 'Technical summary of work done in English'\n },\n invoiceDescription: {\n type: 'string',\n description: 'Short invoice-friendly description in the language of the ticket (2-3 sentences max, suitable for billing)'\n },\n efficiencyNotes: { type: 'string' }\n },\n required: ['aiSessionId', 'workCompleted']\n }\n },\n {\n name: 'log-hours',\n description: 'Analyze current chat conversation and log hours as draft tracker entry. AI analyzes chat context to estimate hours as a senior developer would (without AI assistance). Cursor AI matches workspace name to correct project from list (optional).',\n inputSchema: {\n type: 'object',\n properties: {\n projectId: {\n type: 'string',\n description: 'Project ID (UUID) - Optional. Cursor AI should call get-projects first to try matching workspace name. If no clear match, omit this field.'\n },\n workDescription: {\n type: 'string',\n description: 'Short description of the work done (for the tracker entry)'\n },\n estimatedHours: {\n type: 'number',\n description: 'AI-estimated hours as senior developer would spend WITHOUT AI (e.g., 2.5 for 2.5 hours)'\n },\n chatContextSummary: {\n type: 'string',\n description: 'Brief summary of chat context for internal logging (optional)'\n }\n },\n required: ['workDescription', 'estimatedHours']\n }\n }\n];\n\n// Available resources\nconst RESOURCES = [\n {\n uri: 'tickets://recent',\n name: 'Recent Tickets',\n description: 'Most recently created tickets',\n mimeType: 'application/json'\n },\n {\n uri: 'customers://all',\n name: 'All Customers', \n description: 'Complete customer directory',\n mimeType: 'application/json'\n },\n {\n uri: 'projects://active',\n name: 'Active Projects',\n description: 'Currently active projects',\n mimeType: 'application/json'\n }\n];\n\n// List tools handler\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n});\n\n// List resources handler\nserver.setRequestHandler(ListResourcesRequestSchema, async () => {\n return { resources: RESOURCES };\n});\n\n// Tool execution handler\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (!authContext) {\n return {\n content: [{ type: 'text', text: 'Error: Not authenticated. API key validation failed.' }],\n };\n }\n\n const { name, arguments: args } = request.params;\n console.error(`šŸ› ļø Executing tool: ${name} for team ${authContext.teamId}`);\n \n try {\n switch (name) {\n case 'get-tickets': {\n const { status, priority, projectId, customerId, q, pageSize = 20 } = args as any;\n \n // Get all accessible team IDs (own team + child teams)\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n \n let query = supabase\n .from('tickets')\n .select(`\n id,\n ticket_number,\n title,\n description,\n status,\n priority,\n type,\n created_at,\n project_id,\n customer_id,\n projects:project_id(id, name),\n customers:customer_id(id, name)\n `)\n .in('team_id', teamIds)\n .limit(Math.min(pageSize, 100));\n \n if (status) query = query.eq('status', status);\n if (priority) query = query.eq('priority', priority);\n if (projectId) query = query.eq('project_id', projectId);\n if (customerId) query = query.eq('customer_id', customerId);\n if (q) query = query.or(`title.ilike.%${q}%,description.ilike.%${q}%`);\n \n const { data, error } = await query.order('created_at', { ascending: false });\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} tickets:\\n\\n${data?.map(ticket => \n `**${ticket.ticket_number}**: ${ticket.title}\\n` +\n `Status: ${ticket.status} | Priority: ${ticket.priority}\\n` +\n `${(ticket.projects as any)?.name ? `Project: ${(ticket.projects as any).name}\\n` : ''}` +\n `${(ticket.customers as any)?.name ? `Customer: ${(ticket.customers as any).name}\\n` : ''}` +\n `Created: ${new Date(ticket.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No tickets found.'}`\n }]\n };\n }\n \n case 'get-ticket-by-id': {\n const { id } = args as any;\n \n // Get ticket data - include tickets from provider's team AND child customer teams\n const { data: ticketData, error } = await supabase\n .from('tickets')\n .select(`\n *,\n projects:project_id(id, name),\n customers:customer_id(id, name),\n assignee:assignee_id(id, full_name, email),\n requester:requester_id(id, full_name, email)\n `)\n .eq('id', id)\n .single();\n \n if (error) throw error;\n \n // Check if user has access to this ticket (own team or child team)\n const { data: teamAccess } = await supabase\n .from('teams')\n .select('id')\n .or(`id.eq.${ticketData.team_id},parent_team_id.eq.${authContext.teamId}`)\n .eq('id', ticketData.team_id)\n .single();\n \n if (!teamAccess && ticketData.team_id !== authContext.teamId) {\n throw new Error('Access denied: You do not have permission to view this ticket');\n }\n \n const data = ticketData;\n \n // Get ticket attachments (no team filter needed - already validated ticket access)\n const { data: attachments, error: attachmentsError } = await supabase\n .from('ticket_attachments')\n .select(`\n id,\n file_name,\n file_size,\n mime_type,\n storage_key,\n created_at,\n users:user_id(id, full_name)\n `)\n .eq('ticket_id', id)\n .order('created_at', { ascending: true });\n \n if (attachmentsError) {\n console.error('Error fetching attachments:', attachmentsError);\n }\n \n // Get ticket comments\n const { data: comments, error: commentsError } = await supabase\n .from('ticket_comments')\n .select(`\n id,\n content,\n created_at,\n users:user_id(id, full_name)\n `)\n .eq('ticket_id', id)\n .order('created_at', { ascending: true });\n \n if (commentsError) {\n console.error('Error fetching comments:', commentsError);\n }\n \n // Get comment attachments (no team filter needed - already validated ticket access)\n const commentIds = comments?.map(c => c.id) || [];\n let commentAttachments: any[] = [];\n \n if (commentIds.length > 0) {\n const { data: commAttachments, error: commAttachmentsError } = await supabase\n .from('ticket_comment_attachments')\n .select(`\n id,\n comment_id,\n file_name,\n file_size,\n mime_type,\n storage_key,\n created_at\n `)\n .in('comment_id', commentIds);\n \n if (commAttachmentsError) {\n console.error('Error fetching comment attachments:', commAttachmentsError);\n } else {\n commentAttachments = commAttachments || [];\n }\n }\n \n // Build content array starting with text\n const content: any[] = [{\n type: 'text',\n text: `**Ticket Details:**\\n\\n` +\n `**${data.ticket_number}**: ${data.title}\\n` +\n `Status: ${data.status}\\n` +\n `Priority: ${data.priority}\\n` +\n `Type: ${data.type}\\n` +\n `${data.description ? `Description: ${data.description}\\n` : ''}` +\n `${(data.projects as any)?.name ? `Project: ${(data.projects as any).name}\\n` : ''}` +\n `${(data.customers as any)?.name ? `Customer: ${(data.customers as any).name}\\n` : ''}` +\n `${data.assignee?.full_name ? `Assignee: ${data.assignee.full_name}\\n` : ''}` +\n `Requester: ${data.requester?.full_name || 'Unknown'}\\n` +\n `Created: ${new Date(data.created_at).toLocaleDateString()}\\n` +\n `${attachments && attachments.length > 0 ? `\\nšŸ“Ž Attachments: ${attachments.length}\\n` : ''}` +\n `${comments && comments.length > 0 ? `šŸ’¬ Comments: ${comments.length}\\n` : ''}`\n }];\n \n // Process ticket attachments - download images\n if (attachments && attachments.length > 0) {\n console.error(`šŸ“Ž Processing ${attachments.length} ticket attachments...`);\n \n for (const attachment of attachments) {\n if (isImageFile(attachment.mime_type)) {\n console.error(`šŸ–¼ļø Downloading image: ${attachment.file_name}`);\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\n \n if (base64Data) {\n content.push({\n type: 'image',\n data: base64Data,\n mimeType: attachment.mime_type\n });\n \n // Add text context about the image\n content.push({\n type: 'text',\n text: `\\nšŸ“ø **Image from ticket**: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB, uploaded by ${(attachment.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()})\\n`\n });\n }\n }\n }\n }\n \n // Process comment attachments - download images\n if (commentAttachments.length > 0) {\n console.error(`šŸ“Ž Processing ${commentAttachments.length} comment attachments...`);\n \n for (const attachment of commentAttachments) {\n if (isImageFile(attachment.mime_type)) {\n console.error(`šŸ–¼ļø Downloading comment image: ${attachment.file_name}`);\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\n \n if (base64Data) {\n // Find the comment this attachment belongs to\n const comment = comments?.find(c => c.id === attachment.comment_id);\n \n content.push({\n type: 'image',\n data: base64Data,\n mimeType: attachment.mime_type\n });\n \n // Add text context about the image\n content.push({\n type: 'text',\n text: `\\nšŸ“ø **Image from comment** by ${(comment?.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()}: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB)\\n` +\n (comment?.content ? `Comment text: \"${comment.content.substring(0, 100)}${comment.content.length > 100 ? '...' : ''}\"\\n` : '')\n });\n }\n }\n }\n }\n \n console.error(`āœ… Returning ticket with ${content.filter(c => c.type === 'image').length} images`);\n \n return { content };\n }\n \n case 'create-ticket': {\n const { title, description, status = 'open', priority = 'medium', type = 'task', projectId, customerId } = args as any;\n \n // Generate ticket number\n const year = new Date().getFullYear();\n const { count } = await supabase\n .from('tickets')\n .select('*', { count: 'exact', head: true })\n .eq('team_id', authContext.teamId);\n \n const ticketNumber = `${year}-${String((count || 0) + 1).padStart(3, '0')}`;\n \n const { data, error } = await supabase\n .from('tickets')\n .insert({\n team_id: authContext.teamId,\n ticket_number: ticketNumber,\n title,\n description,\n status,\n priority,\n type,\n project_id: projectId || null,\n customer_id: customerId || null,\n requester_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `āœ… **Ticket Created Successfully!**\\n\\n` +\n `Ticket Number: **${ticketNumber}**\\n` +\n `Title: ${title}\\n` +\n `Status: ${status}\\n` +\n `Priority: ${priority}\\n` +\n `Type: ${type}\\n`\n }]\n };\n }\n \n case 'get-customers': {\n const { q, pageSize = 20 } = args as any;\n \n // Get all accessible team IDs (own team + child teams)\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n \n let query = supabase\n .from('customers')\n .select('id, name, email, website, created_at')\n .in('team_id', teamIds)\n .limit(Math.min(pageSize, 100));\n \n if (q) query = query.or(`name.ilike.%${q}%,email.ilike.%${q}%`);\n \n const { data, error } = await query.order('name');\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} customers:\\n\\n${data?.map(customer => \n `**${customer.name}**\\n` +\n `${customer.email ? `Email: ${customer.email}\\n` : ''}` +\n `${customer.website ? `Website: ${customer.website}\\n` : ''}` +\n `Created: ${new Date(customer.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No customers found.'}`\n }]\n };\n }\n \n case 'create-customer': {\n const { name, email, website } = args as any;\n \n const { data, error } = await supabase\n .from('customers')\n .insert({\n team_id: authContext.teamId,\n name,\n email: email || null,\n website: website || null,\n user_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `āœ… **Customer Created Successfully!**\\n\\n` +\n `Name: ${name}\\n` +\n `${email ? `Email: ${email}\\n` : ''}` +\n `${website ? `Website: ${website}\\n` : ''}`\n }]\n };\n }\n \n case 'get-projects': {\n const { customerId, q, pageSize = 20 } = args as any;\n \n // Get all accessible team IDs (own team + child teams)\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n \n let query = supabase\n .from('projects')\n .select(`\n id,\n name,\n description,\n customer_id,\n created_at\n `)\n .in('team_id', teamIds)\n .limit(Math.min(pageSize, 100));\n \n if (customerId) query = query.eq('customer_id', customerId);\n if (q) query = query.ilike('name', `%${q}%`);\n \n const { data, error } = await query.order('name');\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} projects:\\n\\n${data?.map(project => \n `**${project.name}** (ID: ${project.id})\\n` +\n `${project.description ? `Description: ${project.description}\\n` : ''}` +\n `Created: ${new Date(project.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No projects found.'}`\n }]\n };\n }\n \n case 'create-project': {\n const { name, description, customerId, status = 'active' } = args as any;\n \n const { data, error } = await supabase\n .from('projects')\n .insert({\n team_id: authContext.teamId,\n name,\n description: description || null,\n customer_id: customerId || null,\n status,\n user_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `āœ… **Project Created Successfully!**\\n\\n` +\n `Name: ${name}\\n` +\n `Status: ${status}\\n` +\n `${description ? `Description: ${description}\\n` : ''}`\n }]\n };\n }\n \n // === AI SESSION TOOLS ===\n case 'start-ai-session-smart': {\n const { ticketId, ticketUrl, cursorSessionId, codebaseContext, timeBreakdown, complexityScore } = args as any;\n \n // Validate timeBreakdown is provided\n if (!timeBreakdown || !timeBreakdown.analysisMinutes || timeBreakdown.developmentMinutes === undefined) {\n throw new Error('timeBreakdown is required with all phases: analysisMinutes, investigationMinutes, developmentMinutes, communicationMinutes');\n }\n \n // Calculate total time from breakdown\n const totalEstimateMinutes = \n (timeBreakdown.analysisMinutes || 0) +\n (timeBreakdown.investigationMinutes || 0) +\n (timeBreakdown.developmentMinutes || 0) +\n (timeBreakdown.communicationMinutes || 0);\n \n const sessionStartTime = new Date();\n \n // Create AI session with calculated total\n const { data: sessionData, error } = await supabase\n .from('ai_sessions')\n .insert({\n ticket_id: ticketId,\n provider_user_id: authContext.userId,\n team_id: authContext.teamId,\n cursor_session_id: cursorSessionId || null,\n ai_time_estimate_minutes: totalEstimateMinutes,\n complexity_score: complexityScore || null,\n status: 'in_progress'\n })\n .select('id, ticket_id, cursor_session_id, created_at')\n .single();\n \n if (error) throw error;\n \n // CREATE PHASE TIME LOGS: Store breakdown as separate phase activities\n const phaseActivities = [\n {\n ai_session_id: sessionData.id,\n activity_type: 'analysis',\n description: 'Ticket analysis and context understanding',\n duration_seconds: 0,\n estimated_duration_seconds: timeBreakdown.analysisMinutes * 60,\n status: 'in_progress', // Analysis starts immediately\n productivity_score: 8,\n started_at: sessionStartTime.toISOString()\n },\n {\n ai_session_id: sessionData.id,\n activity_type: 'bug_investigation',\n description: 'Bug investigation and root cause analysis',\n duration_seconds: 0,\n estimated_duration_seconds: timeBreakdown.investigationMinutes * 60,\n status: 'pending',\n productivity_score: null\n },\n {\n ai_session_id: sessionData.id,\n activity_type: 'development',\n description: 'Implementation and coding',\n duration_seconds: 0,\n estimated_duration_seconds: timeBreakdown.developmentMinutes * 60,\n status: 'pending',\n productivity_score: null\n },\n {\n ai_session_id: sessionData.id,\n activity_type: 'communication',\n description: 'Customer response and documentation',\n duration_seconds: 0,\n estimated_duration_seconds: timeBreakdown.communicationMinutes * 60,\n status: 'pending',\n productivity_score: null\n }\n ];\n \n // Insert all phase activities\n await supabase.from('ai_time_logs').insert(phaseActivities);\n \n // Generate a readable session ID for UI\n const sessionId = `ai-sess-${sessionData.id.substring(0, 8)}`;\n \n return {\n content: [{\n type: 'text',\n text: `šŸš€ **AI Session Started Successfully!**\\n\\n` +\n `šŸ†” Session ID: **${sessionId}**\\n` +\n `šŸŽ« Ticket: ${ticketId}\\n` +\n `\\nšŸ“Š **Time Breakdown:**\\n` +\n ` • Analysis: ${timeBreakdown.analysisMinutes} min\\n` +\n ` • Investigation: ${timeBreakdown.investigationMinutes} min\\n` +\n ` • Development: ${timeBreakdown.developmentMinutes} min\\n` +\n ` • Communication: ${timeBreakdown.communicationMinutes} min\\n` +\n ` • **Total: ${totalEstimateMinutes} min**\\n\\n` +\n `${complexityScore ? `šŸŽÆ Complexity: ${complexityScore}/10\\n` : ''}` +\n `ā±ļø **Phase Tracking Started** (Analysis in progress)\\n` +\n `${cursorSessionId ? `šŸ”— Cursor Session: ${cursorSessionId}\\n` : ''}` +\n `šŸ“… Started: ${sessionStartTime.toLocaleString()}\\n\\n` +\n `āœ… Session initialized with phase breakdown!\\n` +\n `šŸ“ Timetrack entry will be created when you complete the session.`\n }]\n };\n }\n \n case 'track-manual-follow-up': {\n const { aiSessionId, originalPrompt, aiResponse, developerFollowUp, followUpReason, outcome = 'success', timeSpentMinutes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the full session ID and current session data\n // Find the session - get all sessions for accessible teams and filter in JS\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id, status, created_at, ai_time_estimate_minutes')\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n const followUpTime = new Date();\n \n // RESTART SESSION: Set status back to in_progress for continued tracking\n await supabase\n .from('ai_sessions')\n .update({\n status: 'in_progress', // Restart active tracking\n // Don't update completed_at - session continues\n })\n .eq('id', session.id);\n \n // LOG FOLLOW-UP: Track the manual follow-up interaction\n const { data, error } = await supabase\n .from('manual_follow_ups')\n .insert({\n ai_session_id: session.id,\n developer_id: authContext.userId,\n team_id: authContext.teamId,\n original_prompt: originalPrompt,\n ai_response: aiResponse,\n follow_up_prompt: developerFollowUp,\n follow_up_reason: followUpReason,\n outcome: outcome,\n time_spent_minutes: timeSpentMinutes || null,\n resolved_at: outcome === 'success' ? new Date().toISOString() : null\n })\n .select()\n .single();\n \n if (error) throw error;\n \n // RESTART TIME TRACKING: Log follow-up activity start\n await supabase\n .from('ai_time_logs')\n .insert({\n ai_session_id: session.id,\n activity_type: 'debugging', // Follow-ups are typically debugging/fixing\n description: `Follow-up: ${followUpReason.replace('_', ' ')} - ${outcome}`,\n duration_seconds: (timeSpentMinutes || 0) * 60,\n productivity_score: outcome === 'success' ? 9 : outcome === 'partial_success' ? 6 : 4,\n started_at: followUpTime.toISOString()\n });\n \n // CALCULATE CURRENT EFFICIENCY: Compare time spent vs estimated\n const sessionStartTime = new Date(session.created_at);\n const totalMinutesElapsed = Math.round((followUpTime.getTime() - sessionStartTime.getTime()) / 60000);\n const estimatedMinutes = session.ai_time_estimate_minutes || 60;\n const currentEfficiency = totalMinutesElapsed > 0 ? (totalMinutesElapsed / estimatedMinutes) : 1;\n \n // UPDATE EFFICIENCY TRACKING: Update running efficiency score\n await supabase\n .from('ai_sessions')\n .update({\n efficiency_score: currentEfficiency.toFixed(2),\n actual_time_minutes: totalMinutesElapsed\n })\n .eq('id', session.id);\n \n return {\n content: [{\n type: 'text',\n text: `šŸ”„ **Follow-up Tracked & Session Restarted!**\\n\\n` +\n `šŸ†” Session: ${aiSessionId} (back to active)\\n` +\n `šŸ” Reason: ${followUpReason.replace('_', ' ')}\\n` +\n `āœ… Outcome: ${outcome}\\n` +\n `${timeSpentMinutes ? `ā±ļø Time spent: ${timeSpentMinutes} minutes\\n` : ''}` +\n `šŸ“Š **Current Progress:**\\n` +\n ` • Total time: ${totalMinutesElapsed} minutes\\n` +\n ` • Estimated: ${estimatedMinutes} minutes\\n` +\n ` • Efficiency: ${currentEfficiency < 1 ? 'šŸš€ ' : currentEfficiency > 1.5 ? 'āš ļø ' : 'ā±ļø '}${(currentEfficiency * 100).toFixed(0)}%\\n` +\n `\\n⚔ **Time tracking resumed** - continue with confidence!`\n }]\n };\n }\n \n case 'get-session-context': {\n const { aiSessionId, includeTicketData = true, includeTodoProgress = true, includeFollowUpHistory = false } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session data with related info - find by JavaScript filtering\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select(`\n id,\n ticket_id,\n status,\n ai_time_estimate_minutes,\n actual_time_minutes,\n complexity_score,\n created_at,\n cursor_session_id\n `)\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n \n if (sessionError || !session) {\n throw new Error(`Session not found: ${aiSessionId}`);\n }\n \n let context: any = {\n sessionId: aiSessionId,\n status: session.status,\n timeEstimate: session.ai_time_estimate_minutes,\n actualTime: session.actual_time_minutes,\n complexity: session.complexity_score,\n createdAt: session.created_at\n };\n \n // Include ticket data if requested\n if (includeTicketData) {\n const { data: ticket } = await supabase\n .from('tickets')\n .select('id, ticket_number, title, description, status, priority, type')\n .eq('id', session.ticket_id)\n .single();\n \n context.ticketData = ticket;\n }\n \n // Include todo progress if requested\n if (includeTodoProgress) {\n const { data: todos } = await supabase\n .from('ai_todos')\n .select('id, content, status, estimated_minutes, actual_minutes')\n .eq('ai_session_id', session.id)\n .order('sequence_order');\n \n context.todos = todos || [];\n context.todoProgress = {\n total: todos?.length || 0,\n completed: todos?.filter(t => t.status === 'completed').length || 0,\n inProgress: todos?.filter(t => t.status === 'in_progress').length || 0\n };\n }\n \n // Include follow-up history if requested\n if (includeFollowUpHistory) {\n const { data: followUps } = await supabase\n .from('manual_follow_ups')\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\n .eq('ai_session_id', session.id)\n .order('created_at');\n \n context.followUpHistory = followUps || [];\n }\n \n return {\n content: [{\n type: 'text',\n text: `šŸŽÆ **Session Context Retrieved**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Status: ${session.status}\\n` +\n `${context.ticketData ? `Ticket: ${context.ticketData.ticket_number} - ${context.ticketData.title}\\n` : ''}` +\n `${context.todoProgress ? `Todo Progress: ${context.todoProgress.completed}/${context.todoProgress.total} completed\\n` : ''}` +\n `${context.followUpHistory ? `Follow-ups: ${context.followUpHistory.length}\\n` : ''}` +\n `\\nšŸ“‹ Full context preserved for seamless continuation!`\n }]\n };\n }\n \n case 'sync-session-todos': {\n const { aiSessionId, todos, replaceAll = true } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the session - get all sessions for accessible teams and filter in JS\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // If replacing all, clear existing todos first\n if (replaceAll) {\n await supabase\n .from('ai_todos')\n .delete()\n .eq('ai_session_id', session.id);\n }\n \n if (todos && todos.length > 0) {\n // Get current max sequence order if adding to existing\n let startSequence = 0;\n if (!replaceAll) {\n const { data: maxTodo } = await supabase\n .from('ai_todos')\n .select('sequence_order')\n .eq('ai_session_id', session.id)\n .order('sequence_order', { ascending: false })\n .limit(1)\n .single();\n startSequence = (maxTodo?.sequence_order || 0) + 1;\n }\n \n const todoInserts = todos.map((todo: any, index: number) => ({\n ai_session_id: session.id,\n content: todo.content,\n status: todo.status,\n cursor_todo_id: todo.todoId || null,\n estimated_minutes: todo.estimatedMinutes || null,\n sequence_order: startSequence + index\n }));\n \n const { error: insertError } = await supabase\n .from('ai_todos')\n .insert(todoInserts);\n \n if (insertError) throw insertError;\n }\n \n return {\n content: [{\n type: 'text',\n text: `āœ… **Todos ${replaceAll ? 'Synced' : 'Added'} Successfully!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `${replaceAll ? 'Synced' : 'Added'} ${todos?.length || 0} todos\\n` +\n `${replaceAll ? '' : 'āž• Added to existing todo list\\n'}` +\n `\\nšŸ“ Todo list updated and tracked for progress monitoring!`\n }]\n };\n }\n \n case 'add-follow-up-todos': {\n const { aiSessionId, newTodos, followUpReason } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the session - get all sessions for accessible teams and filter in JS\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n if (newTodos && newTodos.length > 0) {\n // Get current max sequence order\n const { data: maxTodo } = await supabase\n .from('ai_todos')\n .select('sequence_order')\n .eq('ai_session_id', session.id)\n .order('sequence_order', { ascending: false })\n .limit(1)\n .single();\n const startSequence = (maxTodo?.sequence_order || 0) + 1;\n \n const todoInserts = newTodos.map((todo: any, index: number) => ({\n ai_session_id: session.id,\n content: `[Follow-up] ${todo.content}`,\n status: todo.status || 'pending',\n estimated_minutes: todo.estimatedMinutes || null,\n sequence_order: startSequence + index\n }));\n \n const { error: insertError } = await supabase\n .from('ai_todos')\n .insert(todoInserts);\n \n if (insertError) throw insertError;\n }\n \n return {\n content: [{\n type: 'text',\n text: `āœ… **Follow-up Todos Added Successfully!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Added ${newTodos?.length || 0} new todos from follow-up\\n` +\n `${followUpReason ? `Reason: ${followUpReason}\\n` : ''}` +\n `\\nšŸ“ New tasks identified and added to existing workflow!`\n }]\n };\n }\n \n case 'update-session-status': {\n const { aiSessionId, status, actualTimeMinutes, completionNotes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find and update the session\n // First find the session\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: findError } = await supabase\n .from('ai_sessions')\n .select('id')\n .in('team_id', teamIds);\n \n if (findError) {\n throw new Error(`Database error: ${findError.message}`);\n }\n \n const foundSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!foundSession) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Now update the found session\n const { data, error } = await supabase\n .from('ai_sessions')\n .update({\n status: status,\n actual_time_minutes: actualTimeMinutes || null,\n completed_at: status === 'completed' ? new Date().toISOString() : null\n })\n .eq('id', foundSession.id)\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `šŸŽÆ **Session Status Updated!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Status: ${status}\\n` +\n `${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes\\n` : ''}` +\n `${status === 'completed' ? `āœ… Session completed successfully!\\n` : ''}` +\n `${completionNotes ? `Notes: ${completionNotes}\\n` : ''}`\n }]\n };\n }\n \n case 'get-completion-context': {\n const { aiSessionId, includeFollowUps = true, includeTimeMetrics = true, includeTodos = true } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session data with ticket info\n // Get comprehensive session context - find by JavaScript filtering\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select(`\n id,\n ticket_id,\n ai_time_estimate_minutes,\n actual_time_minutes,\n efficiency_score,\n created_at,\n completed_at,\n status,\n complexity_score\n `)\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Get ticket data\n const { data: ticket, error: ticketError } = await supabase\n .from('tickets')\n .select('ticket_number, title, description, type, priority')\n .eq('id', session.ticket_id)\n .single();\n \n if (ticketError || !ticket) {\n throw new Error('Ticket not found for session');\n }\n \n let contextData: any = {\n session: {\n id: aiSessionId,\n status: session.status,\n complexity: session.complexity_score,\n createdAt: session.created_at,\n completedAt: session.completed_at\n },\n ticket: {\n number: ticket.ticket_number,\n title: ticket.title,\n description: ticket.description,\n type: ticket.type,\n priority: ticket.priority\n }\n };\n \n // Add time metrics if requested\n if (includeTimeMetrics) {\n const timeSaved = session.ai_time_estimate_minutes && session.actual_time_minutes \n ? Math.max(0, session.ai_time_estimate_minutes - session.actual_time_minutes)\n : null;\n \n contextData.timeMetrics = {\n estimatedMinutes: session.ai_time_estimate_minutes,\n actualMinutes: session.actual_time_minutes,\n timeSaved: timeSaved,\n efficiency: session.efficiency_score,\n sessionDuration: session.completed_at && session.created_at \n ? Math.round((new Date(session.completed_at).getTime() - new Date(session.created_at).getTime()) / 60000)\n : null\n };\n }\n \n // Add todos if requested\n if (includeTodos) {\n const { data: todos } = await supabase\n .from('ai_todos')\n .select('content, status, estimated_minutes, actual_minutes, completed_at')\n .eq('ai_session_id', session.id)\n .order('created_at', { ascending: true });\n \n contextData.todos = todos || [];\n }\n \n // Add follow-ups if requested\n if (includeFollowUps) {\n const { data: followUps } = await supabase\n .from('manual_follow_ups')\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\n .eq('ai_session_id', session.id)\n .order('created_at', { ascending: true });\n \n contextData.followUps = followUps || [];\n }\n \n return {\n content: [{\n type: 'text',\n text: `šŸ“‹ **Completion Context Retrieved!**\\n\\n` +\n `šŸŽ« **Ticket:** ${ticket.ticket_number} - ${ticket.title}\\n` +\n `šŸ†” **Session:** ${aiSessionId} (${session.status})\\n` +\n `ā±ļø **Time:** ${session.actual_time_minutes || 'N/A'}/${session.ai_time_estimate_minutes || 'N/A'} minutes\\n` +\n `šŸ“‹ **Todos:** ${contextData.todos?.filter((t: any) => t.status === 'completed').length || 0}/${contextData.todos?.length || 0} completed\\n` +\n `šŸ”„ **Follow-ups:** ${contextData.followUps?.length || 0}\\n\\n` +\n `āœ… **Full context ready for Cursor AI to generate customer response!**\\n\\n` +\n `**Context Data:**\\n\\`\\`\\`json\\n${JSON.stringify(contextData, null, 2)}\\`\\`\\``\n }]\n };\n }\n \n case 'save-customer-response': {\n const { aiSessionId, customerResponse, responseType = 'completion' } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session to validate it exists - find by JavaScript filtering\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .in('team_id', teamIds);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Save the response in database\n const { data: responseData, error: responseError } = await supabase\n .from('ai_responses')\n .insert({\n ai_session_id: session.id,\n response_type: responseType,\n content: customerResponse,\n is_ready_for_customer: true,\n provider_approved: false // Needs manual approval\n })\n .select()\n .single();\n \n if (responseError) throw responseError;\n \n return {\n content: [{\n type: 'text',\n text: `šŸ’¾ **Customer Response Saved!**\\n\\n` +\n `šŸ†” Session: ${aiSessionId}\\n` +\n `šŸ“ Response Type: ${responseType}\\n` +\n `šŸ“„ Length: ${customerResponse.length} characters\\n\\n` +\n `āœ… **Response ready for provider approval**\\n` +\n `šŸ” Provider can review in AI tab before sending to customer\\n\\n` +\n `**Preview:**\\n\\`\\`\\`\\n${customerResponse.substring(0, 200)}${customerResponse.length > 200 ? '...' : ''}\\`\\`\\``\n }]\n };\n }\n \n case 'complete-ai-session': {\n const { aiSessionId, workCompleted, technicalSummary, invoiceDescription, efficiencyNotes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session to calculate actual time spent - find by JavaScript filtering\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: allSessions, error: getSessionError } = await supabase\n .from('ai_sessions')\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\n .in('team_id', teamIds);\n \n if (getSessionError) {\n throw new Error(`Database error: ${getSessionError.message}`);\n }\n \n // Find session with matching prefix\n const existingSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!existingSession) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n\n // Calculate actual time spent automatically\n const completionTime = new Date();\n const sessionStartTime = new Date(existingSession.created_at);\n const timeSpentMinutes = Math.round((completionTime.getTime() - sessionStartTime.getTime()) / 60000);\n \n // Update session to completed with calculated time\n const { data: session, error: sessionError } = await supabase\n .from('ai_sessions')\n .update({\n status: 'completed',\n actual_time_minutes: timeSpentMinutes,\n completed_at: completionTime.toISOString(),\n efficiency_score: null // Will be calculated\n })\n .eq('id', existingSession.id)\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\n .single();\n \n if (sessionError || !session) {\n throw new Error(`Failed to update session: ${aiSessionId}`);\n }\n \n // Calculate efficiency score\n const efficiencyScore = session.ai_time_estimate_minutes \n ? (timeSpentMinutes / session.ai_time_estimate_minutes)\n : 1.0;\n \n // Update efficiency score\n await supabase\n .from('ai_sessions')\n .update({ efficiency_score: efficiencyScore.toFixed(2) })\n .eq('id', session.id);\n \n // Get session duration\n const sessionDuration = Math.round(\n (completionTime.getTime() - new Date(session.created_at).getTime()) / 60000\n );\n \n // Create work summary\n const workSummary = `Completed ${workCompleted.length} tasks including: ${workCompleted.slice(0, 3).join(', ')}${workCompleted.length > 3 ? ' and more' : ''}.`;\n \n // Get ticket details for agenda event creation\n const { data: ticketInfo } = await supabase\n .from('tickets')\n .select('ticket_number, title, project_id')\n .eq('id', session.ticket_id)\n .single();\n \n // CREATE AGENDA EVENT: Now that work is complete, create the timetrack entry\n // Use invoice description if provided, otherwise create a technical one\n let completionDescription: string;\n \n if (invoiceDescription) {\n // Use the invoice-friendly description provided by Cursor (in ticket language)\n completionDescription = `${ticketInfo?.ticket_number || 'Ticket'}: ${invoiceDescription}`;\n } else {\n // Fallback: Create a technical work description\n const workDescription = workCompleted.map((task: string, index: number) => `${index + 1}. ${task}`).join('\\n');\n completionDescription = `${ticketInfo?.ticket_number || 'Ticket'}: ${technicalSummary || workSummary}\\n\\nCompleted work:\\n${workDescription}`;\n }\n \n // Create the agenda event with AI estimated time\n // Use the original AI estimate for billing, not the actual AI completion time\n const estimatedMinutes = session.ai_time_estimate_minutes || timeSpentMinutes;\n const sessionStart = new Date(session.created_at);\n const estimatedEnd = new Date(sessionStart.getTime() + estimatedMinutes * 60000);\n \n const { data: agendaEvent, error: agendaError } = await supabase\n .from('agenda_events')\n .insert({\n team_id: authContext.teamId,\n user_id: authContext.userId,\n title: ticketInfo?.title || 'Development Work',\n description: completionDescription,\n start_time: sessionStart.toISOString(),\n end_time: estimatedEnd.toISOString(),\n project_id: ticketInfo?.project_id || null,\n ticket_id: session.ticket_id,\n ai_session_id: session.id, // Use the actual UUID, not the readable ID\n type: 'work',\n status: 'draft', // Mark as draft for manual approval\n all_day: false,\n is_tracked: true,\n tracked_duration: estimatedMinutes * 60 // Use AI estimate in seconds for billing\n })\n .select('id')\n .single();\n \n if (agendaError) {\n console.error('āš ļø Failed to create agenda event:', agendaError);\n // Don't fail the completion if agenda event creation fails\n }\n \n let responseText = `šŸŽ‰ **AI Session Completed Successfully!**\\n\\n`;\n responseText += `šŸ†” Session: ${aiSessionId}\\n`;\n responseText += `šŸ“Š **Performance Summary:**\\n`;\n responseText += ` • Tasks Completed: ${workCompleted.length}\\n`;\n responseText += ` • Time Spent: ${timeSpentMinutes} minutes\\n`;\n responseText += ` • Estimated Time: ${session.ai_time_estimate_minutes || 'N/A'} minutes\\n`;\n responseText += ` • Efficiency: ${efficiencyScore < 1 ? 'šŸš€' : efficiencyScore > 1.5 ? 'āš ļø' : 'ā±ļø'} ${(efficiencyScore * 100).toFixed(0)}%\\n`;\n responseText += ` • Session Duration: ${sessionDuration} minutes\\n\\n`;\n \n responseText += `āœ… **Work Completed:**\\n`;\n workCompleted.forEach((task: string, index: number) => {\n responseText += `${index + 1}. ${task}\\n`;\n });\n responseText += `\\n`;\n \n if (technicalSummary) {\n responseText += `šŸ”§ **Technical Summary:**\\n${technicalSummary}\\n\\n`;\n }\n \n if (efficiencyNotes) {\n responseText += `šŸ“ˆ **Efficiency Notes:**\\n${efficiencyNotes}\\n\\n`;\n }\n \n if (agendaEvent) {\n responseText += `šŸ“… **Timetrack Entry Created:**\\n`;\n responseText += ` • Agenda event created with work summary\\n`;\n responseText += ` • Status: DRAFT (requires approval in agenda)\\n`;\n responseText += ` • Duration: ${timeSpentMinutes} minutes\\n`;\n responseText += ` • Period: ${sessionStart.toLocaleString()} - ${completionTime.toLocaleString()}\\n\\n`;\n }\n \n // Provide context for Cursor AI to generate customer response\n responseText += `šŸ“‹ **Context for Customer Response:**\\n`;\n responseText += ` • Use \"get-completion-context\" to retrieve full context\\n`;\n responseText += ` • Generate customer-friendly response based on completed work\\n`;\n responseText += ` • Focus on business value and customer benefits\\n\\n`;\n \n responseText += `šŸŽÆ **Session archived successfully!**`;\n \n return {\n content: [{\n type: 'text',\n text: responseText\n }]\n };\n }\n \n case 'log-hours': {\n const { projectId, workDescription, estimatedHours, chatContextSummary } = args as any;\n \n let project = null;\n \n // Verify project access if projectId is provided\n if (projectId) {\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\n const { data: projectData, error: projectError } = await supabase\n .from('projects')\n .select('id, name, team_id')\n .eq('id', projectId)\n .in('team_id', teamIds)\n .single();\n \n if (projectError || !projectData) {\n throw new Error(`Project not found or no access: ${projectId}. Please call get-projects first to find the correct project.`);\n }\n \n project = projectData;\n }\n \n // Convert hours to seconds for agenda_events.tracked_duration\n const durationSeconds = Math.round(estimatedHours * 3600);\n \n // Create agenda event as time tracking entry (draft)\n const now = new Date();\n const startTime = new Date(now.getTime() - durationSeconds * 1000); // Back-calculate start time\n \n const { data: agendaEntry, error: agendaError } = await supabase\n .from('agenda_events')\n .insert({\n team_id: authContext.teamId,\n user_id: authContext.userId,\n project_id: project?.id || null,\n title: workDescription,\n description: chatContextSummary || workDescription,\n start_time: startTime.toISOString(),\n end_time: now.toISOString(),\n type: 'work',\n status: 'draft',\n all_day: false,\n is_tracked: true,\n tracked_duration: durationSeconds\n })\n .select('id, tracked_duration, project_id')\n .single();\n \n if (agendaError || !agendaEntry) {\n throw new Error(`Failed to create time entry: ${agendaError?.message || 'Unknown error'}`);\n }\n \n let responseText = `ā±ļø **Hours Logged Successfully!**\\n\\n`;\n responseText += `šŸ“‹ **Entry Details:**\\n`;\n if (project) {\n responseText += ` • Project: ${project.name}\\n`;\n } else {\n responseText += ` • Project: (No project assigned)\\n`;\n }\n responseText += ` • Description: ${workDescription}\\n`;\n responseText += ` • Estimated Hours: ${estimatedHours}h (${Math.floor(estimatedHours)}h ${Math.round((estimatedHours % 1) * 60)}m)\\n`;\n responseText += ` • Status: DRAFT (not billed yet)\\n`;\n responseText += ` • Entry ID: ${agendaEntry.id}\\n\\n`;\n \n if (chatContextSummary) {\n responseText += `šŸ“Š **Work Context:**\\n`;\n responseText += `${chatContextSummary.substring(0, 200)}${chatContextSummary.length > 200 ? '...' : ''}\\n\\n`;\n }\n \n responseText += `āœ… Time entry created and ready for review in the agenda!`;\n \n return {\n content: [{\n type: 'text',\n text: responseText\n }]\n };\n }\n \n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n \n } catch (error) {\n console.error(`āŒ Tool execution error:`, error);\n return {\n content: [{\n type: 'text',\n text: `Error executing ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`\n }]\n };\n }\n});\n\n// Resource read handler\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n if (!authContext) {\n return {\n contents: [{\n uri: request.params.uri,\n mimeType: 'text/plain',\n text: 'Error: Not authenticated. API key validation failed.'\n }]\n };\n }\n\n const { uri } = request.params;\n console.error(`šŸ“š Reading resource: ${uri}`);\n \n try {\n switch (uri) {\n case 'tickets://recent': {\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\n const { data, error } = await supabase\n .from('tickets')\n .select(`\n id,\n ticket_number,\n title,\n status,\n priority,\n created_at\n `)\n .in('team_id', teamIds)\n .order('created_at', { ascending: false })\n .limit(20);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n case 'customers://all': {\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\n const { data, error } = await supabase\n .from('customers')\n .select('id, name, email, website, created_at')\n .in('team_id', teamIds)\n .order('name')\n .limit(50);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n case 'projects://active': {\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\n const { data, error } = await supabase\n .from('projects')\n .select(`\n id,\n name,\n description,\n status,\n created_at,\n customers:customer_id(id, name)\n `)\n .in('team_id', teamIds)\n .eq('status', 'active')\n .order('name')\n .limit(50);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n default:\n throw new Error(`Unknown resource: ${uri}`);\n }\n \n } catch (error) {\n console.error(`āŒ Resource read error:`, error);\n return {\n contents: [{\n uri,\n mimeType: 'text/plain',\n text: `Error reading ${uri}: ${error instanceof Error ? error.message : 'Unknown error'}`\n }]\n };\n }\n});\n\n// Main function\nasync function main() {\n console.error('šŸš€ Starting MG Tickets MCP Bridge Server...');\n console.error(`šŸ”‘ API Key: ${apiKey?.substring(0, 10)}...`);\n \n // Validate API key\n authContext = await validateApiKey(apiKey!);\n if (!authContext) {\n console.error('āŒ API key validation failed. Please check your key and try again.');\n process.exit(1);\n }\n \n console.error(`āœ… Authenticated as user ${authContext.userId} in team ${authContext.teamId}`);\n console.error(`šŸ“‹ Available scopes: ${authContext.scopes.join(', ')}`);\n console.error('šŸ“” MCP Bridge Server ready for connections');\n \n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n// Handle graceful shutdown\nprocess.on('SIGINT', async () => {\n console.error('šŸ‘‹ Shutting down MCP Bridge Server...');\n process.exit(0);\n});\n\nprocess.on('SIGTERM', async () => {\n console.error('šŸ‘‹ Shutting down MCP Bridge Server...');\n process.exit(0);\n});\n\n// Start the server\nmain().catch((error) => {\n console.error('šŸ’„ Fatal error:', error);\n process.exit(1);\n});"]}
package/package.json CHANGED
@@ -1,47 +1,47 @@
1
- {
2
- "name": "@mgsoftwarebv/mcp-server-bridge",
3
- "version": "2.12.1",
4
- "description": "MCP Server bridge for MG Tickets - connects Cursor to HTTP MCP server with image support",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "bin": {
8
- "mg-tickets-mcp": "dist/index.js"
9
- },
10
- "scripts": {
11
- "build": "tsup",
12
- "dev": "tsup --watch",
13
- "start": "node dist/index.js",
14
- "typecheck": "tsc --noEmit"
15
- },
16
- "keywords": [
17
- "mcp",
18
- "tickets",
19
- "bridge",
20
- "cursor",
21
- "mg-software"
22
- ],
23
- "author": "MG Software B.V.",
24
- "license": "MIT",
25
- "dependencies": {
26
- "@modelcontextprotocol/sdk": "^1.0.4",
27
- "@supabase/supabase-js": "^2.50.0",
28
- "crypto": "^1.0.1"
29
- },
30
- "devDependencies": {
31
- "@types/node": "^20.0.0",
32
- "tsup": "^8.0.0",
33
- "typescript": "^5.0.0"
34
- },
35
- "files": [
36
- "dist",
37
- "README.md"
38
- ],
39
- "repository": {
40
- "type": "git",
41
- "url": "git+https://github.com/mgsoftwarebv/tickets-v2.git"
42
- },
43
- "publishConfig": {
44
- "access": "public",
45
- "registry": "https://registry.npmjs.org/"
46
- }
47
- }
1
+ {
2
+ "name": "@mgsoftwarebv/mcp-server-bridge",
3
+ "version": "2.13.0",
4
+ "description": "MCP Server bridge for MG Tickets - connects Cursor to HTTP MCP server with image support",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "mg-tickets-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "dev": "tsup --watch",
13
+ "start": "node dist/index.js",
14
+ "typecheck": "tsc --noEmit"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "tickets",
19
+ "bridge",
20
+ "cursor",
21
+ "mg-software"
22
+ ],
23
+ "author": "MG Software B.V.",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.0.4",
27
+ "@supabase/supabase-js": "^2.50.0",
28
+ "crypto": "^1.0.1"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.0.0",
32
+ "tsup": "^8.0.0",
33
+ "typescript": "^5.0.0"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/mgsoftwarebv/tickets-v2.git"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public",
45
+ "registry": "https://registry.npmjs.org/"
46
+ }
47
+ }