Skip to content

[SILO-1196] fix: add work items to plane entity tools#109

Open
Saurabhkmr98 wants to merge 3 commits intomainfrom
fix/add_wi_to_cycle_tool
Open

[SILO-1196] fix: add work items to plane entity tools#109
Saurabhkmr98 wants to merge 3 commits intomainfrom
fix/add_wi_to_cycle_tool

Conversation

@Saurabhkmr98
Copy link
Copy Markdown
Member

@Saurabhkmr98 Saurabhkmr98 commented Apr 16, 2026

Description

  • Added fix to add work items to plane entity tools across cycle module and milestone

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Screenshot 2026-04-16 at 6 40 55 PM Screenshot 2026-04-16 at 6 41 49 PM

Test Scenarios

  • Tested add work items to cycles, modules and milestones

Summary by CodeRabbit

  • Refactor
    • Standardized parameter naming across work item management tools (cycles, milestones, and modules) for consistent API interface.

@makeplane
Copy link
Copy Markdown

makeplane Bot commented Apr 16, 2026

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

Three MCP tool files were updated to rename the issue_ids parameter to work_item_ids across functions for adding work items to cycles, milestones, and modules. The underlying API calls preserve the original issue_ids keyword argument name, ensuring backward compatibility with the client interface.

Changes

Cohort / File(s) Summary
Parameter Rename: MCP Tool Functions
plane_mcp/tools/cycles.py, plane_mcp/tools/milestones.py, plane_mcp/tools/modules.py
Renamed issue_ids: list[str] parameter to work_item_ids: list[str] in add_work_items_to_cycle, add_work_items_to_milestone, remove_work_items_from_milestone, and add_work_items_to_module functions. Updated docstrings to reflect new parameter naming. Client method calls adjusted to use issue_ids=work_item_ids keyword argument, maintaining compatibility with existing API interface.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 Parameter names now align with purpose true,
From issue_ids to work_item_ids we flew,
Three tools refreshed with consistent care,
Semantics clear throughout the air! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and clearly summarizes the main change: renaming the issue_ids parameter to work_item_ids across cycle, module, and milestone MCP tools for semantic clarity.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/add_wi_to_cycle_tool

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
plane_mcp/tools/milestones.py (1)

148-177: Add Returns sections to both changed milestone tool docstrings.

Each has Args only; repository tool docstrings require both Args and Returns.

As per coding guidelines, "Tool docstrings must include Args and Returns sections."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/milestones.py` around lines 148 - 177, Both milestone tool
docstrings are missing a Returns section; update the docstrings for
add_work_items_to_milestone and remove_work_items_from_milestone to include a
Returns section that specifies the return type (None) and a short description
(e.g., "None: performs the operation in-place and returns nothing"), ensuring
both tool functions' docstrings follow the repository guideline requiring Args
and Returns.
plane_mcp/tools/cycles.py (1)

195-202: Add a Returns section to the tool docstring.

This docstring has Args but not Returns, which violates the repo tool-docstring contract.

As per coding guidelines, "Tool docstrings must include Args and Returns sections."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/cycles.py` around lines 195 - 202, The docstring for the
function whose docstring starts "Add work items to a cycle" is missing a Returns
section; update that tool docstring to include a Returns section describing the
return value and type (e.g., success flag, updated cycle object, or None) and
any errors raised, matching the repo's tool-docstring contract; ensure the
Returns entry is concise and placed after Args in the same docstring for the
function referenced by the "Add work items to a cycle" docstring.
plane_mcp/tools/modules.py (1)

212-219: Include a Returns section in this tool docstring.

Args is present, but Returns is missing.

