Skip to content

feat(deck): Add card discovery (list_board_cards) and card comment tools#155

Merged
marcelklehr merged 3 commits intonextcloud:mainfrom
Pavlinchen:feat/deck-card-comments
Apr 27, 2026
Merged

feat(deck): Add card discovery (list_board_cards) and card comment tools#155
marcelklehr merged 3 commits intonextcloud:mainfrom
Pavlinchen:feat/deck-card-comments

Conversation

@Pavlinchen
Copy link
Copy Markdown
Contributor

@Pavlinchen Pavlinchen commented Apr 22, 2026

Summary

  • Adds a new list_board_cards safe tool that lists cards in a Deck board with structured metadata (stack, labels, assignees, due date, archived status, done status, comments count)
  • Adds 4 new card comment tools: list_card_comments, add_card_comment, update_card_comment, delete_card_comment
  • Comments use the Deck OCS API, accessed via nc.ocs() (same pattern as shares.py); comment endpoints support threaded replies via optional parent_id on add_card_comment
  • Updates three existing docstrings (add_card_label, assign_card_to_user, delete_card) to point card_id lookups at list_board_cards instead of list_boards, which does not actually return cards

Motivation

Two gaps in one PR, in the same file:

Card discovery was raised in #127 during review:

Deck assign card (impossible to target an existing card by name, it only works right after a card has been added so the agent knows its ID, there could be a "list board cards" tool with an optional list ID param)

The unified search tool works for keyword lookups but does not enumerate cards in a board and does not return the structured metadata (stack, labels, assignees, due date, archived) that an agent typically needs to reason about which card to act on. list_board_cards fills that gap.

Card comments are a core Deck collaboration feature — users discuss tasks directly on cards. The existing Deck tools only support board/card/label/assignment operations but cannot read or write comments. This is a common request when using the AI assistant to interact with project boards.

Implementation Details

Disclaimer

Implementation from a technical perspective was done mainly by a LLM (Claude Opus 4.7 max effort).
Every tool and endpoint response shape was validated end-to-end against Nextcloud 32.0.8 + Deck 1.16.3, with a full lifecycle smoke test completed before opening the PR.

list_board_cards

Uses the existing REST endpoint GET /index.php/apps/deck/api/v1.0/boards/{board_id}/stacks, which already returns cards nested inside stacks. The tool flattens that shape for agent consumption and strips internal fields (ETag, lastModified, order, referenceData, attachments, overdue, type, owner, commentsUnread, deletedAt) that are not relevant for tool use.

Returned shape:

[
  {
    "id": 6,
    "title": "Implement TOTP 2FA support",
    "description": "...",
    "stack_id": 5,
    "stack_title": "Backlog",
    "labels": [{"id": 5, "title": "Read more inside", "color": "CC317C"}],
    "assignees": [{"uid": "admin", "displayname": "admin"}],
    "due_date": "2026-03-15T00:00:00+00:00",
    "archived": false,
    "done": null,
    "comments_count": 2
  },
  ...
]

Parameters:

  • board_id: int (required) — obtainable with list_boards
  • stack_id: Optional[int] — optional client-side filter to a single stack; useful for "what's in the To Do column"

Decorator: @safe_tool (read-only).

Card comments

The Deck app registers comment endpoints as OCS routes (in appinfo/routes.php under the 'ocs' key), so these tools use nc.ocs() rather than the adapter-based HTTP calls used by the existing board/card tools. This is consistent with how shares.py and contacts.py handle OCS endpoints.

Tool Decorator OCS Endpoint
list_card_comments @safe_tool GET /ocs/v2.php/apps/deck/api/v1.0/cards/{cardId}/comments
add_card_comment @dangerous_tool POST /ocs/v2.php/apps/deck/api/v1.0/cards/{cardId}/comments
update_card_comment @dangerous_tool PUT /ocs/v2.php/apps/deck/api/v1.0/cards/{cardId}/comments/{commentId}
delete_card_comment @dangerous_tool DELETE /ocs/v2.php/apps/deck/api/v1.0/cards/{cardId}/comments/{commentId}

Test Plan

Tested against Nextcloud 32.0.8 + Deck 1.16.4:

