capture
Capture and route text input through an ADHD-friendly AI system for automatic context detection and intelligent task organization, reducing cognitive overhead.
Instructions
Capture and route text input using ChurnFlow ADHD-friendly AI system
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| context | No | Optional context hint for routing (business, personal, project, system) | |
| priority | No | Priority level for the captured content | |
| text | Yes | Text to capture and route (can contain multiple items) |
Implementation Reference
- src/index.ts:123-200 (handler)The MCP 'capture' tool handler function. Initializes the CaptureEngine, processes input arguments into CaptureInput, executes capture, and returns formatted MCP CallToolResult with success summary or error./** * Handle capture tool requests */ async function handleCapture(args: any): Promise<CallToolResult> { try { await initializeCaptureEngine(); if (!captureEngine) { throw new Error('Failed to initialize capture engine'); } const input: CaptureInput = { text: args.text, inputType: 'text', forceContext: args.context, }; const result: CaptureResult = await captureEngine.capture(input); if (!result.success) { return { content: [ { type: 'text', text: `Capture failed: ${result.error}`, }, ], isError: true, }; } // Format successful capture result const summary = [ `β Capture Successful!`, `π Primary Tracker: ${result.primaryTracker}`, `π― Confidence: ${Math.round(result.confidence * 100)}%`, `π Generated ${result.itemResults?.length || 0} items`, '', ]; if (result.itemResults && result.itemResults.length > 0) { summary.push('π Items Generated:'); result.itemResults.forEach(item => { summary.push(` β ${item.itemType} β ${item.tracker}`); summary.push(` ${item.formattedEntry}`); }); } if (result.completedTasks && result.completedTasks.length > 0) { summary.push(''); summary.push('π― Task Completions:'); result.completedTasks.forEach(completion => { summary.push(` β completion in ${completion.tracker}`); summary.push(` ${completion.description}`); }); } return { content: [ { type: 'text', text: summary.join('\n'), }, ], isError: false, }; } catch (error) { return { content: [ { type: 'text', text: `Error during capture: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }
- src/index.ts:37-59 (schema)JSON schema definition for the 'capture' tool input, including required 'text' field and optional 'priority' and 'context'.{ name: 'capture', description: 'Capture and route text input using ChurnFlow ADHD-friendly AI system', inputSchema: { type: 'object', properties: { text: { type: 'string', description: 'Text to capture and route (can contain multiple items)', }, priority: { type: 'string', enum: ['high', 'medium', 'low'], description: 'Priority level for the captured content', }, context: { type: 'string', description: 'Optional context hint for routing (business, personal, project, system)', }, }, required: ['text'], }, },
- src/index.ts:334-350 (registration)Registration of CallToolRequestHandler with switch statement that dispatches calls to 'capture' tool to the handleCapture function.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case 'capture': return await handleCapture(args); case 'status': return await handleStatus(); case 'list_trackers': return await handleListTrackers(args); default: throw new Error(`Unknown tool: ${name}`); } });
- src/index.ts:329-331 (registration)Registration of ListToolsRequestHandler that returns the list of available tools including 'capture'.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: TOOLS }; });
- src/core/CaptureEngine.ts:69-183 (helper)Core implementation of capture logic in CaptureEngine class: AI inference, item/task processing, routing to trackers, database save, error handling with review/emergency fallbacks.async capture(input: string | CaptureInput): Promise<CaptureResult> { if (!this.initialized) { await this.initialize(); } // Normalize input const captureInput: CaptureInput = typeof input === "string" ? { text: input, inputType: "text" } : input; console.log(`π― Capturing: "${captureInput.text}"`); try { // Use AI to infer routing and generate multiple items const inference = await this.inferenceEngine.inferCapture(captureInput); console.log( `π€ AI inference: ${inference.primaryTracker} (${inference.confidence * 100}% confidence)`, ); console.log(`π Analysis: ${inference.overallReasoning}`); console.log( `π’ Generated ${inference.generatedItems.length} items, ${inference.taskCompletions.length} completions`, ); // Handle low confidence - route to review if (inference.requiresReview) { return await this.routeToReview(captureInput, inference); } // Process task completions first const completedTasks = []; for (const completion of inference.taskCompletions) { console.log(`β Task completion detected: ${completion.description} in ${completion.tracker}`); // Actually mark the task as complete in the tracker file const success = await this.trackerManager.markTaskComplete( completion.tracker, completion.description ); completedTasks.push({ ...completion, success }); if (success) { console.log(`β Successfully marked task as complete: ${completion.description}`); } else { console.error(`β Failed to mark task as complete: ${completion.description}`); } } // Process generated items const itemResults = []; for (const item of inference.generatedItems) { console.log( `π Processing ${item.itemType} for ${item.tracker}: ${item.reasoning}`, ); let success: boolean; if (item.itemType === "activity") { success = await this.trackerManager.appendActivityToTracker( item.tracker, item.content, ); } else { success = await this.trackerManager.appendToTracker( item.tracker, item.content, ); } itemResults.push({ success, tracker: item.tracker, itemType: item.itemType, formattedEntry: item.content, error: success ? undefined : `Failed to write to ${item.tracker}`, }); if (success) { console.log( `β ${item.itemType} successfully added to ${item.tracker}`, ); } else { console.error(`β Failed to add ${item.itemType} to ${item.tracker}`); } } // Determine overall success const overallSuccess = itemResults.some((result) => result.success); // Save to database if available (optional - doesn't affect capture success) if (overallSuccess && this.databaseAvailable) { try { await this.saveCaptureToDatabase(captureInput, inference, itemResults, overallSuccess); } catch (dbError) { console.warn("β οΈ Failed to save to database (file saved successfully):", dbError); } } return { success: overallSuccess, primaryTracker: inference.primaryTracker, confidence: inference.confidence, itemResults, completedTasks, requiresReview: false, }; } catch (error) { console.error("β Capture failed:", error); // Emergency fallback - try to save somewhere return await this.emergencyCapture(captureInput, error as Error); } }