search-advanced
Search and filter tasks in Things 3 using criteria like status, dates, tags, and areas to find specific items for management.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | incomplete, completed, or canceled | |
| start_date | No | Start date in YYYY-MM-DD | |
| deadline | No | Deadline in YYYY-MM-DD | |
| tag | No | Tag title | |
| area | No | Area UUID or title | |
| type | No | to-do, project, or heading | |
| last | No | Created within period like 3d or 1w | |
| detail | No | Response detail level. Defaults to compact. | |
| limit | No | Maximum number of items to return |
Implementation Reference
- src/index.ts:1506-1571 (handler)The handler for the "search-advanced" MCP tool, which filters and returns tasks based on various optional parameters.
server.tool( "search-advanced", { status: z.string().optional().describe("incomplete, completed, or canceled"), start_date: z.string().optional().describe("Start date in YYYY-MM-DD"), deadline: z.string().optional().describe("Deadline in YYYY-MM-DD"), tag: z.string().optional().describe("Tag title"), area: z.string().optional().describe("Area UUID or title"), type: z.string().optional().describe("to-do, project, or heading"), last: z.string().optional().describe("Created within period like 3d or 1w"), detail: z.enum(["compact", "full"]).optional().describe("Response detail level. Defaults to compact."), limit: z.number().int().positive().optional().describe("Maximum number of items to return"), }, async (params) => { const requestedDetail = params.detail ?? "compact"; const results = await withDatabase((db) => { let tasks = getAllTasks(db).filter((task) => !task.trashed); if (params.status) { tasks = tasks.filter((task) => task.status === params.status?.toLowerCase()); } if (params.start_date) { tasks = tasks.filter((task) => task.startDate === params.start_date); } if (params.deadline) { tasks = tasks.filter((task) => task.deadline === params.deadline); } if (params.tag) { tasks = tasks.filter((task) => task.tags.includes(params.tag!)); } if (params.area) { const lower = params.area.toLowerCase(); tasks = tasks.filter( (task) => task.areaId?.toLowerCase() === lower || task.areaTitle?.toLowerCase() === lower ); } if (params.type) { tasks = tasks.filter((task) => task.type === params.type); } if (params.last) { const since = parseRelativePeriod(params.last); tasks = tasks.filter( (task) => task.created && new Date(task.created) >= since ); } return applyLimit(tasks, params.limit).map((task) => toTaskView(task, requestedDetail) ); }); return buildTextResponse(`Found ${results.length} matching items`, { results, detail: requestedDetail, limit: params.limit ?? null, }); } );