import { z } from 'zod';
import { LimitlessClient } from '../../lib/limitless-client.js';
import { LifelogsResponse } from '../../types/limitless.js';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
export const searchLifelogsSchema = z.object({
query: z.string().describe('Search query to find in lifelog content'),
dateFrom: z.string().optional().describe('Start date for search range (YYYY-MM-DD)'),
dateTo: z.string().optional().describe('End date for search range (YYYY-MM-DD)'),
source: z.enum(['pendant', 'desktop', 'web', 'mobile']).optional().describe('Filter by source'),
isStarred: z.boolean().optional().describe('Filter by starred status'),
tags: z.array(z.string()).optional().describe('Filter by tags'),
limit: z.number().min(1).max(100).optional().describe('Number of results to return'),
cursor: z.string().optional().describe('Pagination cursor'),
});
export type SearchLifelogsParams = z.infer<typeof searchLifelogsSchema>;
export const searchLifelogsTool: Tool = {
name: 'limitless_search_lifelogs',
description: 'Search through lifelogs content using natural language queries',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query to find in lifelog content' },
dateFrom: { type: 'string', description: 'Start date for search range (YYYY-MM-DD)' },
dateTo: { type: 'string', description: 'End date for search range (YYYY-MM-DD)' },
source: {
type: 'string',
enum: ['pendant', 'desktop', 'web', 'mobile'],
description: 'Filter by source'
},
isStarred: { type: 'boolean', description: 'Filter by starred status' },
tags: {
type: 'array',
items: { type: 'string' },
description: 'Filter by tags'
},
limit: { type: 'number', description: 'Number of results to return' },
cursor: { type: 'string', description: 'Pagination cursor' },
},
required: ['query'],
},
};
export async function searchLifelogs(params: SearchLifelogsParams, client: LimitlessClient): Promise<LifelogsResponse> {
// Note: This endpoint might not be available yet based on the API docs
// Adding it for completeness as it's a common feature
const queryParams: any = {
q: params.query,
};
if (params.dateFrom) queryParams.dateFrom = params.dateFrom;
if (params.dateTo) queryParams.dateTo = params.dateTo;
if (params.source) queryParams.source = params.source;
if (params.isStarred !== undefined) queryParams.isStarred = params.isStarred;
if (params.tags && params.tags.length > 0) queryParams.tags = params.tags.join(',');
if (params.limit) queryParams.limit = params.limit;
if (params.cursor) queryParams.cursor = params.cursor;
return await client.get<LifelogsResponse>('/lifelogs/search', queryParams);
}