Skip to content

I gotta have more tools - #127

Merged
marcelklehr merged 31 commits into
mainfrom
feat/moartools
Mar 25, 2026
Merged

I gotta have more tools#127
marcelklehr merged 31 commits into
mainfrom
feat/moartools

Conversation

@marcelklehr

@marcelklehrmarcelklehr commented Mar 11, 2026

Copy link
Copy Markdown
Member

@janepie maybe we can share reviewing and testing these together?

Reviewed and tested works:

  • bookmarks
  • tasks: Works
  • circles: Works, although deleting members and circles doesn't seem to work for me on stable33
  • cookbook: Mostly works. Updating recipes doesn't work, though
  • deck
  • files
  • forms
  • mail: broken, list_mail_folders uses a nonexistent route and everything else depends on that
  • music
  • news
  • notes
  • passwords
  • polls
  • sharing

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR significantly expands the available “all_tools” integrations by adding new tool modules for multiple Nextcloud apps (e.g., Shares, Polls, Photos, Passwords, Notes, News, Music, Forms, Bookmarks, Circles, Cookbook) and extending existing tool sets (Files, Deck, Calendar, Mail).

Changes:

  • Add many new tool modules exposing Nextcloud app APIs via @tool functions (safe/dangerous).
  • Extend existing tools for Files (WebDAV ops + tags), Deck (card operations), Calendar (task operations), and Mail (folder/message helpers).
  • Introduce new per-app availability gating via is_available for most new modules.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
ex_app/lib/all_tools/shares.pyNew sharing + groups tools (list/create/update/delete shares, group info)
ex_app/lib/all_tools/polls.pyNew Polls tools (list, details, create/options/votes, close/reopen)
ex_app/lib/all_tools/photos.pyNew Photos tools (albums CRUD, album membership changes, date search)
ex_app/lib/all_tools/passwords.pyNew Passwords tools (folders, search/list, CRUD incl. secret retrieval)
ex_app/lib/all_tools/notes.pyNew Notes tools (list/get/create/update/delete + client-side search)
ex_app/lib/all_tools/news.pyNew News/RSS tools (feeds/folders/items + mark read/unread)
ex_app/lib/all_tools/music.pyNew Music tools (library browsing/search + playlist CRUD)
ex_app/lib/all_tools/forms.pyNew Forms tools (list/details/create/questions/responses/settings)
ex_app/lib/all_tools/bookmarks.pyNew Bookmarks tools (list/search + bookmark/folder/tag management)
ex_app/lib/all_tools/circles.pyNew Circles/Teams tools (CRUD circles + membership + share to circle)
ex_app/lib/all_tools/cookbook.pyNew Cookbook tools (recipes CRUD + categories + search)
ex_app/lib/all_tools/files.pyAdds WebDAV file ops + file tagging tools
ex_app/lib/all_tools/deck.pyExpands Deck tooling for card lifecycle, labels, assignments, comments
ex_app/lib/all_tools/calendar.pyAdds task list/complete/update/delete tools (CalDAV todos)
ex_app/lib/all_tools/mail.pyAdds folder listing, message listing/search, move/delete helpers

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment threadex_app/lib/all_tools/shares.py
Comment threadex_app/lib/all_tools/forms.py
Comment threadex_app/lib/all_tools/passwords.py Outdated
Comment threadex_app/lib/all_tools/notes.py Outdated
Comment threadex_app/lib/all_tools/news.py Outdated
Comment threadex_app/lib/all_tools/shares.py
marcelklehrand others added 2 commits March 11, 2026 14:47
CopilotAIand others added 8 commits March 17, 2026 22:07
- deck.py: Fix list_boards() returning response.text instead of response.json()
- mail.py: Fix wrong docstring on get_mail_account_list(), rewrite
list_mail_folders, search_emails, get_email_messages, move_email_to_folder,
delete_email to use correct Nextcloud Mail REST API routes instead of
nonexistent OCS routes
- polls.py: Fix all routes to include correct /api/v1.0/ prefix, fix
create_poll payload (API doesn't accept description), fix add_poll_option
payload structure, fix vote_on_poll to use correct URL-based answer format
- forms.py: Update from nonexistent v2.4 API to correct v3 API, fix
create_form to use two-step create+update pattern, fix add_question_to_form
payload, fix option creation to use batch optionTexts parameter
- files.py: Fix get_folder_tree to use params= instead of json= for GET request
Co-authored-by: marcelklehr <986878+marcelklehr@users.noreply.github.com>
Nextcloud's SecurityMiddleware enforces CSRF checks on controller methods
without @NoCSRFRequired. ExApps don't have CSRF tokens, but Nextcloud's
Request::passesCSRFCheck() bypasses CSRF if the OCS-APIREQUEST header is
present (any non-empty value).
The nc_py_api library sets this header on the main OCS adapter, but NOT
on fresh adapters created via _create_adapter(True) used for REST calls.
Added "OCS-APIREQUEST": "true" header to all non-DAV REST API calls in:
bookmarks, cookbook, deck, mail, music, news, passwords, photos.
DAV calls (files.py, contacts.py, calendar.py) use /remote.php/dav/ which
goes through Sabre auth (AppAPIAuthBackend), not the CSRF middleware.
OCS calls (forms.py, polls.py, notes.py, circles.py, shares.py) already
have CSRF bypass via the OCS adapter's built-in OCS-APIREQUEST header.
Co-authored-by: marcelklehr <986878+marcelklehr@users.noreply.github.com>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
# Conflicts:
#	ex_app/lib/all_tools/bookmarks.py
#	ex_app/lib/all_tools/circles.py
#	ex_app/lib/all_tools/cookbook.py
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
@marcelklehr

Copy link
Copy Markdown
MemberAuthor

@janepie I dropped all changes that didn't work and or I didn't have the motivation to test, everything in here should now work

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
@julien-nc

Copy link
Copy Markdown
Member
  • Deck add card
  • 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)
  • Delete card