As per coding guidelines, "Tool docstrings must include Args and Returns sections."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/modules.py` around lines 212 - 219, The docstring for the
tool whose summary is "Add work items to a module." is missing a Returns
section; update that docstring to include a Returns block that states the return
type and a one-line description (e.g., Returns: bool: True on success, or
Returns: Module: the updated module object, or Returns: None if nothing is
returned) and ensure the described type and semantics match the actual return
value produced by the function in plane_mcp/tools/modules.py.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plane_mcp/tools/cycles.py`:
- Around line 190-209: The public API rename from issue_ids → work_item_ids
breaks existing callers; update add_work_items_to_cycle to accept both keys
during a deprecation window and forward the correct list to
client.cycles.add_work_items: if caller provided work_item_ids use it, otherwise
accept issue_ids (legacy) and pass that list as the issue_ids argument to
client.cycles.add_work_items; also update any tool schema/argument parsing to
recognize both work_item_ids and issue_ids (mark issue_ids deprecated).

In `@plane_mcp/tools/milestones.py`:
- Around line 143-184: The add_work_items_to_milestone and
remove_work_items_from_milestone functions currently break compatibility by only
accepting work_item_ids and forwarding them as issue_ids to
client.milestones.add_work_items/remove_work_items; update the MCP boundary so
each tool accepts both input keys (work_item_ids and issue_ids), normalizing
them into a single list variable (e.g., resolved_ids) before calling
client.milestones.add_work_items and client.milestones.remove_work_items with
issue_ids=resolved_ids, and handle precedence/validation (prefer work_item_ids
if both provided, or merge/validate) to maintain backward-compatible behavior.

In `@plane_mcp/tools/modules.py`:
- Around line 207-226: The function add_work_items_to_module currently only
accepts work_item_ids which breaks callers using the old name issue_ids; update
the signature to accept both (e.g., work_item_ids: list[str] | None = None,
issue_ids: list[str] | None = None) and normalize them inside the function
(prefer work_item_ids if provided, else use issue_ids) before calling
client.modules.add_work_items with issue_ids=normalized_list; keep parameter
names project_id and module_id unchanged and ensure validation/typing handles
the merged list to preserve backward compatibility.

---

Nitpick comments:
In `@plane_mcp/tools/cycles.py`:
- Around line 195-202: The docstring for the function whose docstring starts
"Add work items to a cycle" is missing a Returns section; update that tool
docstring to include a Returns section describing the return value and type
(e.g., success flag, updated cycle object, or None) and any errors raised,
matching the repo's tool-docstring contract; ensure the Returns entry is concise
and placed after Args in the same docstring for the function referenced by the
"Add work items to a cycle" docstring.

