Conversation
…oday/upcoming (#57) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0ad0778 to
436f3b9
Compare
There was a problem hiding this comment.
This PR delivers substantial performance improvements to the td today and td upcoming commands by implementing server-side assignee scoping and parallelizing project fetching. The changes, which include a new --any-assignee flag, have been thoroughly benchmarked and tested, demonstrating significant speedups and output correctness. No issues were flagged in the inline comments, indicating a high-quality implementation.
scottlovegrove
approved these changes
Feb 11, 2026
2 tasks
gnapse
added a commit
to Doist/todoist-ai
that referenced
this pull request
Feb 12, 2026
…g in get-overview (#310) # Pull Request Closes #311. Inspired by Doist/todoist-cli#59. ## Short description Ports two performance optimizations from the CLI to the MCP server, and fixes a pre-existing bug found during review: 1. **Server-side assignee scoping in `find-tasks`**: The text/labels search path was fetching all matching tasks then filtering by `responsibleUid` client-side. In large workspaces this meant paginating through many irrelevant team members' tasks. Now uses `buildResponsibleUserQueryFilter()` to append assignee filters (e.g. `!assigned to: others`) directly to the API query — matching what `find-tasks-by-date` already does. 2. **Parallel fetching in `get-overview`**: `generateProjectOverview` was calling `getProject()`, `getProjectSections()`, and `getAllTasksForProject()` sequentially. These are independent and now run in parallel via `Promise.all`. 3. **Bug fix: `filterTasksByResponsibleUser` missing `assigned` mode** (#311): The `assigned` filtering mode in the container-based path (projectId/sectionId/parentId) was returning all tasks instead of only tasks assigned to others. Note: The container-based search path in `find-tasks` still uses client-side assignee filtering because `getTasks` doesn't support filter queries. ### Manual testing Verified all three affected tools against the live Todoist API using `scripts/run-tool.ts`: - `find-tasks` with text search (`{"searchText":"meeting","limit":3}`) — returns filtered results correctly - `find-tasks-by-date` with today (`{"startDate":"today","limit":3}`) — confirmed already correct - `get-overview` with project ID — returns full project structure correctly ## PR Checklist - [x] Added tests for bugs / new features - [ ] Updated docs (README, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #57.
td todayandtd upcomingnow use(assigned to: me | !assigned)in the filter query by default, so the API returns only relevant tasks instead of every team member's tasks. Previously, all tasks were fetched then filtered client-side — in large workspaces this meant 10-15+ paginated API calls with most results discarded.getProjects()now runs in parallel with task pagination viaPromise.all, instead of sequentially after.--any-assigneeflag: Opt-in to the old broad-query behavior when you actually want all team members' tasks.filterByWorkspaceOrPersonal: Switched to named args, accepts optional pre-fetched projects map to avoid redundant API calls.Benchmark 1: Single-user account (127 today+overdue tasks)
td today --alltd upcoming 14 --allOutput is byte-for-byte identical between versions.
Benchmark 2: Workspace account (small workspace)
td today --alltd upcoming 30 --allServer-side scoping returned 30 tasks vs 109 with
--any-assignee(broad query) — the filter eliminates ~72% of irrelevant team tasks even in this small workspace.todayoutput is identical;upcominghuman-readable output is identical.Note
Both benchmarks were run against relatively small accounts. The workspace tested had few team members, so the server-side assignee scoping — while effective — did not exercise the full scenario from the original report (~2 min for 192 tasks across 15+ API pages of team members' tasks). The full expected impact still needs validation against a large shared workspace, where the reduction in paginated API calls should yield a much larger speedup.
Test plan
--any-assigneebroad query, assignee inclusion, parallel fetch--any-assignee) queries return correct results🤖 Generated with Claude Code