Wdyt about the "list board cards" tool?

I occasionally got something like messages with role 'tool' must be a response to a preceeding message with 'tool_calls' (with OpenAI + GPT 4.1) or No tool call found for function call output with call_id call_1t4CeDkPZAlWVXMBiNdGbj4d (with OpenRouter + GPT 4.1). It's easy to reproduce but i don't have a clear procedure.

Last time it happened, I just did:

  • list the cards in all lists of the NAME board
  • assign card 8 to the admin user
  • delete card 7

And the "chat with tools" task failed because the request response was messages with role 'tool' must be a response to a preceeding message...

@marcelklehr

Copy link
Copy Markdown
MemberAuthor

I occasionally got something like messages with role 'tool' must be a response to a preceeding message with 'tool_calls'

Can you check if this happens with the main branch as well?

@julien-nc

Copy link
Copy Markdown
Member

Same with main, it seems i'm consistently getting this error after a fixed number of tool calls. I had the same session multiple times:

  • list my talk conversations
  • what is the weather in Paris?
  • list my deck boards
  • what is the weather in Berlin?

And I always got the error for the last message.

@julien-nc

julien-nc commented Mar 25, 2026

Copy link
Copy Markdown
Member

Tools in files.py ✔️

I could see the new tools after registering the app again.

Sharing ✔️

@marcelklehr

Copy link
Copy Markdown
MemberAuthor

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)

Works for me, it can use the search tool

@julien-nc

Copy link
Copy Markdown
Member

Works for me, it can use the search tool

Now I have the tools. All good.

@marcelklehr
marcelklehr merged commit bc27b12 into mainMar 25, 2026
6 checks passed
@marcelklehr
marcelklehr deleted the feat/moartools branch March 25, 2026 13:02
Pavlinchen added a commit to Pavlinchen/context_agent that referenced this pull request Apr 22, 2026
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>
Sign up for freeto 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.

4 participants

@marcelklehr@julien-nc