In `@plane_mcp/tools/milestones.py`:
- Around line 148-177: Both milestone tool docstrings are missing a Returns
section; update the docstrings for add_work_items_to_milestone and
remove_work_items_from_milestone to include a Returns section that specifies the
return type (None) and a short description (e.g., "None: performs the operation
in-place and returns nothing"), ensuring both tool functions' docstrings follow
the repository guideline requiring Args and Returns.

In `@plane_mcp/tools/modules.py`:
- Around line 212-219: The docstring for the tool whose summary is "Add work
items to a module." is missing a Returns section; update that docstring to
include a Returns block that states the return type and a one-line description
(e.g., Returns: bool: True on success, or Returns: Module: the updated module
object, or Returns: None if nothing is returned) and ensure the described type
and semantics match the actual return value produced by the function in
plane_mcp/tools/modules.py.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd410fd3-dc59-4d30-821b-29bdf990fc32

📥 Commits

Reviewing files that changed from the base of the PR and between 24565ab and b35052b.

📒 Files selected for processing (3)
  • plane_mcp/tools/cycles.py
  • plane_mcp/tools/milestones.py
  • plane_mcp/tools/modules.py

Comment thread plane_mcp/tools/cycles.py
Comment on lines 190 to 209
def add_work_items_to_cycle(
project_id: str,
cycle_id: str,
issue_ids: list[str],
work_item_ids: list[str],
) -> None:
"""
Add work items to a cycle.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
cycle_id: UUID of the cycle
issue_ids: List of work item IDs to add to the cycle
work_item_ids: List of work item UUIDs to add to the cycle
"""
client, workspace_slug = get_plane_client_context()
client.cycles.add_work_items(
workspace_slug=workspace_slug,
project_id=project_id,
cycle_id=cycle_id,
issue_ids=issue_ids,
issue_ids=work_item_ids,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

issue_idswork_item_ids rename is breaking for existing MCP callers.

This change removes the old argument key from the tool schema; clients still sending issue_ids will fail argument validation. If this PR is intended to stay non-breaking, accept both keys for a deprecation window.

Suggested backward-compatible patch
     `@mcp.tool`()
     def add_work_items_to_cycle(
         project_id: str,
         cycle_id: str,
-        work_item_ids: list[str],
+        work_item_ids: list[str] | None = None,
+        issue_ids: list[str] | None = None,
     ) -> None:
@@
-            work_item_ids: List of work item UUIDs to add to the cycle
+            work_item_ids: List of work item UUIDs to add to the cycle (preferred)
+            issue_ids: Deprecated alias for backward compatibility
         """
+        resolved_ids = work_item_ids if work_item_ids is not None else issue_ids
+        if not resolved_ids:
+            raise ValueError("Provide `work_item_ids` (preferred) or `issue_ids`.")
+
         client, workspace_slug = get_plane_client_context()
         client.cycles.add_work_items(
             workspace_slug=workspace_slug,
             project_id=project_id,
             cycle_id=cycle_id,
-            issue_ids=work_item_ids,
+            issue_ids=resolved_ids,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/cycles.py` around lines 190 - 209, The public API rename from
issue_ids → work_item_ids breaks existing callers; update
add_work_items_to_cycle to accept both keys during a deprecation window and
forward the correct list to client.cycles.add_work_items: if caller provided
work_item_ids use it, otherwise accept issue_ids (legacy) and pass that list as
the issue_ids argument to client.cycles.add_work_items; also update any tool
schema/argument parsing to recognize both work_item_ids and issue_ids (mark
issue_ids deprecated).

Comment on lines 143 to 184
def add_work_items_to_milestone(
project_id: str,
milestone_id: str,
issue_ids: list[str],
work_item_ids: list[str],
) -> None:
"""
Add work items to a milestone.

Args:
project_id: UUID of the project
milestone_id: UUID of the milestone
issue_ids: List of work item IDs to add to the milestone
work_item_ids: List of work item UUIDs to add to the milestone
"""
client, workspace_slug = get_plane_client_context()
client.milestones.add_work_items(
workspace_slug=workspace_slug,
project_id=project_id,
milestone_id=milestone_id,
issue_ids=issue_ids,
issue_ids=work_item_ids,
)

@mcp.tool()
def remove_work_items_from_milestone(
project_id: str,
milestone_id: str,
issue_ids: list[str],
work_item_ids: list[str],
) -> None:
"""
Remove work items from a milestone.

Args:
project_id: UUID of the project
milestone_id: UUID of the milestone
issue_ids: List of work item IDs to remove from the milestone
work_item_ids: List of work item UUIDs to remove from the milestone
"""
client, workspace_slug = get_plane_client_context()
client.milestones.remove_work_items(
workspace_slug=workspace_slug,
project_id=project_id,
milestone_id=milestone_id,
issue_ids=issue_ids,
issue_ids=work_item_ids,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Both milestone tools introduce a breaking input-key rename.

issue_ids is no longer accepted at the MCP boundary in both add/remove functions, so existing clients can fail. For non-breaking behavior, accept both keys during migration.

Suggested backward-compatible patch for both functions
     def add_work_items_to_milestone(
         project_id: str,
         milestone_id: str,
-        work_item_ids: list[str],
+        work_item_ids: list[str] | None = None,
+        issue_ids: list[str] | None = None,
     ) -> None:
@@
-            work_item_ids: List of work item UUIDs to add to the milestone
+            work_item_ids: List of work item UUIDs to add to the milestone (preferred)
+            issue_ids: Deprecated alias for backward compatibility
         """
+        resolved_ids = work_item_ids if work_item_ids is not None else issue_ids
+        if not resolved_ids:
+            raise ValueError("Provide `work_item_ids` (preferred) or `issue_ids`.")
+
         client, workspace_slug = get_plane_client_context()
         client.milestones.add_work_items(
@@
-            issue_ids=work_item_ids,
+            issue_ids=resolved_ids,
         )

     def remove_work_items_from_milestone(
         project_id: str,
         milestone_id: str,
-        work_item_ids: list[str],
+        work_item_ids: list[str] | None = None,
+        issue_ids: list[str] | None = None,
     ) -> None:
@@
-            work_item_ids: List of work item UUIDs to remove from the milestone
+            work_item_ids: List of work item UUIDs to remove from the milestone (preferred)
+            issue_ids: Deprecated alias for backward compatibility
         """
+        resolved_ids = work_item_ids if work_item_ids is not None else issue_ids
+        if not resolved_ids:
+            raise ValueError("Provide `work_item_ids` (preferred) or `issue_ids`.")
+
         client, workspace_slug = get_plane_client_context()
         client.milestones.remove_work_items(
@@
-            issue_ids=work_item_ids,
+            issue_ids=resolved_ids,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/milestones.py` around lines 143 - 184, The
add_work_items_to_milestone and remove_work_items_from_milestone functions
currently break compatibility by only accepting work_item_ids and forwarding
them as issue_ids to client.milestones.add_work_items/remove_work_items; update
the MCP boundary so each tool accepts both input keys (work_item_ids and
issue_ids), normalizing them into a single list variable (e.g., resolved_ids)
before calling client.milestones.add_work_items and
client.milestones.remove_work_items with issue_ids=resolved_ids, and handle
precedence/validation (prefer work_item_ids if both provided, or merge/validate)
to maintain backward-compatible behavior.

Comment on lines 207 to 226
def add_work_items_to_module(
project_id: str,
module_id: str,
issue_ids: list[str],
work_item_ids: list[str],
) -> None:
"""
Add work items to a module.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
module_id: UUID of the module
issue_ids: List of work item IDs to add to the module
work_item_ids: List of work item UUIDs to add to the module
"""
client, workspace_slug = get_plane_client_context()
client.modules.add_work_items(
workspace_slug=workspace_slug,
project_id=project_id,
module_id=module_id,
issue_ids=issue_ids,
issue_ids=work_item_ids,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Renamed tool argument drops backward compatibility for issue_ids callers.

The MCP tool now only accepts work_item_ids; older integrations using issue_ids will break. Consider supporting both names temporarily.

Suggested backward-compatible patch
     `@mcp.tool`()
     def add_work_items_to_module(
         project_id: str,
         module_id: str,
-        work_item_ids: list[str],
+        work_item_ids: list[str] | None = None,
+        issue_ids: list[str] | None = None,
     ) -> None:
@@
-            work_item_ids: List of work item UUIDs to add to the module
+            work_item_ids: List of work item UUIDs to add to the module (preferred)
+            issue_ids: Deprecated alias for backward compatibility
         """
+        resolved_ids = work_item_ids if work_item_ids is not None else issue_ids
+        if not resolved_ids:
+            raise ValueError("Provide `work_item_ids` (preferred) or `issue_ids`.")
+
         client, workspace_slug = get_plane_client_context()
         client.modules.add_work_items(
             workspace_slug=workspace_slug,
             project_id=project_id,
             module_id=module_id,
-            issue_ids=work_item_ids,
+            issue_ids=resolved_ids,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plane_mcp/tools/modules.py` around lines 207 - 226, The function
add_work_items_to_module currently only accepts work_item_ids which breaks
callers using the old name issue_ids; update the signature to accept both (e.g.,
work_item_ids: list[str] | None = None, issue_ids: list[str] | None = None) and
normalize them inside the function (prefer work_item_ids if provided, else use
issue_ids) before calling client.modules.add_work_items with
issue_ids=normalized_list; keep parameter names project_id and module_id
unchanged and ensure validation/typing handles the merged list to preserve
backward compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants