Skip to content

馃殌 Feature: Work item archive/unarchive endpoints in the public API (parity with Python SDK & MCP server)#9452

Description

@mwatola-glitch

Summary

The public REST API (apps/api/plane/api/) has no archive/unarchive endpoints for work items, while the official plane-python-sdk and plane-mcp-server both publish this capability. As a result, the official toolchain fails with HTTP 404 against self-hosted / Community Edition instances.

Current state

The SDK exposes (plane/api/work_items/base.py):

  • work_items.archive() -> POST /{slug}/projects/{project_id}/work-items/{id}/archive
  • work_items.unarchive() -> DELETE /{slug}/projects/{project_id}/work-items/{id}/unarchive
  • work_items.list_archived() -> GET /{slug}/projects/{project_id}/archived-work-items

The MCP server builds on it (plane_mcp/tools/work_items.py): manage_work_item_archive, list_archived_work_items.

The server, however, only implements archive endpoints for cycles and modules in the public API (apps/api/plane/api/urls/cycle.py, module.py) - apps/api/plane/api/urls/work_item.py has no archive routes at all (verified on preview and on the v1.3.1 release).

The feature itself exists server-side - the internal app API has it (apps/api/plane/app/urls/issue.py: POST .../issues/<pk>/archive/, used by the web UI) - so this is purely a public API surface gap, not new functionality.

Impact

Calling manage_work_item_archive (MCP) or client.work_items.archive(...) (SDK) against a self-hosted instance returns HTTP 404. There is no workaround via the public API; the only way to archive a work item is the web UI.

Proposal

Add an IssueArchiveUnarchiveAPIEndpoint to apps/api/plane/api/views/issue.py, mirroring:

  • the existing CycleArchiveUnarchiveAPIEndpoint pattern (same URL/verb structure), and
  • the internal app archive semantics (apps/api/plane/app/views/issue/archive.py): only work items whose state group is completed or cancelled can be archived; issue_activity is emitted; unarchive restores the item.

Routes registered in both URL families of urls/work_item.py:

  • POST .../work-items/<pk>/archive/ (+ deprecated /issues/ alias)
  • DELETE .../work-items/<pk>/unarchive/ (+ alias)
  • GET .../archived-work-items/ (+ archived-issues/ alias)

matching the paths already published by the SDK.

I have a working implementation with contract tests and will open a PR referencing this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions