-
Notifications
You must be signed in to change notification settings - Fork 24
feat: Improve tool output UX with LLM-readable responses #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implement human-readable responses for all Todoist AI tools by leveraging the MCP specification's dual content format support. All 13 tools now provide both contextual text summaries and structured content, significantly improving LLM comprehension and user experience. - Add response builder utilities for consistent human-readable summaries - Update MCP output format to support dual content (text + structured) - Migrate all tools to provide actionable summaries with next-step guidance - Maintain backward compatibility with structured content for existing integrations - Add comprehensive test coverage with snapshot validation Closes #48 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements human-readable responses for all Todoist AI tools using MCP dual content format, providing both contextual text summaries and structured content to improve LLM comprehension and user experience.
- MCP dual format implementation - New
getToolOutput()function provides both text and structured content - Response builders module - Centralized utilities for task summaries, batch operations, list formatting, and next-step suggestions
- Tool name centralization - Single source of truth for tool names to prevent outdated references
Reviewed Changes
Copilot reviewed 41 out of 41 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/utils/tool-names.ts |
Centralized tool names constants to prevent hardcoded strings |
src/utils/response-builders.ts |
Response formatting utilities for task operations, lists, and contextual guidance |
src/tools/test-helpers.ts |
Test utilities including text content extraction and fixed date constants |
src/tools/tasks-*.ts |
Updated task tools to use dual format with human-readable summaries |
src/tools/sections-*.ts |
Updated section tools with contextual text responses |
src/tools/projects-*.ts |
Updated project tools with workflow-aware next steps |
src/tools/overview.ts |
Updated overview tool to provide both markdown and structured data |
src/tools/delete-one.ts |
Updated delete tool with recovery-focused guidance |
src/tools/__tests__/** |
Updated tests to validate text content using snapshots |
src/mcp-helpers.ts |
Simplified MCP helpers with new dual format function |
Comments suppressed due to low confidence (2)
src/utils/response-builders.ts:83
- Consider moving the
new Date()call outside the loop to avoid creating a new Date object for each task comparison. Store it in a variable likeconst now = new Date()before thesome()call.
}
src/utils/response-builders.ts:284
- The
new Date().toISOString().split('T')[0]expression is computed for each task. Consider extracting this to a variable likeconst today = new Date().toISOString().split('T')[0]before thesome()call.
}
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
🤖 I have created a release *beep* *boop* --- ## [3.0.0](v2.2.2...v3.0.0) (2025-08-21) ### ⚠ BREAKING CHANGES * verb-first tool names, unify find-by-container into find-tasks ([#53](#53)) * Remove single update task and replace with multiple ([#47](#47)) ### Features * Improve tool output UX with LLM-readable responses ([#49](#49)) ([7c25696](7c25696)) * Remove single update task and replace with multiple ([#47](#47)) ([8a9b7cf](8a9b7cf)) * verb-first tool names, unify find-by-container into find-tasks ([#53](#53)) ([dbada71](dbada71)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
🗺️ Overview
Implements more human and LLM-readable responses for all Todoist AI tools using MCP dual content format. Tools now provide both contextual text summaries and structured content, improving LLM comprehension and user experience.
🧩 Problem
Tools returned only structured JSON, forcing LLMs to interpret raw data without context:
💡 Solution
src/utils/response-builders.ts) - Task summaries, batch operations, list formatting, next-step suggestionssrc/mcp-helpers.ts) - Text + structured content via newgetToolOutput()function🌟 Benefits
contentpart for nowstructuredContentfield from the more recent June 18th MCP spec is hidden for now, controlled by an environment variable.🧪 Test plan
These instructions are specific for Claude Desktop, but you should be able to adapt them for Claude Code or Cursor or VS Code by searching the web to see where their MCP config file can be found.
npm install && npm run build/Users/<username>/Library/Application Support/Claude/claude_desktop_config.jsonin macOStodoist-ai-localentry under themcpServersobject{ "mcpServers": { "todoist-ai-local": { "command": "node", "args": ["/path/to/todoist-ai/dist/main.js"], // change this path ⚠️ "env": { "TODOIST_API_KEY": "<PRODUCTION-API-KEY>" // change this API key ⚠️ } } } }dist/main.jsfile, and a valid production API key for Todoist🎥 Demo
CleanShot.2025-08-19.at.15.21.37.mp4
🌐 Usage in other languages
I was worried about the natural language response being in English, and what would happen if we used this when chatting with the LLM in a language other than English. So I tried, and it seems to work well.
👉 Here's a demo and a screenshot:
(click to expand)
CleanShot.2025-08-19.at.15.37.59.mp4
I even asked the LLM if it received some suggestions for actions that could come next, and it totally got it from the English language response, but answered me in Spanish about it: