feat: add epic tools for managing epics#63
feat: add epic tools for managing epics#63jessedijkstra wants to merge 1 commit intomakeplane:canaryfrom
Conversation
📝 WalkthroughWalkthroughAdds Epic management: new Changes
Sequence Diagram(s)sequenceDiagram
participant Test as Integration Test
participant MCP as MCP Server
participant Client as Plane Client
participant API as Plane API
rect rgba(200,200,255,0.5)
Test->>MCP: register_epic_tools()
MCP->>MCP: register tool endpoints
end
rect rgba(200,255,200,0.5)
Test->>MCP: create_epic(project_id, payload)
MCP->>Client: resolve epic work item type
Client->>API: GET work item types
API-->>Client: types list
Client-->>MCP: type ID
MCP->>Client: create work item (epic)
Client->>API: POST work item
API-->>Client: created work item
Client-->>MCP: Epic object
MCP-->>Test: return Epic
end
rect rgba(255,240,200,0.5)
Test->>MCP: list_epics(project_id, params)
MCP->>Client: list work items filtered by epic type
Client->>API: GET paginated work items
API-->>Client: paginated epics
Client-->>MCP: PaginatedEpicResponse
MCP-->>Test: epic list
end
rect rgba(255,200,200,0.5)
Test->>MCP: delete_epic(project_id, epic_id)
MCP->>Client: delete work item by ID
Client->>API: DELETE work item
API-->>Client: deletion confirmed
Client-->>MCP: success
MCP-->>Test: deletion acknowledged
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
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 |
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. Tip You can enable review details to help with troubleshooting, context usage and more.Enable the ✨ 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 |
2 similar comments
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. Tip You can enable review details to help with troubleshooting, context usage and more.Enable the ✨ 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 |
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. Tip You can enable review details to help with troubleshooting, context usage and more.Enable the ✨ 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 |
📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
3 similar comments
📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In `@plane_mcp/tools/epics.py`:
- Around line 37-52: Docstrings for list_epics, create_epic, update_epic, and
retrieve_epic contain parameters (workspace_slug, expand, fields, order_by,
external_id, external_source) that are not in those functions' signatures;
update each function's docstring to exactly match its actual parameters and
return description used by the MCP/LLM layer (remove all phantom parameters or
add them only if you also add them to the function signature). Specifically,
edit the docstrings in functions named list_epics, create_epic, update_epic, and
retrieve_epic so the Args section lists only the real parameters present in
their definitions and remove any references to workspace_slug, expand, fields,
order_by, external_id, and external_source unless you also implement those as
real parameters.
- Line 242: The docstring contains a grammar issue: change the text "Retrieve a
epic by ID." to "Retrieve an epic by ID." in the function/class docstring where
that exact string appears (search for the literal "Retrieve a epic by ID." to
locate the docstring to update).
- Line 171: The function's return type annotation is incorrect: it currently
declares WorkItem but actually returns an Epic from client.epics.retrieve(...);
change the function's signature to return Epic (matching create_epic and
retrieve_epic) and update any type imports if necessary so Epic is available in
the module; ensure the docstring/typed usages that expect WorkItem are adjusted
to Epic where this function (which calls client.epics.retrieve) is referenced.
- Around line 118-121: The code currently silently coerces invalid priority
values to None (see the validated_priority assignment using PriorityEnum) which
masks user errors; update both create_epic and update_epic to validate the
incoming priority and raise a ValueError listing allowed values when the
provided priority is not one of get_args(PriorityEnum) instead of assigning
None—use the existing PriorityEnum and get_args(PriorityEnum) to build the error
message so callers/LLM receive actionable feedback.
- Line 114: Check the result of _get_epic_work_item_type_id() before passing it
to CreateWorkItem: if _get_epic_work_item_type_id() returns None, do not call
CreateWorkItem with a None type_id—either raise a clear exception (e.g.,
ValueError with context), log an informative error and return/abort, or fall
back to an explicit default type id. Update the code around the
work_item_type_id variable so CreateWorkItem is only invoked when
work_item_type_id is non-None, and include a descriptive message that references
the workspace and intent to create an epic to aid debugging.
In `@tests/test_integration.py`:
- Around line 126-127: Several print statements (e.g., the call print(f"Creating
epic...") and other print(...) lines flagged by Ruff F541) use f-strings with no
interpolations; remove the unnecessary f prefix so they are plain string
literals. Locate the plain print calls in tests/test_integration.py (the
print(f"...") instances around the epic/work item creation and the other flagged
lines) and change them from f"..." to "..." for each occurrence.
- Around line 163-164: The test assumes extract_result(epics_result) returns a
paginated dict with a "results" key but list_epics actually returns a flat
list[Epic]; update the test to treat epics as a list (e.g., iterate epics or
access epic['id'] directly) or change extract_result to wrap the list in
{"results": ...}; specifically, modify the test lines using epics['results'] to
use epics (the list returned by list_epics) or adjust extract_result so that
when given a list it returns {"results": list} and keep references to list_epics
and extract_result to locate the code.
🧹 Nitpick comments (1)
plane_mcp/tools/epics.py (1)
20-29:_get_epic_work_item_type_idcreates its own client context, causing a redundant call.
create_epiccalls_get_epic_work_item_type_id()(line 114) which invokesget_plane_client_context(), and then immediately calls it again (line 116). Consider refactoring the helper to accept the client and workspace_slug as parameters, or returning them alongside the type ID.
plane_mcp/tools/epics.py
Outdated
| """ | ||
| List all epics in a project. | ||
|
|
||
| Args: | ||
| workspace_slug: The workspace slug identifier | ||
| project_id: UUID of the project | ||
| cursor: Pagination cursor for getting next set of results | ||
| per_page: Number of results per page (1-100) | ||
| expand: Comma-separated list of related fields to expand in response | ||
| fields: Comma-separated list of fields to include in response | ||
| order_by: Field to order results by. Prefix with '-' for descending order | ||
| external_id: External system identifier for filtering or lookup | ||
| external_source: External system source name for filtering or lookup | ||
|
|
||
| Returns: | ||
| List of WorkItem objects |
There was a problem hiding this comment.
Docstring lists parameters not present in the function signature.
The docstring references workspace_slug, expand, fields, order_by, external_id, and external_source, but none of these are actual parameters of list_epics. Since these docstrings serve as tool descriptions for the MCP/LLM layer, phantom parameters will confuse the model. The same issue applies to the docstrings of create_epic (line 93), update_epic (line 176), and retrieve_epic (line 245) which all list workspace_slug.
🤖 Prompt for AI Agents
In `@plane_mcp/tools/epics.py` around lines 37 - 52, Docstrings for list_epics,
create_epic, update_epic, and retrieve_epic contain parameters (workspace_slug,
expand, fields, order_by, external_id, external_source) that are not in those
functions' signatures; update each function's docstring to exactly match its
actual parameters and return description used by the MCP/LLM layer (remove all
phantom parameters or add them only if you also add them to the function
signature). Specifically, edit the docstrings in functions named list_epics,
create_epic, update_epic, and retrieve_epic so the Args section lists only the
real parameters present in their definitions and remove any references to
workspace_slug, expand, fields, order_by, external_id, and external_source
unless you also implement those as real parameters.
| # Validate priority against allowed literal values | ||
| validated_priority: PriorityEnum | None = ( | ||
| priority if priority in get_args(PriorityEnum) else None # type: ignore[assignment] | ||
| ) |
There was a problem hiding this comment.
Silent coercion of invalid priority to None can mask user errors.
If a caller passes priority="critical" (an invalid value), it silently becomes None rather than surfacing the mistake. This same pattern is duplicated in update_epic (lines 200-203). Consider raising a ValueError with the allowed values so the LLM/user gets actionable feedback.
Proposed fix (apply similarly in update_epic)
- validated_priority: PriorityEnum | None = (
- priority if priority in get_args(PriorityEnum) else None # type: ignore[assignment]
- )
+ valid_priorities = get_args(PriorityEnum)
+ if priority is not None and priority not in valid_priorities:
+ raise ValueError(f"Invalid priority '{priority}'. Must be one of: {valid_priorities}")
+ validated_priority: PriorityEnum | None = priority # type: ignore[assignment]📝 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.
| # Validate priority against allowed literal values | |
| validated_priority: PriorityEnum | None = ( | |
| priority if priority in get_args(PriorityEnum) else None # type: ignore[assignment] | |
| ) | |
| # Validate priority against allowed literal values | |
| valid_priorities = get_args(PriorityEnum) | |
| if priority is not None and priority not in valid_priorities: | |
| raise ValueError(f"Invalid priority '{priority}'. Must be one of: {valid_priorities}") | |
| validated_priority: PriorityEnum | None = priority # type: ignore[assignment] |
🤖 Prompt for AI Agents
In `@plane_mcp/tools/epics.py` around lines 118 - 121, The code currently silently
coerces invalid priority values to None (see the validated_priority assignment
using PriorityEnum) which masks user errors; update both create_epic and
update_epic to validate the incoming priority and raise a ValueError listing
allowed values when the provided priority is not one of get_args(PriorityEnum)
instead of assigning None—use the existing PriorityEnum and
get_args(PriorityEnum) to build the error message so callers/LLM receive
actionable feedback.
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
3 similar comments
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThe PR introduces Epic management tooling to the MCP server by adding a new module with list, create, update, and retrieve functions for epics. These tools are registered in the tools initialization and covered by integration tests. The build dependency manager uv is pinned to version 0.9.18. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
3 similar comments
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
2 similar comments
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@tests/test_integration.py`:
- Around line 312-317: The EXPECTED_TOOLS list in tests/test_integration.py is
missing the registered "delete_epic" tool; update the EXPECTED_TOOLS constant to
include "delete_epic" so test_tools_availability verifies it. Locate the
EXPECTED_TOOLS list (the array containing
"list_epics","retrieve_epic","create_epic","update_epic") and add the string
"delete_epic" to that list to match the registration in epics.py and the
integration flow that exercises delete_epic.
🧹 Nitpick comments (1)
plane_mcp/tools/epics.py (1)
20-29: Redundantget_plane_client_context()call —_get_epic_work_item_type_idcreates its own context.
_get_epic_work_item_type_id()(line 22) andcreate_epic(line 116) each independently callget_plane_client_context(). This doubles the auth/context resolution work. Consider passing the client and workspace slug into the helper instead.Proposed refactor
- def _get_epic_work_item_type_id() -> str | None: + def _get_epic_work_item_type_id(client, workspace_slug: str) -> str | None: """Helper function to get the work item type ID for epics.""" - client, workspace_slug = get_plane_client_context() response = client.work_item_types.list(workspace_slug=workspace_slug, project_id="")Then in
create_epic:+ client, workspace_slug = get_plane_client_context() + work_item_type_id = _get_epic_work_item_type_id(client, workspace_slug) - work_item_type_id = _get_epic_work_item_type_id() - - client, workspace_slug = get_plane_client_context()Also applies to: 114-116
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
3 similar comments
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
2 similar comments
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
Add MCP tools for epic management: - list_epics: List all epics in a project - create_epic: Create a new epic - update_epic: Update an existing epic - retrieve_epic: Retrieve a specific epic by ID Also includes: - Integration tests for epic operations - mise.toml for uv version pinning Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Add deleting an epic Update integration tests Address PR review feedback for epic tools - Fix docstrings to only list actual function parameters - Add validation for epic work item type (raise ValueError if not found) - Add priority validation with actionable error messages - Fix update_epic return type from WorkItem to Epic - Fix grammar: "a epic" -> "an epic" - Refactor _get_epic_work_item_type_id to accept client/workspace params - Remove unused WorkItem import - Fix test to handle list_epics returning flat list (not paginated) - Remove extraneous f-string prefixes in test prints - Add delete_epic to EXPECTED_TOOLS Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Fix epics
26a6328 to
b265c06
Compare
Summary
list_epics,create_epic,update_epic, andretrieve_epicmise.tomlfor uv version pinning (0.9.18)Test plan
uv run pytest tests/test_integration.py🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
Tests