limitless_get_detailed_analysis
Extract precise technical specifications, exact measurements, and scientific details from conversation recordings. Focus on financial data, research findings, or decision analysis while maintaining numerical accuracy.
Instructions
Deep analysis focused on technical details, exact figures, scientific terminology, and specific information. Preserves precision without generalization - ideal for extracting exact specifications, measurements, and technical discussions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| time_expression | No | Natural time expression like 'today', 'this week' (defaults to 'today'). | |
| timezone | No | IANA timezone for date calculations. | |
| focus_area | No | Focus analysis on specific areas: technical (scientific/medical terms, specifications), financial (numbers, costs, budgets), decisions (choices made, conclusions), research (findings, data, studies), or all. | all |
| preserve_precision | No | Maintain exact numbers, measurements, and technical specifications without rounding or generalization. |
Implementation Reference
- src/server.ts:992-1136 (handler)Primary handler function for the 'limitless_get_detailed_analysis' tool. Fetches lifelogs for the given time range using pagination, extracts detailed structured transcripts with metadata (technical terms, numbers/figures, key phrases), then filters and analyzes content based on focus_area (technical, financial, decisions, research, or all). Returns structured analysis preserving exact details and precision.async (args, _extra) => { try { const timeExpression = args.time_expression || 'today'; const parser = new NaturalTimeParser({ timezone: args.timezone }); const timeRange = parser.parseTimeExpression(timeExpression); // Fetch all logs with pagination const allLogs: Lifelog[] = []; let cursor: string | undefined = undefined; while (true) { const result = await getLifelogsWithPagination(limitlessApiKey, { start: timeRange.start, end: timeRange.end, timezone: timeRange.timezone, includeMarkdown: true, includeHeadings: true, limit: MAX_API_LIMIT, direction: 'asc', cursor: cursor }); allLogs.push(...result.lifelogs); if (!result.pagination.nextCursor || result.lifelogs.length < MAX_API_LIMIT) { break; } cursor = result.pagination.nextCursor; } const logs = allLogs; if (logs.length === 0) { return { content: [{ type: "text", text: `No detailed information found for "${timeExpression}".` }] }; } // Extract detailed transcripts with maximum context preservation const transcriptOptions: TranscriptOptions = { format: "structured", includeTimestamps: true, includeSpeakers: true, includeContext: true, preserveFormatting: true }; const detailedAnalysis = { timeRange: `${timeRange.start} to ${timeRange.end}`, totalLifelogs: logs.length, focusArea: args.focus_area, preservePrecision: args.preserve_precision, analysis: [] as any[] }; for (const lifelog of logs) { const transcript = TranscriptExtractor.extractRawTranscript(lifelog, transcriptOptions); // Focus analysis based on requested area let focusedContent: any = {}; switch (args.focus_area) { case "technical": focusedContent = { technicalTerms: transcript.metadata.technicalTermsFound, specifications: transcript.segments.filter(s => /\b(?:specification|spec|requirement|parameter|protocol|algorithm|implementation|architecture|design|version|model|standard)\b/i.test(s.content) ), measurements: transcript.metadata.numbersAndFigures.filter(f => /\b\d+(?:\.\d+)?\s*(?:mg|kg|ml|cm|mm|km|hz|ghz|mb|gb|tb|fps|rpm|°[CF]|pH|ppm|mol|atm|bar|pascal|joule|watt|volt|amp|ohm)\b/i.test(f) ) }; break; case "financial": focusedContent = { monetaryFigures: transcript.metadata.numbersAndFigures.filter(f => /\$|budget|cost|price|revenue|profit|expense|dollar|EUR|GBP|million|billion/i.test(f) ), percentages: transcript.metadata.numbersAndFigures.filter(f => f.includes('%')), financialTerms: transcript.segments.filter(s => /\b(?:budget|cost|price|revenue|profit|loss|expense|investment|ROI|funding|valuation|equity|debt|cash flow|EBITDA|margin)\b/i.test(s.content) ) }; break; case "decisions": focusedContent = { decisions: transcript.segments.filter(s => /\b(?:decided|decision|agreed|concluded|determined|chose|selected|approved|rejected|final|consensus)\b/i.test(s.content) ), keyChoices: transcript.metadata.keyPhrases.filter(p => /\b(?:decide|determine|choose|select|go with|option|alternative)\b/i.test(p) ) }; break; case "research": focusedContent = { findings: transcript.segments.filter(s => /\b(?:study|research|data|analysis|results|findings|evidence|statistics|survey|experiment|trial|test)\b/i.test(s.content) ), citations: transcript.segments.filter(s => /\b(?:according to|source|reference|cited|published|journal|paper|article|report)\b/i.test(s.content) ), methodology: transcript.segments.filter(s => /\b(?:method|methodology|approach|technique|process|procedure|protocol|framework)\b/i.test(s.content) ) }; break; default: // "all" focusedContent = { technicalTerms: transcript.metadata.technicalTermsFound, numbersAndFigures: transcript.metadata.numbersAndFigures, keyPhrases: transcript.metadata.keyPhrases, decisions: transcript.segments.filter(s => /\b(?:decided|decision|agreed|concluded)\b/i.test(s.content) ), specificDetails: transcript.segments.filter(s => s.content.length > 50 && // Longer, more detailed segments (/\b(?:\d+(?:\.\d+)?|\$|%|version|model|specification|exactly|precisely|specifically)\b/i.test(s.content)) ) }; } detailedAnalysis.analysis.push({ lifelogId: lifelog.id, title: transcript.title, duration: `${Math.round(transcript.totalDuration / 60000)} minutes`, participants: transcript.metadata.uniqueSpeakers, wordCount: transcript.metadata.wordCount, focusedContent, fullTranscript: args.preserve_precision ? transcript.formattedTranscript : transcript.rawText }); } return createSafeResponse( detailedAnalysis, `Detailed analysis for "${timeExpression}" (Focus: ${args.focus_area})` ); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error generating detailed analysis: ${errorMessage}` }], isError: true }; } }
- src/server.ts:276-282 (schema)Input schema validation using Zod for the tool's arguments: time_expression, timezone, focus_area, preserve_precision.const DetailedAnalysisArgsSchema = { time_expression: z.string().optional().describe("Natural time expression like 'today', 'this week' (defaults to 'today')."), timezone: z.string().optional().describe("IANA timezone for date calculations."), focus_area: z.enum(["technical", "financial", "decisions", "research", "all"]).optional().default("all").describe("Focus analysis on specific areas: technical (scientific/medical terms, specifications), financial (numbers, costs, budgets), decisions (choices made, conclusions), research (findings, data, studies), or all."), preserve_precision: z.boolean().optional().default(true).describe("Maintain exact numbers, measurements, and technical specifications without rounding or generalization."), };
- src/server.ts:989-992 (registration)MCP server registration of the 'limitless_get_detailed_analysis' tool with description, schema, and handler reference.server.tool("limitless_get_detailed_analysis", "Deep analysis focused on technical details, exact figures, scientific terminology, and specific information. Preserves precision without generalization - ideal for extracting exact specifications, measurements, and technical discussions.", DetailedAnalysisArgsSchema, async (args, _extra) => {
- src/transcript-extraction.ts:55-99 (helper)Key helper function TranscriptExtractor.extractRawTranscript used by the handler to process each lifelog into detailed transcript with segments, metadata (technicalTermsFound, numbersAndFigures, keyPhrases), which drives the focused analysis.static extractRawTranscript(lifelog: Lifelog, options: TranscriptOptions = { format: "structured" }): DetailedTranscript { const { format = "structured", includeTimestamps = true, includeSpeakers = true, includeContext = true, preserveFormatting = false, timeFormat = "absolute", speakerFormat = "names" } = options; if (!lifelog.contents || lifelog.contents.length === 0) { return this.createEmptyTranscript(lifelog); } // Extract all conversation segments with full context const segments = this.extractSegments(lifelog.contents, { includeTimestamps, includeSpeakers, includeContext, timeFormat, speakerFormat }); // Analyze content for technical terms, figures, and key phrases const metadata = this.analyzeContent(segments); // Generate different format outputs const rawText = this.generateRawText(segments, preserveFormatting); const formattedTranscript = this.generateFormattedTranscript(segments, format, options); const totalDuration = new Date(lifelog.endTime).getTime() - new Date(lifelog.startTime).getTime(); return { lifelogId: lifelog.id, title: lifelog.title || "Untitled Conversation", startTime: lifelog.startTime, endTime: lifelog.endTime, totalDuration, segments, metadata, rawText, formattedTranscript }; }
- src/advanced-features.ts:130-170 (helper)NaturalTimeParser.parseTimeExpression helper used in handler to convert natural language time_expression to precise time range for fetching lifelogs.parseTimeExpression(expression: string): TimeRange { const normalized = expression.toLowerCase().trim(); // Get current time in target timezone const now = new Date(this.referenceTime); const currentDate = new Date(now.toLocaleString("en-US", { timeZone: this.timezone })); // Basic day references switch (normalized) { case "today": return this.getDayRange(currentDate); case "yesterday": const yesterday = new Date(currentDate); yesterday.setDate(yesterday.getDate() - 1); return this.getDayRange(yesterday); case "tomorrow": const tomorrow = new Date(currentDate); tomorrow.setDate(tomorrow.getDate() + 1); return this.getDayRange(tomorrow); // Time of day - today case "this morning": case "morning": return this.getTimeOfDayRange(currentDate, 6, 12); case "this afternoon": case "afternoon": return this.getTimeOfDayRange(currentDate, 12, 18); case "this evening": case "evening": return this.getTimeOfDayRange(currentDate, 18, 22); case "tonight": case "this night": return this.getTimeOfDayRange(currentDate, 20, 23, 59); case "earlier today": case "earlier":