-
Couldn't load subscription status.
- Fork 29
feat: Add list_project_issues tool to fetch all issues in a project #39
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
base: canary
Are you sure you want to change the base?
Conversation
WalkthroughAdded a new tool to list project issues with a compact response, introduced internal paginated/summary types, and applied explicit Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant MCP as MCP Server
participant Tool as list_project_issues
participant API as Project API
Client->>MCP: Request list_project_issues (project_id, pagination)
MCP->>Tool: Invoke tool with params
Tool->>API: Fetch issues for project (paginated)
API-->>Tool: Return paginated issue data
Tool->>Tool: Map to compact issue shape (id, name, sequence_id, state, priority, created_at, updated_at)
Tool-->>MCP: Return summary payload (total_count, count, results)
MCP-->>Client: Respond with compacted issues
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This PR is being reviewed by Cursor BugbotDetailsYour team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team. To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Bug: UUID References Hinder LLM ProcessingThe simplified issues object includes |
Bug: Inconsistent Issue Data MappingThe |
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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/tools/issues.ts (1)
23-63: Consider exposing pagination information.The implementation correctly fetches issues and simplifies the response to reduce token usage. However, the Plane API returns pagination fields (
next_page_results,prev_page_results,next_cursor,prev_cursor) that are not exposed in the simplified response. For projects with many issues, this tool will only return the first page without indicating that more results exist.Consider including pagination metadata in the response:
return { content: [ { type: "text", text: JSON.stringify( { total_count: issuesResponse.total_count, count: issuesResponse.count, + total_pages: issuesResponse.total_pages, + next_page_results: issuesResponse.next_page_results, + prev_page_results: issuesResponse.prev_page_results, results: simplifiedIssues, }, null, 2 ), }, ], };Additionally, you might want to add optional
cursororpageparameters to the tool in a follow-up to enable paginated access for large result sets.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/common/request-helper.ts(2 hunks)src/tools/issues.ts(1 hunks)src/tools/modules.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/tools/issues.ts (2)
src/schemas.ts (2)
Issue(38-68)Issue(69-69)src/common/request-helper.ts (1)
makePlaneRequest(3-36)
🔇 Additional comments (5)
src/common/request-helper.ts (1)
12-12: LGTM! Formatting consistency improvement.The change from single quotes to double quotes for string literals improves consistency across the codebase.
Also applies to: 24-24
src/tools/modules.ts (1)
7-7: LGTM! Explicit return type annotation.Adding the explicit
voidreturn type improves type safety and satisfies linting requirements.src/tools/issues.ts (3)
5-5: LGTM! Type-only import pattern.Using the
typekeyword for the Issue import is a good practice that helps with tree-shaking and clearly distinguishes type imports from value imports.
22-22: LGTM! Explicit return type annotation.Adding the explicit
voidreturn type improves type safety and satisfies linting requirements, consistent with the change insrc/tools/modules.ts.
67-70: LGTM! Improved parameter descriptions.The enhanced descriptions clearly explain the readable identifier format (e.g.,
FIRST-123) and how to split it intoproject_identifierandissue_identifier, which will help LLM agents use this tool correctly.
| type IssuesResponse = { | ||
| grouped_by: null; | ||
| sub_grouped_by: null; | ||
| total_count: number; | ||
| next_cursor: string; | ||
| prev_cursor: string; | ||
| next_page_results: boolean; | ||
| prev_page_results: boolean; | ||
| count: number; | ||
| total_pages: number; | ||
| total_results: number; | ||
| extra_stats: null; | ||
| results: Issue[]; | ||
| }; |
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.
🧩 Analysis chain
Consider more flexible typing for nullable fields.
The IssuesResponse type definition hardcodes several fields as null (lines 8, 9, 18). If the Plane API can return non-null values for grouped_by, sub_grouped_by, or extra_stats in different contexts (e.g., when grouping is applied), the current typing will cause runtime type mismatches.
Consider using union types for these fields if they can have values:
type IssuesResponse = {
- grouped_by: null;
- sub_grouped_by: null;
+ grouped_by: string | null;
+ sub_grouped_by: string | null;
total_count: number;
next_cursor: string;
prev_cursor: string;
next_page_results: boolean;
prev_page_results: boolean;
count: number;
total_pages: number;
total_results: number;
- extra_stats: null;
+ extra_stats: Record<string, any> | null;
results: Issue[];
};Please verify the Plane API documentation to confirm whether these fields can have non-null values.
🌐 Web query:
What are the possible values for grouped_by, sub_grouped_by, and extra_stats fields in Plane API issues endpoint response?
💡 Result:
Do you mean Plane (plane.so) API? I can look up the official docs and list the exact permitted values — want me to fetch that now?
---
🏁 Script executed:
```shell
#!/bin/bash
# Search for API response examples, fixtures, or references to grouped_by, sub_grouped_by, extra_stats
rg -nC5 "grouped_by|sub_grouped_by|extra_stats" --type=ts --type=js --type=json
Length of output: 2088
---
🏁 Script executed:
```shell
#!/bin/bash
# Check how IssuesResponse is used in the codebase
echo "=== Searching for IssuesResponse usage ==="
rg -nC3 "IssuesResponse" --type=ts --type=js
echo -e "\n=== Checking for makePlaneRequest calls to issues endpoint ==="
rg -nC5 "makePlaneRequest.*issues|/issues" --type=ts --type=js
echo -e "\n=== Looking for test files or mock data ==="
fd -e "test\|spec\|mock\|fixture" --type f
echo -e "\n=== Searching for any Plane API version info or documentation references ==="
rg -nC2 "plane\.so|developers\.plane|API.*version" --type=ts --type=js --type=md
Length of output: 9275
---
🏁 Script executed:
```shell
#!/bin/bash
# Check Plane source code for API response schemas
# Try to find issues API response definition
rg -nC5 "grouped_by|sub_grouped_by" --type=py --type=json -g "*.py" -g "*.json"
# Also check if there are any import statements or API schema definitions
echo -e "\n=== Checking for schema or serializer files ==="
fd -e "schema" -e "serializer" -e "response" | head -20
Length of output: 48
---
🌐 Web query:
```web
Plane API list issues endpoint response schema grouped_by sub_grouped_by
💡 Result:
The List Issues response includes top-level keys grouped_by and sub_grouped_by. Type: string | null — they contain the field name used to group results (or null when not grouped). Example (from Plane dummy response): "grouped_by": null, "sub_grouped_by": null. [1][2]
Sources:
- Plane API — List issues (response/pagination description). [1]
- Example/dummy JSON showing grouped_by and sub_grouped_by. [2]
Update field types to match Plane API schema.
The IssuesResponse type (lines 8, 9, 18) has types that are too narrow and don't match the documented Plane API response schema:
grouped_byandsub_grouped_byshould bestring | nullper Plane API docs—they contain the grouping field name when grouping is applied, ornullwhen not groupedextra_statsshould beRecord<string, any> | nullper API documentation (shown as{}in responses, notnull)
The same issue exists in src/tools/projects.ts with the identical ProjectsResponse type definition.
Update both files:
type IssuesResponse = {
- grouped_by: null;
- sub_grouped_by: null;
+ grouped_by: string | null;
+ sub_grouped_by: string | null;
total_count: number;
next_cursor: string;
prev_cursor: string;
next_page_results: boolean;
prev_page_results: boolean;
count: number;
total_pages: number;
total_results: number;
- extra_stats: null;
+ extra_stats: Record<string, any> | null;
results: Issue[];
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type IssuesResponse = { | |
| grouped_by: null; | |
| sub_grouped_by: null; | |
| total_count: number; | |
| next_cursor: string; | |
| prev_cursor: string; | |
| next_page_results: boolean; | |
| prev_page_results: boolean; | |
| count: number; | |
| total_pages: number; | |
| total_results: number; | |
| extra_stats: null; | |
| results: Issue[]; | |
| }; | |
| type IssuesResponse = { | |
| grouped_by: string | null; | |
| sub_grouped_by: string | null; | |
| total_count: number; | |
| next_cursor: string; | |
| prev_cursor: string; | |
| next_page_results: boolean; | |
| prev_page_results: boolean; | |
| count: number; | |
| total_pages: number; | |
| total_results: number; | |
| extra_stats: Record<string, any> | null; | |
| results: Issue[]; | |
| }; |
🤖 Prompt for AI Agents
In src/tools/issues.ts around lines 7 to 20, update the IssuesResponse type so
that grouped_by and sub_grouped_by are typed as string | null (they hold the
grouping field name or null) and change extra_stats to Record<string, any> |
null (API returns an object or null); apply the same changes to the identical
ProjectsResponse type in src/tools/projects.ts so both response types match the
Plane API schema.
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.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/tools/issues.ts (1)
26-39: Update IssuesResponse type to match Plane API schema.As noted in the previous review, the
grouped_by,sub_grouped_by, andextra_statsfields are typed too narrowly:
grouped_byandsub_grouped_byshould bestring | null(they contain the grouping field name or null)extra_statsshould beRecord<string, any> | null(API returns an object or null)
🧹 Nitpick comments (1)
src/tools/issues.ts (1)
42-100: Well-implemented token usage optimization.The new
list_project_issuestool effectively reduces token usage by mapping to a simplified structure with only essential fields. The fallback logic for state and priority details handles various API response shapes defensively.Consider adding a brief comment explaining the priority fallback logic (lines 57-61), as the handling of both object and string priority values may not be immediately obvious:
const simplifiedIssues = issuesResponse.results.map((issue) => { const stateDetail = issue.state_detail ?? null; + // Priority can be either a UUID string or an object with details const priorityDetail = issue.priority_detail ?? (typeof issue.priority === "object" && issue.priority !== null ? (issue.priority as IssuePrioritySummary) : null);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/tools/issues.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/tools/issues.ts (2)
src/schemas.ts (2)
Issue(38-68)Issue(69-69)src/common/request-helper.ts (1)
makePlaneRequest(3-36)
🔇 Additional comments (3)
src/tools/issues.ts (3)
5-5: LGTM: Clean type/schema separation.The type-only import and renaming convention clearly distinguishes the runtime schema from the type definition.
41-41: LGTM: Explicit return type improves clarity.The explicit
: voidreturn type improves type safety and is consistent with similar tool registration functions in the codebase.
104-107: LGTM: Improved documentation clarity.The enhanced descriptions with concrete examples (e.g., FIRST-123) make the readable identifier pattern immediately clear to users.
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.
Description
This PR adds a new MCP tool
list_project_issuesto retrieve all issues for a specific project.Background:
The current MCP server only provides tools to list issues within modules (
list_module_issues) or cycles (list_cycle_issues), but lacks a general tool to list all issues in a project. This makes it difficult for LLM agents to:Changes:
list_project_issuestool insrc/tools/issues.tsIssuesResponsetype definition matching Plane API response structureregisterIssueTools(): void)get_issue_using_readable_identifierfor clarityAPI Usage Example:
Type of Change
After: New
list_project_issuestool availableTest Scenarios
Manual Testing:
npm run build)npm run lint)npm run format:check)IssuesResponsetypeIntegration Testing:
plane_list_project_issueswith correct parametersCode Quality:
References
list_module_issuesandlist_cycle_issuestoolsget_projectstool implementation (seesrc/tools/projects.ts)Summary by CodeRabbit
New Features
Documentation
Chores / Style