list_board_cards:

  • Returns all cards in a board (35 cards across 5 stacks on test board)
  • stack_id filter correctly limits to one stack (19 cards, all with stack_id == 5)
  • Cards with labels return [{id, title, color}] shape
  • Cards with assignees return [{uid, displayname}] shape (verified via assign/unassign round-trip)
  • due_date returns ISO 8601 or null
  • archived, done, comments_count present on every card
  • Non-existent stack_id returns empty list (no error)

Card comments:

  • Tested all 4 endpoints against Nextcloud 32.0.8 with curl
  • Verified create returns comment with id, message, actorId, creationDateTime
  • Verified list returns array of comments
  • Verified update changes message text, returns updated comment
  • Verified delete returns empty data, subsequent list confirms removal
  • Verified threaded reply support (parentId parameter)
  • Integration test with Context Agent MCP server (requires running ExApp)

Extend the Deck tool module with one discovery tool and four comment
tools, together addressing a gap where the agent could not target
existing cards by name or interact with card discussions.

Card discovery (1 tool):
- list_board_cards: list all cards in a board with metadata (stack,
  labels, assignees, due date, archived status, done, comments count).
  Optional stack_id filter limits to a single stack. Fills the gap
  raised in nextcloud#127 where add_card, add_card_label, assign_card_to_user,
  and delete_card all require a card_id the agent otherwise cannot
  discover (the unified search tool works for keyword lookups but does
  not enumerate and does not return structured metadata).

Card comments (4 tools):
- list_card_comments: list all comments on a card with pagination
- add_card_comment: create a comment, with optional threaded reply support
- update_card_comment: edit an existing comment (author-only)
- delete_card_comment: remove a comment (author-only)

list_board_cards uses the existing /boards/{boardId}/stacks REST
endpoint via the adapter pattern consistent with the other Deck
tools, and flattens the nested stack-cards shape for agent use while
stripping internal fields (ETag, lastModified, order, etc.).

Comments use the Deck OCS API via nc.ocs(), consistent with how
shares.py and other OCS-based tools work. The existing board/card
tools (REST API) are unchanged except for docstring corrections
pointing card_id lookups at list_board_cards instead of list_boards
(which does not return cards).

Tested against Nextcloud 32.0.8 with Deck 1.16.4.

Signed-off-by: Pavlinchen <paulm.schmidt@icloud.com>
@Pavlinchen Pavlinchen force-pushed the feat/deck-card-comments branch from a8afbf4 to 0064aa7 Compare April 22, 2026 05:42
@Pavlinchen Pavlinchen changed the title feat(deck): Add card comment tools (list, create, update, delete) feat(deck): Add card discovery (list_board_cards) and card comment tools Apr 22, 2026
Comment thread ex_app/lib/all_tools/deck.py Outdated
@marcelklehr
Copy link
Copy Markdown
Member

Tested all tools and confirmed this to work.

Append a short disclaimer to messages posted by add_card_comment
("Posted by Nextcloud AI Assistant.") and update_card_comment
("Edited by Nextcloud AI Assistant.") so Deck users can distinguish
AI-generated comments from human-authored ones.

Matches the convention already used by add_card (description),
send_message_to_conversation, reply_to_message, and share_file_to_conversation
in this codebase, and addresses EU AI Act Article 50(4) disclosure
requirements for text generated by an AI system.

Only the two messaging tools are affected; list_card_comments and
delete_card_comment do not produce user-visible text.

Signed-off-by: Pavlinchen <paulm.schmidt@icloud.com>
Comment thread ex_app/lib/all_tools/deck.py Outdated
Wrap the return value of list_card_comments, add_card_comment,
update_card_comment, and delete_card_comment with json.dumps(),
matching the convention already used by every other tool in this
module (list_boards, list_board_cards, add_card, etc.).

Some OpenAI API implementations error on non-string tool outputs,
per maintainer review feedback on nextcloud#155.

Signed-off-by: Pavlinchen <paulm.schmidt@icloud.com>
@marcelklehr marcelklehr merged commit 57d7fe2 into nextcloud:main Apr 27, 2026
9 of 10 checks passed
@Pavlinchen
Copy link
Copy Markdown
Contributor Author

Thanks for the great collaboration and merging! :)

See you in the next PR ;)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants